您好,登錄后才能下訂單哦!
Grok 是 Logstash 最重要的插件。你可以在 grok 里預定義好命名正則表達式,在稍后(grok參數或者其他正則表達式里)引用它。它非常適用于syslog logs,apache和一些其他的webserver logs,以及mysql logs。grok有很多定義好pattern,當然也可以自己定義。
grok的語法:
%{SYNTAX:SEMANTIC}
SYNTAX表示grok定義好的pattern,SEMANTIC表示自定義的字段。
例如192.168.0.100
用%{IP:client}可以將IP定義為client
假如現在某webserver log中的內容為以下格式,
55.3.244.1 GET /index.html 15824 0.043
我們完全可以利用grok將這些信息定義成以下字段
%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}
寫到配置文件中通常這樣子:
input { file { path => "/var/log/http.log" }}filter { grok { match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" } }}
grok過濾后得到的信息成了以下這樣子
client: 55.3.244.1
method: GET
request: /index.html
bytes: 15824
duration: 0.043
如何自定義Pattern?
語法:(?<field_name>the pattern here)
假如有以下內容“
begin 123.456 end
我們希望將123.456定義成request_time字段,可以向下面這樣寫這個正則表達式
\s+(?<request_time>\d+(?:\.\d+)?)\s+
解釋:
\s:匹配任何不可見字符,包括空格、制表符、換頁符等等。等價于[ \f\n\r\t\v]。+表示匹配次數為1次或者多次
(?<request_time> ):這個是grok語法,request_time表示要將捕獲的字符定義成的字段名
\d+:匹配一個或者多個數字
(?:\.\d+):為正則表達式,
(?: pattern):非獲取匹配,匹配pattern但不獲取匹配結果,不進行存儲供以后使用。這在使用或字符“(|)”來組合一個模式的各個部分是很有用。例如“industr(?:y|ies)”就是一個比“industry|industries”更簡略的表達式。
\.\d+:表示點后面跟一個或者多個 數字,(?:\.\d+)?表示點后面跟一個或多個數字這種情況出現0次或者多次,如果為0次,則request_time為一個整數。所以匹配到的結果可能為123.456或者123或者123.4.5.6,這些都滿足條件
測試下:
創建一個配置文件,內容如下:
input {stdin{}} filter { grok { match => { "message" => "\s+(?<request_time>\d+(?:\.\d+)?)\s+" } } } output {stdout{}}
運行 logstash 進程然后輸入 "begin 123.456 end",你會看到類似下面這樣的輸出:
{ "message" => "begin 123.456 end", "@version" => "1", "@timestamp" => "2014-08-09T11:55:38.186Z", "host" => "raochenlindeMacBook-Air.local", "request_time" => "123.456" }
練習:
/var/log/userlog.info 日志文件中獲取到的信息為以下格式,需要自定義 2016-05-20T20:00:15.703407+08:00 localhost [audit root/13283 as root/13283 on pts/0/172.16.100.99:64790->10.10.10.6:22]: #=== session closed === 2016-05-21T09:52:54.424055+08:00 localhost [audit root/13558 as root/13558 on pts/0/172.16.100.99:50897->10.10.10.6:22]: #=== session opened === 2016-05-21T09:53:25.687134+08:00 localhost [audit root/13558 as root/13558 on pts/0/172.16.100.99:50897->10.10.10.6:22] /root: cd /etc/logstash/conf.d/ 2016-05-21T09:53:26.284741+08:00 localhost [audit root/13558 as root/13558 on pts/0/172.16.100.99:50897->10.10.10.6:22] /etc/logstash/conf.d: ll
注意上面的日志文件中不是每一行的內容格式都是一樣的,grok表達式如下
%{TIMESTAMP_ISO8601:timestamp} %{IPORHOST:login_host} \[\S+ %{USER:login_user}/%{NUMBER:pid} as %{USER:sudouser}/%{NUMBER:sudouser_pid} on %{WORD:tty}/%{NUMBER:tty_id}/%{IPORHOST:host_ip}:%{NUMBER:source_port}-\>%{IPORHOST:local_ip}:%{NUMBER:dest_port}\](?:\:|) (%{UNIXPATH:current_path} %{GREEDYDATA:command}|%{GREEDYDATA:detail})
注意:(?:\:|) (%{UNIXPATH:current_path} %{GREEDYDATA:command}|%{GREEDYDATA:detail})
上面的日志內容在后面出現了不一樣的地方
該如何處理?冒號可能有也可能沒有,必須對冒號進行匹配,正則表達式如下
(?:\:|) 還可以這樣寫 (\:)? 表示冒號出現一次或者多次
當沒有冒號,后面的信息是以下內容時,
/root: cd /etc/logstash/conf.d/
grok這樣寫,
%{UNIXPATH:current_path} %{GREEDYDATA:command}
當出現
#=== session closed ===
這樣的內容時,grok這樣寫,
%{GREEDYDATA:detail}
但是這兩種情況需要加“|”來判斷,表示或,所以正確的寫法為
(%{UNIXPATH:current_path} %{GREEDYDATA:command}|%{GREEDYDATA:detail})
注意如果上面的grok語句順序調整為下面這樣子時
(%{GREEDYDATA:detail}|%{UNIXPATH:current_path} %{GREEDYDATA:command})
就會有問題,它會將
/root: cd /etc/logstash/conf.d/
全部匹配成detail。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。