通過(guò)本篇內(nèi)容,你可以學(xué)到如何解決Logstash的常見(jiàn)問(wèn)題、理解Logstash的運(yùn)行機(jī)制、集群環(huán)境下如何部署ELKStack。
本文目錄如下:
前言一、部署架構(gòu)圖二、Logstash 用來(lái)做什么?三、Logstash 的原理3.1 從 Logstash 自帶的配置說(shuō)起3.2 Input 插件3.3 Filter 插件3.4 Output 插件3.5 完整配置四、Logstash 怎么跑起來(lái)的4.1 Logstash 如何運(yùn)行的4.2 Logstash 的架構(gòu)原理五、Logstash 宕機(jī)風(fēng)險(xiǎn)5.1 Logstash 單點(diǎn)部署的風(fēng)險(xiǎn)5.2 開(kāi)機(jī)啟動(dòng) Logstash六、總結(jié)前言
通過(guò)本篇內(nèi)容,你可以學(xué)到如何解決 Logstash 的常見(jiàn)問(wèn)題、理解 Logstash 的運(yùn)行機(jī)制、集群環(huán)境下如何部署 ELK Stack。
在使用 Logstash 遇到了很多坑,本篇也會(huì)講解解決方案。
【資料圖】
日志記錄的格式復(fù)雜,正則表達(dá)式非常磨人。服務(wù)日志有多種格式,如何匹配。錯(cuò)誤日志打印了堆棧信息,包含很多行,如何合并。日志記錄行數(shù)過(guò)多(100 多行),被拆分到了其他的日志記錄中。輸出到 ES 的日志包含很多無(wú)意義字段。輸出到 ES 的日志時(shí)間和本來(lái)的日志時(shí)間相差 8 小時(shí)。如何優(yōu)化 Logstash 的性能Logstash 單點(diǎn)故障如何處理。一、部署架構(gòu)圖
上次我們聊到了 ELK Stack 的搭建:
一文帶你搭建一套 ELK Stack 日志平臺(tái)
最近悟空正在我們的測(cè)試環(huán)境部署這一套 ELK,發(fā)現(xiàn)還是有很多內(nèi)容需要再單獨(dú)拎幾篇出來(lái)詳細(xì)講講的,這次我會(huì)帶著大家一起來(lái)看下 ELK 中的 Logstash 組件的落地玩法和踩坑之路。
測(cè)試環(huán)境目前有 12 臺(tái)機(jī)器,其中 有 4 臺(tái)給后端微服務(wù)、Filebeat、Logstash 使用,3 臺(tái)給 ES 集群和 Kibana 使用。
部署拓?fù)鋱D如下:
部署說(shuō)明:
4 臺(tái)服務(wù)器給業(yè)務(wù)微服務(wù)服務(wù)使用,微服務(wù)的日志會(huì)存放本機(jī)上。4 臺(tái)服務(wù)器都安裝 Filebeat 日志采集器,采集本機(jī)的微服務(wù)日志,其中一臺(tái)服務(wù)器安裝 Logstash ,F(xiàn)ilebeat 發(fā)送日志給 Logstash。Logstash 將日志輸出到 Elasticsearch 集群中。3 臺(tái)服務(wù)器都安裝有 Elasticsearch 服務(wù),組成 ES 集群。其中一臺(tái)安裝 Kibana 服務(wù),查詢(xún) ES 集群中的日志信息。二、Logstash 用來(lái)做什么?
你是否還在苦惱每次生產(chǎn)環(huán)境出現(xiàn)問(wèn)題都需要遠(yuǎn)程到服務(wù)器查看日志文件?
你是否還在為了沒(méi)有統(tǒng)一的日志搜索入口而煩心?
你是否還在為從幾十萬(wàn)條日志中搜索關(guān)鍵信息而苦惱?
沒(méi)錯(cuò),Logstash 它來(lái)啦,帶著所有的日志記錄來(lái)啦。
Logstash 它是幫助我們收集、解析和轉(zhuǎn)換日志的。作為 ELK 中的一員,發(fā)揮著很大的作用。
當(dāng)然 Logstash 不僅僅用在收集日志方面,還可以收集其他內(nèi)容,我們最熟悉的還是用在日志方面。
三、Logstash 的原理
3.1 從 Logstash 自帶的配置說(shuō)起
Logstash 的原理其實(shí)還比較簡(jiǎn)單,一個(gè)輸入,一個(gè)輸出,中間有個(gè)管道(不是必須的),這個(gè)管道用來(lái)收集、解析和轉(zhuǎn)換日志的。如下圖所示:
Logstash 組件
Logstash 運(yùn)行時(shí),會(huì)讀取 Logstash 的配置文件,配置文件可以配置輸入源、輸出源、以及如何解析和轉(zhuǎn)換的。
Logstash 配置項(xiàng)中有兩個(gè)必需元素,輸入(inputs)和輸出(ouputs),以及一個(gè)可選元素 filters 過(guò)濾器插件。input 可以配置來(lái)源數(shù)據(jù),過(guò)濾器插件在你指定時(shí)修改數(shù)據(jù),output 將數(shù)據(jù)寫(xiě)入目標(biāo)。
我們來(lái)看下 Logstash 軟件自帶的一個(gè)示例配置,文件路徑:\logstash-7.6.2\config\logstash-sample.conf
是不是很簡(jiǎn)單,一個(gè) input 和 一個(gè) output 就搞定了。如下圖所示:
但是這種配置其實(shí)意義不大,沒(méi)有對(duì)日志進(jìn)行解析,傳到 ES 中的數(shù)據(jù)是原始數(shù)據(jù),也就是一個(gè) message 字段包含一整條日志信息,不便于根據(jù)字段搜索。
3.2 Input 插件
配置文件中 input 輸入源指定了 beats,而 beats 是一個(gè)大家族,F(xiàn)ilebeat 只是其中之一。對(duì)應(yīng)的端口 port = 5044,表示 beats 插件可以往 5044 端口發(fā)送日志,logstash 可以接收到通過(guò)這個(gè)端口和 beats 插件通信。
在部署架構(gòu)圖中,input 輸入源是 Filebeat,它專(zhuān)門(mén)監(jiān)控日志的變化,然后將日志傳給 Logstash。在早期,Logstash 是自己來(lái)采集的日志文件的。所以早期的日志檢索方案才叫做 ELK,Elasticsearch + Logstash + Kibana,而現(xiàn)在加入了 Filebeat 后,這套日志檢索方案屬于 ELK Stack,不是 ELKF,摒棄了用首字母縮寫(xiě)來(lái)命名。
另外 input 其實(shí)有很多組件可以作為輸入源,不限于 Filebeat,比如我們可以用 Kafka 作為輸入源,將消息傳給 Logstash。具體有哪些插件列表,可以參考這個(gè) input 插件列表 1
3.3 Filter 插件
而對(duì)于 Logstash 的 Filter,這個(gè)才是 Logstash 最強(qiáng)大的地方。Filter 插件也非常多,我們常用到的 grok、date、mutate、mutiline 四個(gè)插件。
對(duì)于 filter 的各個(gè)插件執(zhí)行流程,可以看下面這張圖:
圖片來(lái)自 Elasticsearch 官網(wǎng)
3.3.1 日志示例
我以我們后端服務(wù)打印的日志為例,看是如何用 filter 插件來(lái)解析和轉(zhuǎn)換日志的。
logback.xml 配置的日志格式如下:
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
日志格式解釋如下:
記錄日志時(shí)間:%d{yyyy-MM-dd HH:mm:ss.SSS}記錄是哪個(gè)線程打印的日志:%thread記錄日志等級(jí):%-5level打印日志的類(lèi):%logger記錄具體日志信息:%msg%n,這個(gè) msg 的內(nèi)容就是 log.info("abc") 中的 abc。通過(guò)執(zhí)行代碼 log.info("xxx") 后,就會(huì)在本地的日志文件中追加一條日志。
3.3.2 打印的日志內(nèi)容
從服務(wù)器拷貝出了一條日志,看下長(zhǎng)什么樣,有部分敏感信息我已經(jīng)去掉了。
2022-06-16 15:50:00.070 [XNIO-1 task-1] INFO com.passjava.config - 方法名為:MemberController-,請(qǐng)求參數(shù):{省略}
那么 Logstash 如何針對(duì)上面的信息解析出對(duì)應(yīng)的字段呢?比如如何解析出打印日志的時(shí)間、日志等級(jí)、日志信息?
3.3.3 grok 插件
這里就要用到 logstash 的 filter 中的 grok 插件。filebeat 發(fā)送給 logstash 的日志內(nèi)容會(huì)放到 message 字段里面,logstash 匹配這個(gè) message 字段就可以了。配置項(xiàng)如下所示:
filter { grok { match => [ "message", "(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3})\s+\[(?.*)\]\s+(?\w*)\s{1,2}+(?\S*)\s+-\s+(?.*)\s*"] match => [ "message", "(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3})\s{1,2}+(?\w*)\s{1,2}+.\s---+\s\[(?.*)\]+\s(?\S*)\s*:+\s(?.*)\s*"] }}
坑:日志記錄的格式復(fù)雜,正則表達(dá)式非常磨人。
大家發(fā)現(xiàn)沒(méi),上面的 匹配 message 的正則表達(dá)式還是挺復(fù)雜的,這個(gè)是我一點(diǎn)一點(diǎn)試出來(lái)的。Kibana 自帶 grok 的正則匹配的工具,路徑如下:
http://:5601/app/kibana#/dev_tools/grokdebugger
我們把日志和正則表達(dá)式分別粘貼到上面的輸入框,點(diǎn)擊 Simulate 就可以測(cè)試是否能正確匹配和解析出日志字段。如下圖所示:
Grok Debugger 工具
有沒(méi)有常用的正則表達(dá)式呢?有的,logstash 官方也給了一些常用的常量
來(lái)表達(dá)那些正則表達(dá)式,可以到這個(gè) Github 地址查看有哪些常用的常量。
https://github.com/logstash-plugins/logstash-patterns-core/blob/main/patterns/ecs-v1/grok-patterns
比如可以用 IP 常量來(lái)代替正則表達(dá)式 IP (?:%{IPV6}|%{IPV4})
。
好了,經(jīng)過(guò)正則表達(dá)式的匹配之后,grok 插件會(huì)將日志解析成多個(gè)字段,然后將多個(gè)字段存到了 ES 中,這樣我們可以在 ES 通過(guò)字段來(lái)搜索,也可以在 kibana 的 Discover 界面添加列表展示的字段。
坑:我們后端項(xiàng)目的不同服務(wù)打印了兩種不同格式的日志,那這種如何匹配?
再加一個(gè) match 就可以了。
filter { grok { match => [ "message", "(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3})\s+\[(?.*)\]\s+(?\w*)\s{1,2}+(?\S*)\s+-\s+(?.*)\s*"] match => [ "message", "(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3})\s{1,2}+(?\w*)\s{1,2}+.\s---+\s\[(?.*)\]+\s(?\S*)\s*:+\s(?.*)\s*"] }}
當(dāng)任意一個(gè) message 匹配上了這個(gè)正則,則 grok 執(zhí)行完畢。假如還有第三種格式的 message,那么雖然 grok 沒(méi)有匹配上,但是 message 也會(huì)輸出到 ES,只是這條日志在 ES 中不會(huì)展示 logTime、level 等字段。
3.3.4 multiline 插件
還有一個(gè)坑的地方是錯(cuò)誤日志一般都是很多行的,會(huì)把堆棧信息打印出來(lái),當(dāng)經(jīng)過(guò) logstash 解析后,每一行都會(huì)當(dāng)做一條記錄存放到 ES,那這種情況肯定是需要處理的。這里就需要使用 multiline 插件,對(duì)屬于同一個(gè)條日志的記錄進(jìn)行拼接。
3.3.4.1 安裝 multiline 插件
multiline 不是 logstash 自帶的,需要單獨(dú)進(jìn)行安裝。我們的環(huán)境是沒(méi)有外網(wǎng)的,所以需要進(jìn)行離線安裝。
介紹在線和離線安裝 multiline 的方式:
在線安裝插件。在 logstash 根目錄執(zhí)行以下命令進(jìn)行安裝。
bin/logstash-plugin install logstash-filter-multiline
離線安裝插件。在有網(wǎng)的機(jī)器上在線安裝插件,然后打包。
bin/logstash-plugin install logstash-filter-multilinebin/logstash-plugin prepare-offline-pack logstash-filter-multiline
拷貝到服務(wù)器,執(zhí)行安裝命令。
bin/logstash-plugin install file:///home/software/logstash-offline-plugins-7.6.2.zip
安裝插件需要等待 5 分鐘左右的時(shí)間,控制臺(tái)界面會(huì)被 hang 住,當(dāng)出現(xiàn) Install successful
表示安裝成功。
檢查下插件是否安裝成功,可以執(zhí)行以下命令查看插件列表。當(dāng)出現(xiàn) multiline 插件時(shí)則表示安裝成功。
bin/logstash-plugin list
3.3.4.2 使用 multiline 插件
如果要對(duì)同一條日志的多行進(jìn)行合并,你的思路是怎么樣的?比如下面這兩條異常日志,如何把文件中的 8 行日志合并成兩條日志?
多行日志示例
思路是這樣的:
第一步:每一條日志的第一行開(kāi)頭都是一個(gè)時(shí)間,可以用時(shí)間的正則表達(dá)式匹配到第一行。第二步:然后將后面每一行的日志與第一行合并。第三步:當(dāng)遇到某一行的開(kāi)頭是可以匹配正則表達(dá)式的時(shí)間的,就停止第一條日志的合并,開(kāi)始合并第二條日志。第四步:重復(fù)第二步和第三步按照這個(gè)思路,multiline 的配置如下:
filter { multiline { pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}.\d{3}" negate => true what => "previous" }}
時(shí)間的正則表達(dá)式就是這個(gè) pattern 字段,大家可以根據(jù)自己項(xiàng)目中的日志的時(shí)間來(lái)定義正則表達(dá)式。
pattern: 這個(gè)是用來(lái)匹配文本的表達(dá)式,也可以是grok
表達(dá)式what: 如果pattern
匹配成功的話,那么匹配行是歸屬于上一個(gè)事件,還是歸屬于下一個(gè)事件。previous: 歸屬于上一個(gè)事件,向上合并。
next: 歸屬于下一個(gè)事件,向下合并
negate: 是否對(duì) pattern 的結(jié)果取反false: 不取反,是默認(rèn)值。
true: 取反。將多行事件掃描過(guò)程中的行匹配邏輯取反(如果 pattern 匹配失敗,則認(rèn)為當(dāng)前行是多行事件的組成部分)
參考 multiline 官方文檔 2
3.3.5 多行被拆分
坑:Java 堆棧日志太長(zhǎng)了,有 100 多行,被拆分了兩部分,一部分被合并到了原來(lái)的那一條日志中,另外一部分被合并到了不相關(guān)的日志中。
如下圖所示,第二條日志有 100 多行,其中最后一行被錯(cuò)誤地合并到了第三條日志中。
日志合并錯(cuò)亂
為了解決這個(gè)問(wèn)題,我是通過(guò)配置 filebeat 的 multiline 插件來(lái)截?cái)嗳罩镜?。為什么不?logstash 的 multiline 插件呢?因?yàn)樵?filter 中使用 multiline 沒(méi)有截?cái)嗟呐渲庙?xiàng)。filebeat 的 multiline 配置項(xiàng)如下:
multiline.type: patternmultiline.pattern: "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}.\d{3}"multiline.negate: truemultiline.match: aftermultiline.max_lines: 50
配置項(xiàng)說(shuō)明:
multiline.pattern:希望匹配到的結(jié)果(正則表達(dá)式)multiline.negate:值為 true 或 false。使用 false 代表匹配到的行合并到上一行;使用 true 代表不匹配的行合并到上一行multiline.match:值為 after 或 before。after 代表合并到上一行的末尾;before 代表合并到下一行的開(kāi)頭multiline.max_lines:合并的最大行數(shù),默認(rèn) 500multiline.timeout:一次合并事件的超時(shí)時(shí)間,默認(rèn)為 5s,防止合并消耗太多時(shí)間導(dǎo)致 filebeat 進(jìn)程卡死我們重點(diǎn)關(guān)注 max_lines 屬性,表示最多保留多少行后執(zhí)行截?cái)啵@里配置 50 行。
注意:filebeat 和 logstash 我都配置了 multiline,沒(méi)有驗(yàn)證過(guò)只配置 filebeat 的情況。參考 Filebeat 官方文檔 3
3.3.6 mutate 插件
當(dāng)我們將日志解析出來(lái)后,Logstash 自身會(huì)傳一些不相關(guān)的字段到 ES 中,這些字段對(duì)我們排查線上問(wèn)題幫助不大??梢灾苯犹蕹?。
坑:輸出到 ES 的日志包含很多無(wú)意義字段。
這里我們就要用到 mutate 插件了。它可以對(duì)字段進(jìn)行轉(zhuǎn)換,剔除等。
比如我的配置是這樣的,對(duì)很多字段進(jìn)行了剔除。
mutate { remove_field => ["agent","message","@version", "tags", "ecs", "input", "[log][offset]"]}
注意:一定要把 log.offset 字段去掉,這個(gè)字段可能會(huì)包含很多無(wú)意義內(nèi)容。
關(guān)于 Mutate 過(guò)濾器它有很多配置項(xiàng)可供選擇,如下表格所示:
Mutate 過(guò)濾器配置選項(xiàng)
參考 Mutate 參考文章 4
3.3.7 date 插件
到 kibana 查詢(xún)?nèi)罩緯r(shí),發(fā)現(xiàn)排序和過(guò)濾字段 @timestamp
是 ES 插入日志的時(shí)間,而不是打印日志的時(shí)間。
這里我們就要用到 date
插件了。
上面的 grok 插件已經(jīng)成功解析出了打印日志的時(shí)間,賦值到了 logTime
變量中,現(xiàn)在用 date 插件將 logTime
匹配下,如果能匹配,則會(huì)賦值到 @timestamp
字段,寫(xiě)入到 ES 中的 @timestamp
字段就會(huì)和日志時(shí)間一致了。配置如下所示:
date { match => ["logTime", "MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"]}
但是經(jīng)過(guò)測(cè)試寫(xiě)入到 ES 的 @timestamp
日志時(shí)間和打印的日志時(shí)間相差 8 小時(shí)。如下圖所示:
我們到 ES 中查詢(xún)記錄后,發(fā)現(xiàn) @timestamp
字段時(shí)間多了一個(gè)字母 Z
,代表 UTC
時(shí)間,也就是說(shuō) ES 中存的時(shí)間比日志記錄的時(shí)間晚 8 個(gè)小時(shí)。
我們可以通過(guò)增加配置 timezone => "Asia/Shanghai" 來(lái)解決這個(gè)問(wèn)題。修改后的配置如下所示:
date { match => ["logTime", "MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"]}
調(diào)整后,再加一條日志后查看結(jié)果,Kibana 顯示 @timestamp 字段和日志的記錄時(shí)間一致了。
3.4 Output 插件
Logstash 解析和轉(zhuǎn)換后的日志最后輸出到了 Elasticsearch 中,由于我們 ES 是集群部署的,所以需要配置多個(gè) ES 節(jié)點(diǎn)地址。
output { stdout { } elasticsearch { hosts => ["10.2.1.64:9200","10.2.1.65:9200","10.27.2.1:9200"] index => "qa_log" }}
注意這里的 index 名稱(chēng) qa_log 必須是小寫(xiě),不然寫(xiě)入 es 時(shí)會(huì)報(bào)錯(cuò)。
3.5 完整配置
logstah 配置文件內(nèi)容如下:
input { beats { port => 9900 }}filter { multiline { pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}.\d{3}" negate => true what => "previous" } grok { match => [ "message", "(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3})\s+\[(?.*)\]\s+(?\w*)\s{1,2}+(?\S*)\s+-\s+(?.*)\s*"] match => [ "message", "(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3})\s{1,2}+(?\w*)\s{1,2}+.\s---+\s\[(?.*)\]+\s(?\S*)\s*:+\s(?.*)\s*"] match => [ "source", "/home/passjava/logs/(?\w+)/.*.log" ] overwrite => [ "source"] break_on_match => false } mutate { convert => { "bytes" => "integer" } remove_field => ["agent","message","@version", "tags", "ecs", "_score", "input", "[log][offset]"] } useragent { source => "user_agent" target => "useragent" } date { match => ["logTime", "MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"] timezone => "Asia/Shanghai" }}output { stdout { } elasticsearch { hosts => ["10.2.1.64:9200","10.2.1.65:9200","10.2.1.66:9200"] index => "qa_log" }}
四、Logstash 怎么跑起來(lái)的
4.1 Logstash 如何運(yùn)行的
你會(huì)好奇 Logstash 是怎么運(yùn)行起來(lái)的嗎?
官方提供的啟動(dòng)方式是執(zhí)行 logstash -f weblog.conf 命令來(lái)啟動(dòng),當(dāng)執(zhí)行這個(gè)命令的時(shí)候其實(shí)會(huì)調(diào)用 Java 命令,以及設(shè)置 java 啟動(dòng)參數(shù),然后傳入了一個(gè)配置文件 weblog.conf 來(lái)啟動(dòng) Logstash。
cd /home/logstash-7.6.2sudo ./bin/logstash -f weblog.conf
當(dāng)啟動(dòng)完之后,我們通過(guò)命令來(lái)看下 Logstash 的運(yùn)行狀態(tài)
ps -ef | grep logstash
執(zhí)行結(jié)果如下圖所示,可以看到用到了 Java 命令,設(shè)置了 JVM 參數(shù),用到了 Logstash 的 JAR 包,傳入了參數(shù)。
所以建議 Logstash 單獨(dú)部署到一臺(tái)服務(wù)器上,避免服務(wù)器的資源被 Logstash 占用。
Logstash 默認(rèn)的 JVM 配置是 -Xms1g -Xmx1g,表示分配的最小和最大堆內(nèi)存大小為 1 G。
那么這個(gè)參數(shù)是在哪里配置的呢?全局搜索下 Xms1g,找到是在這個(gè)文件里面配置的,config\jvm.options,我們可以修改這里面的 JVM 配置。
我們可以調(diào)整 Logstash 的 JVM 啟動(dòng)參數(shù),來(lái)優(yōu)化 Logstash 的性能。
另外 Kibana 上面還可以監(jiān)控 Logstash 的運(yùn)行狀態(tài)(不在本篇討論范圍)。
4.2 Logstash 的架構(gòu)原理
本內(nèi)容參考這篇 Logstash 架構(gòu) 5
Logstash 有多個(gè) input,每個(gè) input 都會(huì)有自己的 codec。
數(shù)據(jù)會(huì)先存放到 Queue 中,Logstash 會(huì)把 Queue 中的數(shù)據(jù)分發(fā)到不同的 pipeline 中。
然后每一個(gè) pipeline 由 Batcher、filter、output 組成
Batcher 的作用是批量地從 Queue 中取數(shù)據(jù)。Batcher 可以配置為一次取一百個(gè)數(shù)據(jù)。
五、Logstash 宕機(jī)風(fēng)險(xiǎn)
5.1 Logstash 單點(diǎn)部署的風(fēng)險(xiǎn)
因?yàn)?Logstash 是單點(diǎn)部署到一臺(tái)服務(wù)器上,所以會(huì)存在兩個(gè)風(fēng)險(xiǎn):
logstash 突然崩了怎么辦?logstash 所在的機(jī)器宕機(jī)了怎么辦?Logstash 所在的機(jī)器重啟了怎么辦?對(duì)于第一個(gè)問(wèn)題,可以安裝 Keepalived 軟件來(lái)保證高可用。另外即使沒(méi)有安裝,當(dāng)手動(dòng)啟動(dòng) Logstash 后,Logstash 也能將未及時(shí)同步的日志寫(xiě)入到 ES。
對(duì)于第二個(gè)問(wèn)題,所在的機(jī)器宕機(jī)了,那可以通過(guò)安裝兩套 Logstash,通過(guò) keepalived 提供的虛擬 IP 功能,切換流量到另外一個(gè) Logstash。關(guān)于如何使用 Keepalived,可以參考之前的 實(shí)戰(zhàn) MySQL 高可用架構(gòu)
對(duì)于第三個(gè)問(wèn)題,就是把啟動(dòng) Logstash 的命令放到開(kāi)機(jī)啟動(dòng)腳本中就可以了,但是存在以下問(wèn)題:
Ubuntu 18.04 版本是沒(méi)有開(kāi)機(jī)啟動(dòng)文件的Logstash 無(wú)法找到 Java 運(yùn)行環(huán)境接下來(lái)我們來(lái)看下怎么進(jìn)行配置開(kāi)機(jī)自啟動(dòng) Logstash。
5.2 開(kāi)機(jī)啟動(dòng) Logstash
5.2.1 創(chuàng)建自動(dòng)啟動(dòng)腳本
建立 rc-local.service 文件
sudo vim /etc/systemd/system/rc-local.service
將下列內(nèi)容復(fù)制進(jìn) rc-local.service 文件
[Unit]Description=/etc/rc.local CompatibilityConditionPathExists=/etc/rc.local [Service]Type=forkingExecStart=/etc/rc.local startTimeoutSec=0StandardOutput=ttyRemainAfterExit=yesSysVStartPriority=99 [Install]WantedBy=multi-user.target
創(chuàng)建文件 rc.local
sudo vim /etc/rc.local
添加啟動(dòng)腳本到啟動(dòng)文件中
#!/bin/sh -e# 啟動(dòng) logstash#nohup /home/software/logstash-7.6.2/bin/logstash -f /home/software/logstash-7.6.2/weblog.conf 啟動(dòng) filebeatnohup /home/software/filebeat-7.6.2-linux-x86_64/filebeat -e -c /home/software/filebeat-7.6.2-linux-x86_64/config.yml &exit 0
5.2.2 修改 Java 運(yùn)行環(huán)境
因在開(kāi)機(jī)啟動(dòng)中,logstash 找不到 java 的運(yùn)行環(huán)境,所以需要手動(dòng)配置下 logstash。
cd /home/software/logstash-7.6.2/bin/sudo vim logstash.lib.sh
在 setup_java() 方法的第一行加入 JAVA_HOME 變量,JAVA_HOME 的路徑需要根據(jù)自己的 java 安裝目錄來(lái)。
JAVA_HOME="/opt/java/jdk1.8.0_181"
修改 Java 運(yùn)行環(huán)境
5.2.3 權(quán)限問(wèn)題
給 rc.local 加上權(quán)限, 啟用服務(wù)
sudo chmod +x /etc/rc.localsudo systemctl enable rc-localsudo systemctl stop rc-local.servicesudo systemctl start rc-local.servicesudo systemctl status rc-local.service
Logstash 啟動(dòng)成功
然后重啟機(jī)器,查看 logstash 進(jìn)程是否正在運(yùn)行,看到一大串 java 運(yùn)行的命令則表示 logstash 正在運(yùn)行。
ps -ef | grep logstash
六、總結(jié)
本篇講解了 Logstash 在集群環(huán)境下的部署架構(gòu)圖、Logstash 遇到的幾大坑、以及 Logstash 的運(yùn)行機(jī)制和架構(gòu)原理。
Logstash 還是非常強(qiáng)大的,有很多功能未在本篇進(jìn)行講解,本篇也是拋磚引玉,感興趣的讀者朋友們可以加我好友 passjava 共同探索。
更多好文請(qǐng)查看:
實(shí)戰(zhàn) MySQL 高可用架構(gòu)
一文帶你搭建一套 ELK Stack 日志平臺(tái)
巨人的肩膀
https://blog.csdn.net/xzk9381/article/details/109571087https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.htmlhttps://github.com/logstash-plugins/logstash-patterns-core/blob/main/patterns/ecs-v1/grok-patternshttps://www.runoob.com/regexp/regexp-syntax.htmlhttps://www.elastic.co/guide/en/beats/libbeat/current/config-file-permissions.htmlhttps://www.tutorialspoint.com/logstash/logstash_supported_outputs.htm
參考資料
1input 插件列表: https://www.elastic.co/guide/en/logstash/current/input-plugins.html
2multiline 官方文檔: https://www.elastic.co/guide/en/logstash/current/plugins-codecs-multiline.html#plugins-codecs-multiline-negate
3Filebeat 官方文檔: https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.html
4Mutate 參考文章: https://blog.csdn.net/UbuntuTouch/article/details/106466873
5Logstash 架構(gòu): https://jenrey.blog.csdn.net/article/details/107122930
END -