在elk+filebeat都安裝好,且明白了基本流程后,主要的就是寫logstash的filter了,以此來解析特定格式的日志
logstash的filter是用插件實現的,grok是其中一個,用來解析自定義結構的日志,就是說可以完全自定義的去解析
grok的語法是%{pattern:field}
pattern是指模板(或者說是類型),logstash內置了很多,也可以自定義(用正則)
field是指解析后的鍵值中的鍵,當然值就是從日志解析出來的內容
(無論用什么pattern解析到elasticsearch默認都是用string存儲,可以通過%{pattern:field:int}將之轉換為number類型就可以進行加減計算了,只支持int和float)
比如,一個日志文件中是序號+ip,這樣
1 127.0.0.1 2 127.0.0.2 3 127.0.0.3
filter就可以這樣寫(input省略了,肯定是從filebeat來的,output中指定index,方便測試)
filter { grok { match => { "message" => "%{NUMBER:myid} %{IP:myip}"} } } output { elasticsearch { hosts => "localhost" index => "mytest" } }
那么日志到 elasticsearch中,就是這樣:
{ ... "hits" : { ... "hits" : [ { ... "_source" : { "message" : "1 127.0.0.1", ... "myid" : "1", "myip" : "127.0.0.1" } }, { ... "_source" : { "message" : "2 127.0.0.2", ... "myid" : "2", "myip" : "127.0.0.2" } }, { ... "_source" : { ... "myid" : "3", "myip" : "127.0.0.3" } } ] } }
kibana中的效果
grok的基礎用法就是這樣了,一般來說內置的pattern就夠用了
更多pattern可以看https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns
像IP、NUMBER這樣的基本pattern位於grok-patterns中,常用的有:
INT | int類型 |
NUMBER | 數字 |
DATA | 數據,可以對應字符串 |
GREEDYDATA | 數據,可以對應字符串,貪婪匹配 |
QUOTEDSTRING | 帶引號的字符串,可以簡寫為QS |
WORD | 一個詞 |
IP | ip地址,v4 或 v6 |
DATE | 日期 |
TIME | 時間 |
DATESTAMP | 日期+時間 |
PATH | 系統路徑 |
HOSTNAME | 計算機名 |
MAC | mac地址 |
UUID | uuid |
LOGLEVEL | 日志等級 |
EMAILADDRESS | email地址 |
另外,還有可以直接用的模板集合,比如官方文檔中的例子:
filter { grok { match => { "message" => "%{COMBINEDAPACHELOG}"} } }
這個COMBINEDAPACHELOG就是一個內置的集合,這種集合還有很多,也在上面那個鏈接中,COMBINEDAPACHELOG就位於httpd,它的定義是:
COMBINEDAPACHELOG %{HTTPD_COMBINEDLOG} HTTPD_COMBINEDLOG %{HTTPD_COMMONLOG} %{QS:referrer} %{QS:agent} HTTPD_COMMONLOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{HTTPDUSER:auth} ...
(HTTPD_COMMONLOG的定義有點長,就省略了~~)
當日志的結構比較多,就需要自定義為模板集合,方便管理(自定義模板是一樣的方式,感覺沒必要,用內置的組合成自己的集合就行了)
mkdir -p /etc/logstash/patterns
vi /etc/logstash/patterns/test.conf
MYPATTERN %{NUMBER:myid} %{IP:myip}
filter改為
filter { grok { patterns_dir => ["/etc/logstash/patterns"] match => { "message" => "%{MYPATTERN}"} } }
測試下,效果當然跟上面是一樣的。
還有一點,pattern本質都是正則,%{}之間的空格不是結構要求,而是因為日志就是空格分隔的,如果日志都用空格和-來分隔,那就是:
MYPATTERN %{TIME:mytime} - %{DATA:mythread} - %{LOGLEVEL:mylevel} - %{DATA:myclass} - %{GREEDYDATA:myinfo}
特別說明一個情況,java中log4j的日志會出現日志級別ERROR和DEBUG后面一個空格,而其他INFO那些后面兩個空格
原因應該是ERROR和DEBUG比INFO那些多一個字母,為了對齊,這種情況難在不知道以致浪費時間到處查解析正確的原因,知道了當然就簡單了
%{LOGLEVEL:mylevel} %{DATA:myclass}
改為
%{LOGLEVEL:mylevel}\s{1,2}%{DATA:myclass}
over