Grok(正則捕獲)、Dissect(切分):
grok使用正則匹配來提取非結構化日志數並據解析為結構化和可查詢的內容。
dissect使用多種定界符(非數字和字母的符號,split只能一次只能使用一種定界符)來提取非結構化日志數據。
dissect與grok的不同之處在於它不使用正則表達式並且速度更快。當數據可靠地重復時,解析很有效。當文本結構因行而異時,grok是更好的選擇。當線路的一部分可靠重復時,您可以同時使用dissect和grok作為混合用例。dissect過濾可以解構重復行的部分。grok過濾可以處理剩余的字段值,具有更多的正則表達式可預測。
自定義格式:
(?<field_name>the pattern here)
示例:
[root@node2006 logstash]# bin/logstash -e 'input{stdin{}}filter{grok{match => {"message" => "(?<request_time>\d+\.\d+)" }}}output{stdout{codec=>rubydebug}}' #匹配帶有小數點的數字,這里得到的字段值是字符串類型。logstash中只有三種類型,string,integer,float。如果不指定類型,默認string
123.456
...
{
"message" => "123.456",
"host" => "node2006",
"request_time" => "123.456",
"@version" => "1",
"@timestamp" => 2019-01-25T06:43:37.948Z
}
上面的示例是匹配一個字段。如果為了匹配一行web日志,將全部寫在一行,而且一行過多時就顯的亂了。
還好官方提供了大量的已經寫好的正則規則,只需要調用即可。官方調試地址:http://grokdebug.herokuapp.com/
如果需要自己配置相應的正則規則時,建議把所有的grok表達式統一寫入到patterns
目錄下某個有意義名稱的文件里,並在grok中使用patterns_dir
參數調用即可。這樣就可管理了。
標准格式:
%{SYNTAX:SEMANTIC}
SYNTAX
是與您的文本匹配的模式名稱,正則表達式也在patterns目錄下某個文件里的簡稱
SEMANTIC
是您為匹配的文本提供的標識符,也就是獲取跟據SYNTAX
獲取到的數據的key,獲取到的數據就是value
``` [root@node2006 logstash]# head -n 3 ./vendor/bundle/jruby/2.3.0/gems/logstash-patterns-core-4.1.2/patterns/grok-patterns #logstash自帶的正則表達式就都存放在此文件里,USERNAME就是SYNTAX,[a-zA-Z0-9._-]+就是正則表達式 USERNAME [a-zA-Z0-9._-]+ USER %{USERNAME} EMAILLOCALPART [a-zA-Z][a-zA-Z0-9_.+-=:]+ [root@node2006 logstash]# ```
示例:
[root@node2006 logstash]# cat text.conf
input {
stdin {
}
}
filter {
grok {
match => {
"message" => "\[%{TIMESTAMP_ISO8601:time}\]\|%{IP:remote_addr}\|%{WORD:request_method} %{URIPATHPARAM:request_uri} HTTP/%{NUMBER:httpversion}\|%{NUMBER:status}"
}
}
}
output {
stdout{
codec => rubydebug
}
}
[root@node2006 logstash]# bin/logstash -f text.conf #執行配置文件,並提供數據,根據配置文件中配置的解析數據。
[2018-12-12T10:11:38+08:00]|218.94.48.186|POST /siteapp/users/findUserInfoById HTTP/1.1|200
...
{
"host" => "node2006",
"httpversion" => "1.1",
"time" => "2018-12-12T10:11:38+08:00",
"@version" => "1",
"@timestamp" => 2019-01-26T06:25:35.801Z,
"request_uri" => "/siteapp/users/findUserInfoById",
"remote_addr" => "218.94.48.186",
"request_method" => "POST",
"status" => "200",
"message" => "[2018-12-12T10:11:38+08:00]|218.94.48.186|POST /siteapp/users/findUserInfoById HTTP/1.1|200"
}
上述解析出來的數據,"message"明顯是重復的數據耗費存儲,且如"status"等數據類型應該是數字,方便科學計算。
使用dissect插件實現與grok同樣效果:
[root@node2006 logstash]# cat text.conf
input {
stdin {}
}
filter {
dissect {
mapping => {
"message" => "[%{time}]|%{remote_addr}|%{verb} %{request} HTTP/%{httpversion}|%{status}"
}
}
}
output {
stdout{
codec => rubydebug
}
}
[root@node2006 logstash]# bin/logstash -f text.conf
Sending Logstash logs to /usr/local/pkg/logstash/logs which is now configured via log4j2.properties
{
"remote_addr" => "218.94.48.186",
"status" => "200",
"request" => "/siteapp/users/findUserInfoById",
"@timestamp" => 2019-01-26T07:40:31.354Z,
"time" => "2018-12-12T10:11:38+08:00",
"httpversion" => "1.1",
"@version" => "1",
"verb" => "POST",
"message" => "[2018-12-12T10:11:38+08:00]|218.94.48.186|POST /siteapp/users/findUserInfoById HTTP/1.1|200",
"host" => "node2006"
}
常用配置選項:
參數 | 輸入類型 | 默認值 | 解釋 |
---|---|---|---|
keep_on_match | boole | false | 如果為true,將空捕獲保留為事件字段 |
match | hash | {} | 定義映射位置 |
overwrite | array | [] | 覆蓋已存在的字段中的值,目的是保留最重要的字段 |
patterns_dir | array | [] | Logstash默認帶有一堆模式,當這些模式不適合你時,您自己增加正則匹配時,就可將正則寫在此參數的目錄下的所有文件 |
patterns_files_glob | string | * | 選擇patterns_dir指定的目錄中的某個模式文件 |
tag_on_failure | array | ["_grokparsefailure"] | 沒有成功匹配時,將些值附加到字段 |
下面提供一個對nginx日志的完整配置示例:
[root@node2006 logstash]# cat text.conf
input {
file {
path => "/tmp/text.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
match => {
patterns_dir => ["/usr/local/pkg/logstash/patterns"]
"message" => "%{STANDARDNGINXLOG}"
}
remove_field => ["message"]
}
mutate {
convert => {
"httpversion" => "float"
"response" => "integer"
"bytes" => "integer"
}
}
}
output {
stdout{
codec => rubydebug
}
}
[root@node2006 logstash]# cat patterns/nginx #查看統一管理的正則匹配
STANDARDNGINXLOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
[root@node2006 logstash]#
[root@node2006 logstash]# cat /tmp/text.log #這里存放了一條nginx標准日志
192.168.2.55 - - [24/Jan/2019:12:25:04 -0500] "GET / HTTP/1.1" 200 985 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36" "-"
[root@node2006 logstash]#
[root@node2006 logstash]# bin/logstash -f text.conf #可以看到相應的幾個字段類型已經修改成功,且將不需要message字段刪除了。
{
"auth" => "-",
"bytes" => 985,
"host" => "node2006",
"response" => 200,
"request" => "/",
"timestamp" => "24/Jan/2019:12:25:04 -0500",
"httpversion" => 1.1,
"clientip" => "192.168.2.55",
"@timestamp" => 2019-01-26T12:29:42.429Z,
"ident" => "-",
"@version" => "1",
"verb" => "GET",
"path" => "/tmp/text.log"
}