原文地址:http://chenzhijun.me/2017/12/12/elasticsearch-logstash-kibana-part/,歡迎大家留言交流
基于ELK+Filebeat搭建日志中心
實驗環境
- ubuntu 16
- jdk 1.8
- elasticesearch 6.0, kibana 6.0, logstash 6.0, filebeat 6.0
我也在windows10下安裝過,win10下只需要修改filebeat的文件路徑配置就可以了。
概念介紹
elastic提供了非常多的工具,官方稱為Elastic Stack。它提供了一些解決方案。我們用到的就是其中Stack中的部分工具
Elasticsearch 是一個分布式、可擴展開源全文搜索和分析引擎。它能夠進行存儲,并且能以很快的速度(接近實時)來進行搜索和分析大量的數據。它使用Java編寫,底層基于Apache Lucene。
Logstash 是一個開源的,服務端數據處理管道。 它可同時從多個源來搜集數據,對數據進行過濾等操作,并且將數據傳送到你想要傳送的地方進行存儲。
Kibana 被設計成一個和Elasticsearch共同使用的開源分析和可視化平臺,它支持將ES中存儲的數據生成多種維度的圖等。
Filebeat 是一個輕量級的日志采集器,用于將源數據采集后發送給Logstash,并且Filebeat使用背壓敏感協議,以考慮更多的數據量。如果Logstash正在忙于處理數據,則可以讓Filebeat知道減慢讀取速度。還有很多Beat可以提供選擇,有監控網絡的Packbeat,指標Metricbeat。各種beat詳情:https://www.elastic.co/cn/products/beats
系統架構簡圖如下:
環境搭建
將ELK和filebeat下載后解壓到一個目錄下,四個產品都是開箱即用的。
Logstash安裝與配置
Logstash的作用主要是用來處理數據,當然它也可以直接從日志文件讀取記錄然后進行處理。在Logstash的根目錄,我們需要建立一個新文件logstash.conf
:
# 配置logstash輸入源
input {
beats {
host => "localhost"
port => "5043" #注意要和filebeat的輸出端口一致
}
}
# 配置輸出的地方
output {
# 控制臺
stdout { codec => rubydebug }
# es
elasticsearch {
hosts => [ "localhost:9200" ]
}
}
Filebeat安裝與配置
Filebeat作為日志搜集器,肯定是需要指定輸入源和輸出地,所以我們需要先配置它。在Filebeat的根目錄下我們需要在filebeat.yml
中:
# 輸入源
filebeat.prospectors:
- type: log
paths:
- /var/log/*.log # 日志文件以log結尾并且需要放在/var/log目錄下
# 如果是windows,如下
# - C:\Users\chen\Desktop\elastic\elkjava\log\*.log
# 輸出地
output.logstash:
# The Logstash hosts
hosts: ["localhost:5043"]
Elasticsearch和Kibana安裝與配置
這次演示我們對es和kibana不做特別的配置,就默認就好了。
啟動順序
其實沒有特別的順序,我一般的啟動順序是elasticsearch->logsatsh->kibana->filebeat。其實差別都不大,特別注意一個就是,如果你想要測試的話,logstash支持配置自動更新,如果是日志文件更新,想讓filebeat重新再搜索一次,刪除掉filebeat根目錄下data/registry
文件。其實類推,如果要刪除其它的軟件(elk)的的數據,刪掉data
目錄,很直接很暴力,但不建議在正式場景直接這樣弄。
啟動es:
./bin/elasticsearch
啟動logstash:
# 測試conf文件是否正確配置
./bin/logstash -f logstash.conf --config.test_and_exit
# 啟動logstash,如果有修改conf會自動加載
./bin/logstash -f logstash.conf --config.reload.automatic
啟動kibana:
./bin/kibana
啟動filebeat:
./filebeat -e -c filebeat.yml -d "publish"
現在在瀏覽器中輸入:http://localhost:5601打開kibana,
點擊create,之后再點擊左側導航欄Discover:
就能看到值了。
不管怎么樣,一定要動手實驗才知道能不能行。
進階實戰:收集Java日志
上面搭建的elk是可以用的,但是在實際中我發現一些需要處理的地方,比如Java的日志文件經常將堆棧打印出來,這個時候如果還是按照上面的配置,我們無法正確的顯示在kibana中,因為我們上面實際配置的是按行讀取的。但是堆棧信息應該是一條。所以我們需要對日志進行一些多行處理。
可以在filebeat中處理,也可以在logstash中處理。
我們今天直接在filebeat中處理,讓logstash只做日志的過濾。
首先準備一份Java的日志文件,大致的日志文件都會像下面這樣格式:date log-level log-message
=》時間 日志級別 日志內容
,下面是一個拋出空指針的文件(有刪減):
2017-12-06 16:59:38,927 WARN ExceptionHandlerExceptionResolver:391 Failed to invoke @ExceptionHandler method: public com.framework.common.model.ResultData com.elasticsearch.exception.IntegralExceptionHandler.exceptionHandler(java.lang.Exception)
java.lang.NullPointerException
at com.framework.common.util.SpringUtils.getMessage(SpringUtils.java:152) ~[classes/:?]
at com.framework.common.util.SpringUtils.getMessage(SpringUtils.java:138) ~[classes/:?]
at com.framework.common.util.SpringUtils.getMessage(SpringUtils.java:57) ~[classes/:?]
at com.elasticsearch.exception.IntegralExceptionHandler.exceptionHandler(IntegralExceptionHandler.java:33) ~[classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
在filebeat中主要是將堆棧信息的內容合并到一行中,也就是說發送給logstash的時候將下面的異常堆棧當作log-message,讓filebeat讀取到堆棧的時候將空行轉義成字符串然后將這行的信息補充到第一行后面。我們可以使用filebeat的multiline配置,詳情:https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.html
filebeat.yml
:
filebeat.prospectors:
- type: log
paths:
- /var/log/*.log # 日志文件以log結尾并且需要放在/var/log目錄下
# 如果是windows,如下
# - C:\Users\chen\Desktop\elastic\elkjava\log\*.log
multiline: # 多行處理,正則表示如果前面幾個數字不是4個數字開頭,那么就會合并到一行
pattern: ^\d{4}
negate: true # 正則是否開啟,默認false不開啟
match: after # 不匹配的正則的行是放在上面一行的前面還是后面
output.logstash:
# The Logstash hosts
hosts: ["localhost:5043"]
同樣的這次我們對Java日志做一些信息提煉,也就是使用過濾規則,將date,log-level,log-message等提取出來:
logstash.conf
:
input {
beats {
host => "localhost"
port => "5043"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{JAVALOGMESSAGE:msg}" }
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => [ "localhost:9200" ]
}
}
值得注意的就是我們使用filter插件,在其中我們使用了grok(基于正則表達式)過濾我們的日志內容。grok可以將無規則的日志數據通過正則匹配將之轉換成有結構的數據,以此我們能夠根據相應結構進行查詢。grok的使用方式是:%{規則:自定義字段名稱}
grok詳情
Logstash提供了很多grok表達式,詳情可以看:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
為了效果,我們可以刪除filebeat,es,logstash,kibana等根目錄的data文件,然后按照之前的步驟重啟這些工具,
現在可以在kibana中看到相應的結果了:
先看到我們自定義的字段:
在Discover中過濾字段:
結果:
目前就告一段落了,最主要的是自己動手時間。接下準備做的事情是將這些能一個Dockerfile,然后只需要自己配置下filebeat的收集目錄和logstash的過濾規則,我們就能使用了。
不管怎樣只有自己動手去做了,才會知道有很多坑需要填。我也在google搜了很多資料,本來想在文后加個參考鏈接的,后來發現太多了。算了,還是不貼鏈接了。總之,謝謝哪些我在網上搜資料給了我靈感,幫我跨過一些坑的人。謝謝。
紙上得來終覺淺,絕知此事要躬行。