構建基于Docker的ELK日志分析服務
通過構建基于Docker的ELK日志分析服務,進一步增強對日志文件的分析、檢索能力

容器化部署
所謂ELK指的是ElasticSearch、Logstash、Kibana,其中ElasticSearch用于數(shù)據(jù)的存儲、檢索,Logstash用于數(shù)據(jù)的結構化處理,Kibana則進行可視化展示。這里直接通過Docker Compose搭建ELK服務,值得一提的是需保證ElasticSearch、Logstash、Kibana各組件的版本完全一致
#?Compose?版本
version:?'3.8'
#?定義Docker服務
services:
??#?ElasticSearch?服務
??ElasticSearch-Service:
????build:
??????#?指定dockerfile的路徑
??????context:?./ESDockerFile
??????#?指定dockerfile的文件名
??????dockerfile:?Dockerfile
????#?設置dockerfile所構建鏡像的名稱、tag
????image:?es-ik:7.12.0
????container_name:?ElasticSearch-Service
????ports:
??????-?9200:9200
??????-?9300:9300
????environment:
??????-?"ES_JAVA_OPTS=-Xms2g?-Xmx2g"
??????-?"discovery.type=single-node"
??????-?"TZ=Asia/Shanghai"
????volumes:
??????#?ES數(shù)據(jù)目錄
??????-?/Users/zgh/Docker/ELK/ES/data:/usr/share/elasticsearch/data
??????#?ES日志目錄
??????-?/Users/zgh/Docker/ELK/ES/logs:/usr/share/elasticsearch/logs
??#?Logstash?服務
??Logstash-Service:
????image:?logstash:7.12.0
????container_name:?Logstash-Service
????ports:
??????-?5044:5044
????environment:
??????-?"xpack.monitoring.enabled=false"
??????-?"TZ=Asia/Shanghai"
????volumes:
??????#?Logstash配置文件
??????-?/Users/zgh/Docker/ELK/Logstash/conf/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
??????#?自定義的索引模板文件
??????-?/Users/zgh/Docker/ELK/Logstash/conf/customTemplate.json:/usr/share/logstash/config/customTemplate.json
??????#?日志文件所在目錄
??????-?/Users/zgh/Docker/ELK/Logstash/LocalLog:/home/Aaron/LocalLog
????depends_on:
??????-?ElasticSearch-Service
??#?Kibana?服務
??Kibana-Service:
????image:?kibana:7.12.0
????container_name:?Kibana-Service
????ports:
??????-?5601:5601
????environment:
??????-?"ELASTICSEARCH_HOSTS=http://ElasticSearch-Service:9200"
??????-?"TZ=Asia/Shanghai"
????depends_on:
??????-?ElasticSearch-Service
同時為對中文分詞提供更好的支持,這里以ElasticSearch官方鏡像為基礎重新構建安裝了ik分詞器的ES鏡像,Dockerfile如下所示
#?基礎鏡像環(huán)境:?ES?7.12.0
FROM?elasticsearch:7.12.0
#?切換目錄
WORKDIR?/usr/share/elasticsearch/plugins
#?安裝與ES版本相同的IK分詞器
RUN?elasticsearch-plugin?install?-b?\
??https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.0/elasticsearch-analysis-ik-7.12.0.zip
上述兩文件的相對路徑關系如下圖所示

Logstash
配置
Logstash作為一款主流的日志處理框架,通過提供形式多樣的插件極大地豐富了表現(xiàn)力。具體地,我們通過logstash.conf配置文件進行配置。如下所示
input?{
??file?{
????#?容器下的日志路徑,?支持遞歸匹配路徑
????path?=>?"/home/Aaron/LocalLog/**/*.*"
????#?排除壓縮文件類型
????exclude?=>?["*.zip",?"*.7z",?"*.rar"]
????#?使用read模式,一方面每次都會從文件開始處讀取,另一方面讀取完后會自動刪除日志文件
????mode?=>?"read"
????
????#?文件塊大小, Unit:?字節(jié)。4194304字節(jié)?= 4MB
????file_chunk_size?=>?4194304
????
????#?檢查文件的頻率
????stat_interval?=>?"200?ms"
????#?發(fā)現(xiàn)新文件的頻率:?stat_interval?*?discover_interval
????discover_interval?=>?1
????#?合并多行數(shù)據(jù)
????codec?=>?multiline?{
??????#?正則表達式:?以時間信息開頭
??????pattern?=>?"^%{TIMESTAMP_ISO8601}"
??????#?true:?否定正則表達式,?即如果不匹配的話
??????negate?=>?true
??????#?當negate為true,?即正則表達式不匹配時,?當前日志歸屬于上一條日志
??????what?=>?"previous"
??????#?檢測多行的等待時間閾值,Unit:?s
??????auto_flush_interval?=>?1
????}
??}
}
filter?{
??#?解析日志進行結構化
??grok?{
????match?=>?{
??????"message"?=>?"%{TIMESTAMP_ISO8601:logtime}?%{LOGLEVEL:level}?%{WORD:componentId}\.%{WORD:segmentId}?\[%{DATA:threaad}\]?\[%{DATA:method}\]?%{GREEDYDATA:message}"
????}
????#?重寫message字段
????overwrite?=>?["message"]
??}
??#?通過指定字段計算Hash值
??fingerprint?{
????method?=>?"MURMUR3"
????source?=>?["logtime",?"threaad",?"message"]
????concatenate_sources?=>?"true"
????target?=>?"[@metadata][fingerprint]"
??}
??#?給SQL日志打標簽
??if?[message]?=~?"==>?.*"?or?[message]?=~?"<==?.*"?{
????mutate?{
??????#?對tags字段添加值
??????add_tag?=>?["SQL"]
????}
??}
??#?解析時間并轉存到?@timestamp?字段
??date?{
????#?logtime字段按ISO8601格式進行解析
????match?=>?["logtime",?"ISO8601"]
????#?將解析后的時間存儲到給定的目標字段
????target?=>?"@timestamp"
????#?刪除logtime字段
????remove_field?=>?["logtime"]
??}
??#?解析日志名稱并轉存到logFile字段
??mutate?{
????#?日志文件路徑按/切分
????split?=>?{?"path"?=>?"/"?}
????#?添加logFile日志文件名字段
????add_field?=>?{?"logFile"?=>?"%{[path][-1]}"?}
????#?刪除無用字段
????remove_field?=>?["host",?"@version",?"path"]
??}
}
output?{
??elasticsearch?{
????#?ES地址
????hosts?=>?["http://ElasticSearch-Service:9200"]
????#?索引名稱
????index?=>?"logstash-%{componentId}"
????#?將計算出的Hash值作為文檔ID
????document_id?=>?"%{[@metadata][fingerprint]}"
????#?使能模板管理模板
????manage_template?=>?true
????#?模板名稱
????template_name?=>?"custom_template"
????#?容器下的模板文件路徑
????template?=>?"/usr/share/logstash/config/customTemplate.json"
??}
??#?Only?For?Debug
??#?stdout?{
??#???codec??=>?rubydebug?{
??#?????#?是否輸出元數(shù)據(jù)字段
??#?????metadata?=>?true
??#???}
??#?}
}
Plugin
這里對上述配置文件所使用的各種插件進行介紹
File
File作為Input Plugin輸入插件的一種,用于實現(xiàn)通過日志文件讀取日志信息。具體地
path:指定日志文件所在路徑,支持遞歸 mode:在read模式下,一方面每次都會從文件開始處讀取,另一方面讀取完后會自動刪除日志文件。這里由于我們處理的是靜態(tài)的日志文件,故非常適合使用read模式 exclude:根據(jù)文件名(非路徑)排除文件,這里選擇排除壓縮類型的文件 stat_interval:檢查文件更新的頻率 discover_interval:發(fā)現(xiàn)新文件的頻率,該值是stat_interval配置項的倍數(shù)
Multiline
通常日志都是單行的,但由于異常錯誤的堆棧信息的存在,如下所示。日志中存在多行類型日志的可能性,故這里通過Codec Plugin編解碼插件中的Multiline進行處理,將多行合并為一行
2021-08-12T17:42:31.850+08:00 ERROR hapddg.hapddgweb [http-nio-8080-exec-124] [c.a.t.common.e.GlobalExceptionHandler:49] unexpected exception
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:746)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:360)
... 109 common frames omitted
對于Multiline而言,其常見選項如下所示
pattern:正則表達式。上文配置中我們使用的模式為以時間信息開頭 negate:是否對正則表達式的結果進行否定。上文配置為true,即不匹配pattern配置項指定的正則表達式視為多行并進行處理 what:其可選值有:previous、next。用于多行日志合并時,當前行視為歸屬于上一行還是下一行 auto_flush_interval:在處理當前行時檢測多行的等待時間閾值(Unit: s)。該配置項無默認值,故如果不顯式設置,則會發(fā)現(xiàn)處理日志文件時,輸出結果會丟失最后一行日志
Grok
Filter Plugin過濾器插件中最重要的就屬Grok了,我們就是通過它進行正則捕獲實現(xiàn)對日志數(shù)據(jù)的結構化處理。Grok內置定義了多種常見的正則匹配模式,以大大方便我們日常的使用。對于內置模式的使用語法如下,其中PATTERN_NAME為Grok內置的匹配模式的名稱,并通過capture_name對捕獲的文本進行命名。由于默認情況下,捕獲結果都是保存為字符串類型,所以可以通過可選地data_type進行類型轉換。但僅支持int、float兩種類型
#?語法格式
%{PATTERN_NAME:capture_name:data_type}
#?使用.*正則進行捕獲,并以message命名
%{GREEDYDATA:message}
#?使用.*正則進行捕獲,并以age命名,最后將數(shù)據(jù)類型轉換為int
%{GREEDYDATA:age:int}
對于內置模式無法滿足的場景,Grok也支持用戶自定義正則進行匹配。語法格式及示例如下。其中reg_exp為正則表達式
#?語法格式
(?reg_exp)
#?使用.*正則進行捕獲,并以message命名
(?.*)
這里就Grok中內置的常見模式進行介紹
TIMESTAMP_ISO8601:匹配ISO8601格式的時間。例如:2021-08-12T17:33:47.498+08:00 LOGLEVEL:匹配日志級別 WORD: 匹配字符串,包括數(shù)字、大小寫字母、下劃線 DATA、GREEDYDATA:從這兩個模式的正則表達式.*?和.*就可以看出,后者是前者的貪婪模式版本
現(xiàn)在我們就可以利用Grok處理日志了,假設一條日志的格式如下所示
2021-08-12T17:33:47.498+08:00?INFO?hapddg.hapddgweb?[ActiveMQ?Session?Task-483]?[c.a.s.h.EventHandler:187]?add?event?message?to?queue
直接利用Grok內置的模式對上述日志格式進行結構化處理,如下所示。其中match配置項用于定義待匹配的字段、匹配方式。與此同時,由于已經(jīng)將message中所有信息均捕獲到各個字段了。為避免重復存儲,我們可以通過overwrite重寫默認的message字段
#?解析日志進行結構化
grok?{
??match?=>?{
????"message"?=>?"%{TIMESTAMP_ISO8601:logtime}?%{LOGLEVEL:level}?%{WORD:componentId}\.%{WORD:segmentId}?\[%{DATA:threaad}\]?\[%{DATA:method}\]?%{GREEDYDATA:message}"
??}
??#?重寫message字段
??overwrite?=>?["message"]
}
Fingerprint
Fingerprint同樣是一種Filter Plugin,其通過指定字段計算出一個指紋值。后續(xù)我們會將計算出的指紋值作為文檔ID,來實現(xiàn)重復文檔的去重
method:指定計算指紋信息的算法,支持SHA1、SHA256、SHA384、SHA512、MD5、MURMUR3等。這里我們選用MURMUR3,其作為一種非加密型哈希算法,由于計算快、碰撞低等特點被廣泛應用于哈希檢索等場景 source:利用哪些字段計算指紋信息 concatenate_sources:計算指紋前是否將source配置項指定的所有字段的名稱、值拼接為一個字符串,默認值為false。如果為false,則將只會使用source配置項中指定的最后一個字段進行指紋信息計算。故這里需要顯式設為true target:設置存儲指紋值的字段名。這里使用了元數(shù)據(jù)字段
Logstash從1.5版本開始提供了一種特殊字段——@metadata元數(shù)據(jù)字段。@metadata中的內容不會對外進行輸出(特殊條件下可以通過某種方式進行輸出以便于調試)。故非常適合在Logstash DSL中作為臨時字段使用。否則如果使用普通字段存儲中間結果,還需要通過remove_field進行刪除以避免對外輸出。使用元數(shù)據(jù)字段也很簡單,如果期望使用一個名為tempData1的元數(shù)據(jù)字段。則字段名即為[@metadata][tempData1]。當然其同樣支持字段引用,通過[@metadata][tempData1]直接即可訪問,而在字符串中的則可以通過%{[@metadata][tempData1]}方式進行字段引用。關于元字段的使用示例如下所示
filter{
??mutate?{
????#?將message字段的值?存儲到?[@metadata][tempData1]?字段中
????add_field?=>?{?"[@metadata][tempData1]"?=>?"%{[message]}"?}
????#?將?[@metadata][tempData1]?字段的值?存儲到?outdata2?字段中
????add_field?=>?{?"outdata2"?=>?"%{[@metadata][tempData1]}"?}
??}
}
Mutate
Filter Plugin中的Mutate則可以對字段進行修改,包括但不限于split、join、rename、lowercase等操作。但需要注意的是在一個Mutate塊內各操作不是按書寫的順序執(zhí)行的,而是根據(jù)Mutate Plugin內部某種固定的預設順序依次執(zhí)行的。故如果期望控制各操作的執(zhí)行順序,可以定義多個Mutate塊。因為各Mutate塊的執(zhí)行順序是按書寫順序依次進行的。這里我們利用split對日志文件的path字段按路徑分隔符進行切分,并通過下標-1訪問數(shù)組中的最后一個元素取得日志文件名稱,最后對原path字段進行刪除
而對于各種不同類型的日志,我們期望能夠進行分類、打標簽。這樣便于后續(xù)在檢索日志時更加高效。具體地,對于SQL類型的日志而言,其結構特征為"==>"、"<=="開頭。如下所示
2021-08-17T16:33:11.958+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-1] [c.a.t.m.a.A.deleteData:143] ==> Preparing: delete from tb_person where id in ( ? , ? , ? )
2021-08-17T16:44:11.958+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-1] [c.a.t.m.a.A.deleteData:143] ==> Parameters: 22(Integer), 47(Integer), 60(Integer)
2021-08-17T16:55:11.959+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-1] [c.a.t.m.a.A.deleteData:143] <== Updates: 3
這樣即可結合Logstash條件判斷語句、Mutate的add_tag操作實現(xiàn)對SQL日志打標簽,其中值為"SQL"。此外Logstash還提供了 =~、!~ 運算符分別用于匹配正則、不匹配正則
#?給SQL日志打標簽
if?[message]?=~?"==>?.*"?or?[message]?=~?"<==?.*"?{
??mutate?{
????#?對tags字段添加值
????add_tag?=>?["SQL"]
??}
}
Date
由于Logstash輸出的@timestamp字段值默認為其處理日志文件過程的當前時間,故這里我們需要將日志中記錄的時間信息寫入@timestamp字段,以便后續(xù)的搜索。這里選擇Filter Plugin中的Date實現(xiàn)對于時間字符串的解析處理
match:指定時間字段及其對應的時間格式。其中,支持的時間格式有:ISO8601(例如:2021-08-17T16:55:11.959+08:00)、UNIX(Unix紀元以來的秒數(shù))、UNIX_MS(Unix紀元以來的毫秒數(shù))等 target:存儲解析后時間信息的字段
Elasticsearch
當Logstash完成日志的結構化處理后,即可輸出到ElasticSearch。這里直接選擇Elasticsearch Plugin即可。如下所示,這里我們指定了ES的地址、索引、文檔ID等信息。同時還在其中定義了一個名為custom_template的ES索引模板
elasticsearch?{
??#?ES地址
??hosts?=>?["http://ElasticSearch-Service:9200"]
??#?索引名稱
??index?=>?"logstash-%{componentId}"
??#?將計算出的Hash值作為文檔ID
??document_id?=>?"%{[@metadata][fingerprint]}"
??#?使能模板管理模板
??manage_template?=>?true
??#?模板名稱
??template_name?=>?"custom_template"
??#?容器下的模板文件路徑
??template?=>?"/usr/share/logstash/config/customTemplate.json"
}
Rubydebug
前面提到默認情況下,元數(shù)據(jù)字段不會進行輸出。但實際上在調試過程中可以通過Codec Plugin編解碼插件中的Rubydebug使能輸出元數(shù)據(jù)字段。下面即是在一個標準輸出Stdout中包含元數(shù)據(jù)字段輸出的示例
stdout?{
??codec??=>?rubydebug?{
????#?是否輸出元數(shù)據(jù)字段?
????metadata?=>?true
??}
}
Index Template索引模板
在Logstash的DSL配置文件中我們通過Elasticsearch Plugin定義了一個ES索引模板,并且通過template字段指定在Logstash容器下的索引模板文件路徑。具體地,索引模板文件customTemplate.json的內容如下所示
{
??"index_patterns"?:?"logstash-*",
??"order":?20,
??"settings":{
????"index.refresh_interval":?"1s",
????"index.number_of_replicas":?0,
????"index.lifecycle.name":?"autoRemoveOldData"
??},
??"mappings":{
????"properties"?:?{
??????"@timestamp"?:?{
????????"type"?:?"date"
??????},
??????"level"?:?{
????????"type"?:?"keyword",
????????"norms"?:?false
??????},????????
??????"componentId"?:?{
????????"type"?:?"keyword",
????????"norms"?:?false
??????},
??????"segmentId"?:?{
????????"type"?:?"keyword",
????????"norms"?:?false
??????},
??????"threaad"?:?{
????????"type"?:?"text",
????????"fields"?:?{
??????????"keyword"?:?{
????????????"type"?:?"keyword",
????????????"ignore_above"?:?556
??????????}
????????},
????????"norms"?:?false
??????},
??????"method"?:?{
????????"type"?:?"text",
????????"fields"?:?{
??????????"keyword"?:?{
????????????"type"?:?"keyword",
????????????"ignore_above"?:?556
??????????}
????????},
????????"norms"?:?false
??????},
??????"message"?:?{
????????"type"?:?"text",
????????"analyzer":?"ik_max_word"
??????},
??????"logFile"?:?{
????????"type":?"text",
????????"index"?:?false
??????},
??????"tags"?:?{
????????"type"?:?"keyword",
????????"norms"?:?false
??????}
????}???
??}
}
部分配置項說明如下:
index_patterns:該模板匹配索引名稱的通配符表達式 order:優(yōu)先級,值越大優(yōu)先級越高 index.refresh_interval:索引的刷新時間間隔 index.number_of_replicas:每個主分片的副本數(shù) index.lifecycle.name:ILM索引生命周期中的策略名稱
至此,ELK服務中的兩個關鍵性配置文件均已介紹完畢,其在宿主機下的相關層次結構如下所示

Kibana
本地化
通過Docker Compose創(chuàng)建、啟動ELK服務所需的各容器。進入Kibana容器,修改/usr/share/kibana/config路徑下的配置文件kibana.yml,增加 i18n.locale: "zh-CN" 配置項

修改完畢后,重啟Kibana容器。然后通過 http://localhost:5601 訪問Kibana的Web頁面??梢钥吹?,頁面語言已經(jīng)被修改為中文

個性化配置
點擊【Management】下的【Stack Management】,然后進入【高級設置】進行個性化修改、并保存。具體地:
將日期的顯示格式修改為YYYY-MM-DD HH:mm:ss.SSS,并且將Monday周一作為一周的開始

去除不必要的元字段展示,僅保留 _source, _id, _index 字段

將各種通知信息的保留時間設為5秒

ILM索引生命周期管理
在上文的customTemplate.json索引模板文件中,我們通過index.lifecycle.name配置項定義、關聯(lián)了一個名為autoRemoveOldData的ILM策略??赏ㄟ^【Management】-【Stack Management】-【索引管理】-【索引模板】查看,如下所示

現(xiàn)在我們來創(chuàng)建該策略,通過【Management】-【開發(fā)工具】-【控制臺】發(fā)送如下的PUT請求即可
#?創(chuàng)建名為autoRemoveOldData的策略:自動刪除超過20天的索引
PUT?_ilm/policy/autoRemoveOldData?pretty
{
??"policy":?{
????"phases":?{
??????"hot":?{
????????"min_age":?"0",
????????"actions":?{}
??????},
??????"delete":?{
????????"min_age":?"20d",
????????"actions":?{
??????????"delete":?{
????????????"delete_searchable_snapshot":?true
??????????}
????????}
??????}
????}
??}
}
效果如下所示

通過【Management】-【Stack Management】-【索引生命周期策略】查看,可以看到相應的ILM策略已經(jīng)創(chuàng)建成功

建立索引模式
現(xiàn)在,將我們用于測試的日志文件aaron.log放入LocalLog目錄下,已便讓ELK分析日志

其中測試的日志文件aaron.log的內容如下所示
2021-08-12T17:33:47.498+08:00 INFO hapddg.hapddgweb [ActiveMQ Session Task-483] [c.a.s.h.EventHandler:187] add event message to queue
2021-08-12T17:42:31.850+08:00 ERROR hapddg.hapddgweb [http-nio-8080-exec-124] [c.a.t.common.e.GlobalExceptionHandler:49] unexpected exception
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:746)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:360)
... 109 common frames omitted
2021-08-12T18:22:01.959+08:00 INFO hapddg.hapddgweb [http-nio-8080-exec-137] [c.a.t.s.CallBackServiceImpl:71] sublist is empty
2021-08-12T18:25:02.146+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-135] [c.a.t.s.CallBackServiceImpl:72] query down result is ok
2021-08-12T18:29:02.356+08:00 INFO hapddg.hapddgweb [http-nio-8080-exec-137] [c.a.t.s.CallBackServiceImpl:73] start task
2021-08-17T16:33:11.958+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-1] [c.a.t.m.a.A.deleteData:143] ==> Preparing: delete from tb_person where id in ( ? , ? , ? )
2021-08-17T16:44:11.958+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-1] [c.a.t.m.a.A.deleteData:143] ==> Parameters: 22(Integer), 47(Integer), 60(Integer)
2021-08-17T16:55:11.959+08:00 DEBUG hapddg.hapddgweb [http-nio-8080-exec-1] [c.a.t.m.a.A.deleteData:143] <== Updates: 3
當ELK讀取完日志文件后會自動將其進行刪除,同時通過【Management】-【Stack Management】-【索引管理】-【索引】可以查看相應的索引、文檔已經(jīng)建立完畢

通過【Management】-【Stack Management】-【索引模式】來建立索引模式

定義索引模式的名稱為 logstash-*

同時將 @timestamp 字段作為全局時間篩選的時間字段

實踐
只需第一次在Kibana中建立好索引模式即可,后續(xù)無需再次重復建立?,F(xiàn)在通過【Analytics】-【Discover】即可進行日志的檢索,效果如下所示

Note
Docker掛載Volume
掛載Volume前,一方面需要提前在宿主機下創(chuàng)建相應的目錄、文件;另一方面需要將其加入Docker的File Sharing配置中,由于File Sharing對所配置目錄的子目錄同樣會生效,故一般只需將父目錄加入即可。設置方法如下所示

特別地,在Windows系統(tǒng)下掛載Volume時,需要注意路徑的寫法。例如,Windows系統(tǒng)的路徑 D:\Docker\ELK 應該寫為 /D/Docker/ELK
查看Logstash Plugin版本信息
進入Logstash容器后,可通過執(zhí)行如下命令查看Logstash中各Plugin的版本信息
#?查看Logstash?Plugin版本信息
/usr/share/logstash/bin/logstash-plugin?list?--verbose
調試Logstash Filter
對于Logstash DSL中的Filter Plugin,可通過創(chuàng)建一個臨時的Logstash容器進行調試。具體地,輸入、輸出分別使用標準輸入、標準輸出,過濾器則為待調試的Filter DSL。示例如下
docker?run?--rm?-it?logstash:7.12.0??\
??--path.settings=?-e?'
??#?使用標準輸入
??input?{?
????stdin?{}?
??}
??#?待調試的Filter?DSL
??filter?{????
????mutate?{
??????#?按/進行切分
??????split?=>?{?"message"?=>?"/"?}
??????#?取message數(shù)組最后一個元素值賦給新增字段logFile
??????add_field?=>?{?"logFile"?=>?"%{[message][-1]}"?}
????}
??}
??#?使用標準輸出
??output?{?
?????stdout?{}
??}
'
其中,選項說明如下:
rm:容器退出后自動被刪除 it:為容器分配一個偽輸入終端,并保持容器的標準輸入打開
調試效果如下所示

調試Grok
特別地,對于Filter Plugin中的Grok而言,Kibana還專門提供了一個在線調試工具——Grok Debugger。通過【Management】-【開發(fā)工具】-【Grok Debugger】進入即可使用,效果如下所示

參考文獻
Grok內置模式的正則表達式:https://github.com/logstash-plugins/logstash-patterns-core/blob/main/patterns/legacy/grok-patterns ElasticSearch 7.12版官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/7.12/index.html Logstash 7.12版官方文檔:https://www.elastic.co/guide/en/logstash/7.12/index.html
