用ELK監控系統請求和錯誤

本文系原創,轉載請註明。

本文地址:http://blog.csdn.net/xeseo/article/details/38817315

前言:

現在的系統,動則分佈式,分佈式情況下,錯誤的定位比傳統的單機要麻煩很多。因爲log文件分佈在不同的feature的不同節點。一直想找一種方式來簡化這個過程。

目前主流的log監控有:

Splunk:商業收費

syslog-ng:漏數據

flumejava寫的,有點重

chukwa:專爲Hadoop服務

scribejava寫的,略重

zabbixganglia:全面的系統監控,大材小用

graylog2:不詳,沒來得及研究

 

目標要輕量級、可擴展、分佈式、儘量實時。

最終找到了ELKElasticsearchLogstashKibana)Elasticsearch一家子。

 

簡介

LogstashJRuby寫的log收集工具,特點引用官方的話“Ship logs from any source, parse them,get the right timestamp, index them, and search them.

基本使用框架如下


 

logstash本身只有收集、解析和建立索引功能。這個框架中,shipper就是利用logstash的收集、解析功能來做agent,把目標log收集到broker去。Index還是利用logstash的索引功能。

這種架構是比較標準的,在數據量稍大的情況下,靠shipper聚集到broker,最後統一由index處理的。但如果數據量小,可以用一種更簡單的框架:


 

因爲logstash本身作爲agentindex都是分佈式的,可自動加入cluster。所以在這種情況下,去掉一個broker,直接交到storage。(如果有錯,還請指正。)

 

常用的BrokerRedislogstash book上面推薦的。

這裏的Search&Storage,就用自家的Elasticsearch,它的主要特點:

  • 分佈式、HA、近乎實時
  • 讀寫分離
  • 面向文檔
    • 由於是document oriented,所以不需要特定的schema定義。可以在index階段隨意指定。
  • 基於apcheLucene搜索引擎
    • logstash建立的index打碎成shardsshardsprimaryreplica
      • primary是真正存儲的地方,每一個新Index默認創建五個primary shards。該數量可以在Index被創建前改變。但是index一旦創建就無法再變。
      • replicaprimary shards的備份,該數量可以隨時改變,主要用於保護數據和加速查找(讀寫分離)。

 

WebInterface,還是Elasticsearch家族的一員——KibanaKibana是一款完全基於HTML5jsweb統計界面,易於拓展,看上去也比較高大尚。

最新版的logstash自帶了一個,可以用bin目錄的logstash-web直接啓動。

所以部署框架詳情如下:


 

這個框架中除了Kibana外,都是分佈式的~  意味着都可以變成cluster

 

安裝

  1. 下載logstashElasticsearchredistar包。Kibana就不用下了,直接用logstash自帶的。
  2. logstashtar包分別解壓到目標集羣的每個機器上。最好是同一位置。logstash不需要額外配置什麼,大部分都是靠命令行參數。啓動命令:

bin/logstash -f xxx.conf

額外參數:

-p指定端口,默認9292端口

  1. 安裝redis
    1. 解壓出來後,執行make命令
    2. 拷貝執行文件

# mkdir /usr/local/redis/{conf,run,db}pv

#cp redis.conf /usr/local/redis/conf

#cd src

#cp reids-benchmark redis-check-aof redis-check-dump redis-cli redis-servermkreleasehdr.sh /usr/local/redis/

  1. 配置redis

# vi /usr/local/redis/conf/redis.conf

daemonize yes

dir /usr/local/redis/db/

  1. 啓動

#cd/usr/local/redis/

# ./redis-server conf/redis.conf

  1. 測試一下

# ./redis-benchmark

 

  1. 安裝elasticsearch
    1. 解壓出來後修改config/elasticsearch.yml (自己替換通配符)

cluster.name <YOUR_CLUSTER_NAME>

node.name <NODE_NAME>

  1. 啓動 ./bin/elasticsearch
  1. logstash的配置

logstash的配置包含input,filter output三部分,每一部分都有很多的插件可用,可支持讀寫解析file, socket, tcp, udp, jmx等。具體參見:http://logstash.net/docs/1.4.2/

另外filter中的grok,有個debug頁面非常不錯:http://grokdebug.herokuapp.com/

可以在這個頁面測試grok表達式和查看常用的grok pattern

例子: shipper.conf

input{

file {

type => "java_error"

path => ["/opt/tomcat/logs/catalina.out"]

add_field => {"feature" => "tomcat"}

codec => multiline {

              pattern => "(^\d+\serror)|(^.+Exception:?.*)|(^\s+at .+)|(^\s+... \d+ more)|(^\s*Caused by:.+)"

              what => "previous"

            }

}

file {

type => "java_error"

add_field => {"feature" => "pbq"}

path => ["/opt/pbq/logs/bigada.log"]

codec => multiline {

              pattern => "(^\d+\serror)|(^.+Exception:?.*)|(^\s+at .+)|(^\s+... \d+ more)|(^\s*Caused by:.+)"

              what => "previous"

            }

}

file {

type => "java_error"

add_field => {"feature" => "storm"}

path => ["/opt/apache-storm-0.9.2-incubating/logs/worker-*.log","/opt/apache-storm-0.9.2-incubating/logs/seq.log"]

codec => multiline {

              pattern => "(^\d+\serror)|(^.+Exception:?.*)|(^\s+at .+)|(^\s+... \d+ more)|(^\s*Caused by:.+)"

              what => "previous"

            }

}

file {

type => "java_error"

add_field => {"feature" => "kafka"}

path => ["/opt/kafka_2.9.2-0.8.1/logs/server.log"]

codec => multiline {

              pattern => "(^\d+\serror)|(^.+Exception:?.*)|(^\s+at .+)|(^\s+... \d+ more)|(^\s*Caused by:.+)"

              what => "previous"

            }

}

file {

type => "pbp_seq"

path => ["/opt/tomcat/logs/seq.log"]

}

file {

type => "pbp_seq"

path => ["/opt/pbq/logs/seq.log"]

}

file {

type => "pbp_seq"

path => ["/opt/apache-storm-0.9.2-incubating/logs/seq.log"]

}

}

 

filter{

if [type] == "java_error" {

grok{

match => ["message", "%{JAVASTACKTRACEPART}|%{TIMESTAMP_ISO8601:timestamp} ERROR \[%{JAVACLASS:class}\] - <%{GREEDYDATA}>|%{TIMESTAMP_ISO8601:timestamp} %{DATA:class} \[ERROR\] <%{DATA:thread}> %{GREEDYDATA}"]

tag_on_failure => ["grokfailure"]

}

}

 

if [type] == "pbp_seq"{

grok{

match => [ "message", "%{TIMESTAMP_ISO8601:timestamp} %{DATA:class} \[%{LOGLEVEL:log_level}\] <%{DATA:thread}> PBP Seq %{DATA:feature} \[%{DATA:sessionId}\] - \[%{DATA:seq}\] - \[%{INT:step:int}\] %{GREEDYDATA:status}" ]

tag_on_failure => [ "grokfailure" ]

}

}

 

if "grokfailure" in [tags] {

drop { }

}

}

 

output {

stdout{}

redis{

host => "10.1.110.22"

data_type => "list"

key => "logstash"

}

}

 

這個shipper監控了我項目中的tomcatpbqstormkafka的錯誤,以及從各個節點發出來的PBP Seq(我加在各個節點源碼裏打印出來的log

multiline插件合併了java exceptiontrace到一個logstash eventmessage裏面,同時用filter過濾了非目標的log,否則log數據量會很大。

 

如果是用redisbroker,那麼還需要一個indexconf,例子:central.conf

input{

redis {

host => "10.1.110.22"

type => "redis-input"

data_type => "list"

key => "logstash"

}

}

output {

stdout{}

elasticsearch{

cluster => "logstash"

}

}

 

其中cluster的值,對應elasticserach中所填的<YOUR_CLUSTER_NAME>

 

如果是我上面說的簡單的框架,那麼直接把shipperoutputredis部分替換成

elasticsearch{

host=> "10.1.110.22"

                      cluster =>"logstash"

    }

 

  1. 啓動logstash
    1. 在各個節點上執行./logstash -f shipper.conf
    2. index節點上執行./logstash -f central.conf
    3. index節點上執行./logstash-web
  2. 瀏覽器打開http://<IP_OF_INDEX_NODE>:9292/可以看到Kibana界面


 

它已經自帶了一個logstash dashboard,進去就可以看到我們所監控的日誌了。

 

可以點選左下角的Fields,來查看想要看的fields

 

注:

Kibana有一個問題,它列出來的fields只能按照一個field進行排序。事實上Elasticsearch支持組合排序。這個問題已經進入了KibanaJIRA,有望在未來解決。

貼一個我定義的問題收集界面:


 


至此,一個ELK的典型應用已經搭建完畢。但是,這裏有兩個問題:

  1. elasticsearchindex以日期爲單位,默認是不會刪除的,顯然得定期刪除。
  2. 每個logstash的情況必須也得監控起來,否則,如果一個節點上的logstash掛了,顯然其上的錯誤日誌是不會得到監控的。

 

爲了解決問題1elasticsearch提供了一個python的腳本——curatorgithub源碼地址:https://github.com/elasticsearch/curator/

安裝步驟:https://github.com/elasticsearch/curator/wiki/Installation

wiki裏面寫的是服務器可以連接外網情況下,直接用pip安裝。

由於我的服務器無法連接外網,所以只能自己手動裝,步驟如下:

  1. 下載依賴包
    1. urllib3https://pypi.python.org/pypi/urllib3
    2. unittest2https://pypi.python.org/pypi/unittest2
    3. argparsehttps://pypi.python.org/pypi/argparse
    4. elasticsearch-pyhttps://github.com/elasticsearch/elasticsearch-py/archive/master.zip
    5. curatorhttps://github.com/elasticsearch/curator/archive/master.zip
  2. 按照上面順序,解壓後進入其目錄依次用命令python setup.py intall安裝
  3. 執行curator(參考https://github.com/elasticsearch/curator/wiki/Examples)

每天定期刪

python curator.py --host 10.1.110.22 delete --older-than 1   

超過100MB

pythoncurator.py --host 10.1.110.22 delete --disk-space 0.1

 

注意:

curator似乎有點bug,我安裝完畢後,直接用curator命令會報錯,但是直接進入curator_master/curator/下面執行pythoncurator.py是可以用的。

 

解決問題2,由於我是選用了簡單框架,不含redisbroker的,所以我這裏可以給elasticsearch安裝插件kopf,官網地址:https://github.com/lmenezes/elasticsearch-kopf

該插件可以直接監控elasticsearch的集羣狀況,其中就包含其輸入的組件狀況,即logstash

注:

如果是安裝了redis,使用了shipper+broker+index的框架,那麼kopf只能監控到index的狀況!

 

安裝步驟非常簡單

  1. git clonegit://github.com/lmenezes/elasticsearch-kopf.git
  2. cd elasticsearch-kopf
  3. git checkout 1.2 

這裏參考對應版本

elasticsearch version

kopf version

0.90.X

0.90

1.0.X

1.0

1.1.X

1.1

1.2.X

 

 

  1. 然後把整個elasticsearch-kopf包拷到elasticsearch的服務器上,到elasticsearchbin目錄執行

./plugin --install elasticsearch-kopf FILE:///<PATH>/elasticsearch-kopf.zip

 

  1. 瀏覽器打開http://<IP_OF_ELASTICSEARCH>:9200/_plugin/kopf/#/cluster可以看見elasticsearchcluster狀況



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章