ELK學習筆記之CentOS 7下ELK(6.2.4)++LogStash+Filebeat+Log4j日誌整合環境搭建
0x00 簡介
現在的公司由於絕大部分專案都採用分散式架構,很早就採用ELK了,只不過最近因為額外的工作需要,仔細的研究了分散式系統中,怎麼樣的日誌規範和架構才是合理和能夠有效提高問題排查效率的。
經過仔細的分析和研究,確定下面的架構應該是比較合理的之一(Filebeat也支援直接寫到ES),如果可以的話,Filebeat也可以不直接連到Logstash,先寫到kafka,然後從kafka寫到logstash的kafka外掛。
關於ELK的各種架構以及優缺點,可以參考。
首先,不管是不是分散式架構,都應該解決請求日誌上下文關聯的問題,這可以通過Log4j自帶的NDC來實現。以Spring MVC為例,可以使用HandlerInterceptor在HandlerInterceptor中設定NDC.push(SessionBeanUtil.getSessionKey(request).substring(0, 8) + "_" + path + "_" + formatter.format(new Date()));,在postHandle中NDC.pop();。
注:最近在學習spring cloud,spring cloud sleuth也包含了MDC跨節點日誌上下文跟蹤ID的特性,和筆者的思路基本一致。
其次,對於分散式請求,還要解決全域性的請求日誌上下文關聯的問題,這需要依賴與具體的RPC框架來實現,以dubbo為例,可以通過filter在請求端和服務端設定。
第三,服務的呼叫鏈應該可以算做是日誌框架的範疇,這可以通過zipkin整合來實現。
在實現上,對於服務的呼叫鏈可以使用單獨的ES儲存、也可以在一個大的ES叢集中儲存為一個index。
從ELK 6.0開始,對於源是log4j的場景,不再建議使用logstash-input-log4j,而是使用Filebeat作為應用端的日誌代理,具體可以
所以,在本文的搭建過程中,筆者採用的也是Filebeat的方案。
0x01 環境說明與準備
Filebeat一般安裝在產生日誌的伺服器,這裡tomcat在windows 10 x64下,所以Filebeat也需要安裝在windows下。
# CentOS 7.4 64位 ip 192.168.26.135
# 防火牆關閉 Selinux關閉
版本為安裝時的最新版本:
# Elasticsearch 6.2.4 # Kibana 6.2.4 # Logstash 6.2.4
# elasticsearch-head(從github直接clone)
# filebeat 6.2.4
# phantomjs-2.1.1-linux-x84_64 (配合npm指令使用)
# node-v4.9.1-linux-x64 (記住資料夾路徑,需要增加到bash_profile中)
從官網下載並解壓。
因為ES主要通過restful api對外提供服務,所以一般安裝ES時順帶安裝elasticsearch-head,它提供了web控制檯。
elasticsearch-head通過原始碼的方式託管在git上,所以需要安裝下git,直接yum安裝即可。
# yum install git
同時elasticsearch-head是一個nodejs應用,所以還需要具有node, 需要安裝phantomjs。(安裝教程可以參考這篇部落格)
所以在正式開始前,我們需要確保centos下下列基礎設施已經具備:
1、git已經安裝。
# yum install git
2、如果希望原始碼安裝nodejs,確保gcc滿足node的要求,或者直接使用已經編譯好的版本。
筆者直接使用編譯好的版本,可從https://nodejs.org/en/download/releases/選擇具體的版本,基礎執行環境最好不要使用最新版本,這裡我們使用v4.9。下載解壓後即可用。
注意安裝版本和下載解壓後的檔案路徑,下面要加到.bash_profile中。
3、因為elk不能使用root執行,所以需要新建一個elk使用者並設定環境變數。
# groupadd elk # useradd -g elk elk
設定elk使用者的環境變數:
# su - elk
vim .bash_profile 增加如下:注意node-v4.9.1的資料夾路徑
# export NODE_HOME=/usr/local/app/node-v4.9.1-linux-x64 # PATH=$NODE_HOME/bin:$PATH:$HOME/.local/bin:$HOME/bin # export NODE_PATH=$NODE_HOME/lib/node_modules # export PATH
4、下載ELK套件本身並解壓:
# cd /usr/local/app (這是此次實驗的安裝路徑) # wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz # wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.4-linux-x86_64.tar.gz # wget https://artifacts.elastic.co/downloads/logstash/logstash-6.2.4.tar.gz # wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.4-linux-x86_64.tar.gz # git clone https://github.com/mobz/elasticsearch-head
0x02 安裝ElasticSearch
因為使用的是vmware,總共記憶體才分配了1G,所以為了避免OOM,對ES以及logstash記憶體均進行了調整,限制為256M。
因為es需要非root使用者執行,所以對於ES相關的所有操作均在elk使用者下執行。
# su - elk
更改ES配置:
# vim elasticsearch.yml
# 確保下列引數被正確設定: cluster.name: logger # ES叢集的名字 node.name: node-1 path.data: /usr/local/app/elasticsearch-6.2.4/data path.logs: /usr/local/app/elasticsearch-6.2.4/log bootstrap.memory_lock: false # 對於非專用ES,建議設定為false,預設為true bootstrap.system_call_filter: false network.host: 0.0.0.0 # 支援遠端訪問 http.port: 9200 # restful api訪問介面 http.cors.enabled: true #允許ES head跨域訪問 http.cors.allow-origin: "*" #允許ES head跨域訪問
接著改另外一個配置檔案
# vim jvm.options # JVM引數在這個檔案中設定,當然命令列也可以
-Xms256m
-Xmx256m
上述配置調整完成後,就可以啟動ES了。
windows下瀏覽器訪問下http://192.168.26.135:9200
ElasticSearch安裝完成。
0x03 啟動ElasticSearch的TroubleShooting
報錯細節,請參考這篇部落格。
0x04 安裝ElasticSearch-head
需要注意的是,雖然ES head可以認為是es的外掛,但是它不能放在$ES_HOME/plugins目錄下,因為它並不符合ES外掛的規範,否則ES啟動會失敗。
[[email protected] elasticsearch-head]$ pwd /usr/local/app/elasticsearch-head [[email protected] elasticsearch-head]$ npm config set registry https://registry.npm.taobao.org
# npm install
可能會遇到如下報錯
Please report this full log at https://github.com/Medium/phantomjs npm ERR! Darwin 15.0.0 npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" npm ERR! node v4.4.3 npm ERR! npm v3.10.9 npm ERR! code ELIFECYCLE npm ERR! phantomjs[email protected] install: `node install.js` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the phantomjs[email protected] install script 'node install.js
如果出現上述錯誤,則執行下列名稱:
# npm install [email protected] --ignore-scripts
然後重新執行
# npm install
這樣ES head就安裝好了。不要急著啟動!!!
如果只是本機訪問,下面的配置修改不是必須的。如果要其他機器訪問,則需要修改,一般來說,只要是伺服器應用,都是通過遠端訪問的。
[[email protected] elasticsearch-head]$ vim Gruntfile.js
搜尋server,在其options物件屬性下增加一個hostname屬性,值為"*",如下:
現在就可以啟動es head了,如下:
windows下瀏覽器訪問下http://192.168.26.135:9100
0x04 安裝Logstash
logstash和kibana可以使用root使用者來啟動。
Logstach需要搭配指定的配置檔案啟動,建立一個logstash配置檔案,比如logstash-es.conf,配置從filebeat讀取資料來源,輸出到es。
為了簡化起見,忽略過濾器(實際生產中,一般需要配置過濾器對日誌進行規範化處理和分類)
# vim logstash-es.conf
加入如下內容:
為了測試方便,同時開啟控制檯輸入和輸出。
input { stdin { } beats { port => 5000 ssl => false } } output { elasticsearch { action => "index" hosts => "127.0.0.1:9200" index => "logstash-%{+YYYY-MM}" } stdout { codec=> rubydebug } }
配置jvm檔案
# vim jvm.options #設定最多使用256m記憶體
啟動logstash
# ./bin/logstash -f ./config/logstash-es.conf
隨便輸入個字串測試下,如上,看下http://192.168.26.135:9100
這樣logstash對於寫入es和從控制檯輸入的配置就正確了,filebeat還需要等我們後面驗證。我們先完成Kibana的安裝與配置。
0x05 Kibana安裝
kibana也是個nodejs應用。首先來修改kibana的配置:
# cd kibana-6.2.4-linux-x86_64/config/
更改配置檔案
# vim kibana.yml # 確保下列配置正確
server.port: 5601 server.host: "192.168.230.128" elasticsearch.url: "http://localhost:9200"
上述配置完成後,就可以啟動了
訪問下http://192.168.26.135:5601
第一次訪問的時候,會要求設定Index Pattern,因為我們在logstash-es.conf中設定為logstash-%{+YYYY-MM},所以設定為logstash-*就可以了。
# 這裡有可能會遇到要求你建立Index的情況,請參考官網的指導檔案和該部落格匯入json檔案即可
# 官網指導檔案 https://www.elastic.co/guide/en/kibana/6.x/tutorial-load-dataset.html
# 如何批量匯入資料到Kibana,https://www.cnblogs.com/hai-ping/p/6068946.html
Discover是主要的查詢互動介面,如下所示:
有時候在訪問discover的時候,提示no results found,如下所示:
這通常是由於預設的查詢時間範圍太短的原因,可以通過右上角的TimeRange來設定查詢的時間範圍。
到這裡,ELK的環境搭建與基本配置就完成了。
更多的配置與優化參見各官方文件。
0x06 Filebeat安裝與配置
採用Filebeat作為源端代理之後,準確的說,跟log4j已經沒有關係了。所以這裡假設讀者知道log4j的配置,生成的檔案在d:\httx\logs目錄。
因為windows下Filebeat的啟動指令碼是使用powershell指令碼編寫的,所以確保安裝了ps,windows 10下自帶。
從https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.4-windows-x86_64.zip下載windows版本的filebeat。filebeat可以安裝在任何目錄,這裡以D:\filebeat為例。
開啟配置檔案D:\filebeat\filebeat.yml,確保下列設定正確:
filebeat.prospectors: - type: log enabled: true #啟用配置 paths: - D:\httx\logs\* #設定監控路徑 #output.elasticsearch: #禁用ES寫入 output.logstash: #啟用logstash寫入 # The Logstash hosts hosts: ["192.168.26.135:5000"]
安裝與啟動filebeat。
開啟powershell,執行如下命令:
PS C:\Users\admin> cd 'D:\filebeat' PS D:\filebeat> .\install-service-filebeat.ps1 安全警告 請只執行你信任的指令碼。雖然來自 Internet 的指令碼會有一定的用處,但此指令碼可能會損壞你的計算機。如果你信任此指令碼,請使用 Unblock-File cmdlet 允許執行該指令碼,而不顯示此警告訊息。是否要執行 D:\chrome下載\filebeat\install-service-filebeat.ps1? [D] 不執行(D) [R] 執行一次(R) [S] 暫停(S) [?] 幫助 (預設值為“D”): R Status Name DisplayName ------ ---- ----------- Stopped filebeat filebeat PS D:\filebeat> Start-Service filebeat PS D:\filebeat> Stop-Service filebeat
filebeat的日誌在C:\ProgramData\filebeat\logs目錄下,這是寫死的,不知道哪裡可以更改。
filebeat會定期輸出日誌以及遇到的異常資訊。
最後,我們再回到kibana控制檯,看下log4j相關的日誌,如下:
左邊控制要顯示哪些列,比如顯示來源和主機:
到此為止,整個ELK+log4j的整合本身就完成了。但是要達到高效可用的步驟,下列問題還需要進一步研究:
1、filebeat讀取檔案似乎是以行為單位,這在exception堆疊下是不可接受的,需要logstash或者其他方式二次處理。
2、es head的控制檯應該來說作為es的監控還可以,但是作為日誌互動基本上沒什麼用,效果太差了。kibana還不錯,只不過filter不是起碼應該固定麼??
3、elk的詳細配置以及優化。
4、filebeat日誌中出現"sync.go:105: ERR Failed to publish events (host: 10.172.0.165:5044:10200), caused by: write tcp ",但是不影響日誌的傳送。
參考:
https://serverfault.com/questions/911440/filebeat-cant-connect-to-logstash-on-another-server
https://elasticsearch.cn/question/3157
其他:
[ERROR][logstash.plugins.registry] Tried to load a plugin's code, but failed. {:exception=>#<LoadError: no such file to load -- logstash/inputs/log4j>, :path=>"logstash/inputs/log4j", :type=>"input", :name=>"log4j"}
解決方法:執行bin/logstash-plugin install logstash-input-log4j 安裝log4j外掛,預設情況下,外掛沒有繫結,參考https://www.elastic.co/guide/en/logstash/current/plugins-inputs-log4j.html
log4j:ERROR Could not connect to remote log4j server at [192.168.230.128]. We will try again later
解決方法:logstash的log4j監聽地址由127.0.0.1改成ip比如192.168.230.128
log4j:WARN Detected problem with connection: java.net.SocketException: Connection reset by peer: socket write error
採用低版本的ELK比如2.x版本,ELK 2.x之後的版本就是5.x、6.x,3.x、4.x是跳版了的。
參考