-
Notifications
You must be signed in to change notification settings - Fork 255
Grok Parser
Grok Parser是一个类似于Logstash Grok Parser一样的解析配置方式,其本质是按照正则表达式匹配解析日志。
"parser":{
"name":"nginx_parser",
"type":"grok",
"grok_mode":"",#默认为空
"grok_patterns":"%{QINIU_LOG_FORMAT}",
"grok_custom_pattern_files":"/etc/logkit/pattern1,/etc/logkit/pattern2",
"grok_custom_patterns":"",
"timezone_offset":"+08",
"labels":"machine nb110,team pandora"
},
-
grok_patterns
必填项, 用于匹配日志的grok表达式,多个用逗号分隔。填写解析日志的grok pattern名称,包括一些logkit自身内置的patterns以及自定义的pattern名称,以及社区的常见grok pattern,如logstash的内置pattern以及常见的grok库pattern- 填写方式是
%{QINIU_LOG_FORMAT},%{COMMON_LOG_FORMAT}
,以百分号和花括号包裹pattern名称,多个pattern名称以逗号分隔。 - 实际匹配过程中会按顺序依次去parse文本内容,以第一个匹配的pattern解析文本内容。
- 需要注意的是,每多一个pattern,解析时都会多解析一个,直到成功为止,所以pattern的数量多有可能降低解析的速度,在数据量大的情况下,建议一个pattern解决数据解析问题。
- 填写方式是
-
labels
可选项, 填一些额外的标签信息,同样逗号分隔,每个部分由空格隔开,左边是标签的key,右边是value。 -
grok_mode
可选项, 若指定grok_mode
为multi
可以针对多行日志解析,默认为空,单行匹配。grok和普通正则一样,默认是不支持匹配回车换行,只针对单行进行解析。注意:指定为multi
以后,grok会把日志中的换行符替换为空格解析。同时若grok parser希望解析多行,则需要在reader
模块填写head_pattern
行首正则表达式。 -
grok_custom_patterns
用户自定义的grok pattern内容,需符合logkit自定义pattern的写法,按行分隔,参见自定义pattern的写法和用法说明 -
grok_custom_pattern_files
用户自定义的一些grok pattern文件,当自定义pattern太长太多,建议用文件功能。 !!!注意:如果修改pattern文件,需要更新logkit Runner相关配置文件,或者重启logkit才能生效!!! -
Grok Parser中解析出的字段
就是grok表达式中命名的字段,还包括labels中定义的标签名,可以在sender中选择需要发送的字段和标签。 -
timezone_offset
解析出的时区信息默认为UTC
时区,使用timezone_offset
可以修改时区偏移量,默认偏移量为0,写法为"+08"、"08"、"8" 均表示比读取时间加8小时,"-08","-8",表示比读取的时间减8小时。若实际为东八区时间,读取为UTC时间,则实际多读取了8小时,需要写"-8",修正回CST中国北京时间。 -
logkit grok pattern
其格式符合%{<捕获语法>[:<字段名>][:<字段类型>]}
,其中中括号的内容可以省略- logkit的grok pattern是logstash grok pattern的增强版,除了完全兼容logstash grok pattern规则以外,还增加了类型,与telegraf的grok pattern规则一致,但是使用的类型是logkit自身定义的。你可以在logstash grok文档中找到详细的grok介绍.
-
捕获语法
是一个正则表达式的名字,比如内置了USERNAME [a-zA-Z0-9._-]+
,那么此时USERNAME
就是一个捕获语法。所以,在使用自定义的正则表达式之前,你需要先为你的正则命名,然后把这个名字当作捕获语法
填写patterns
中,当然,不推荐自己写正则,建议首选内置的捕获语法。 -
字段名
按照捕获语法对应的正则表达式解析出的字段,其字段名称以此命名,该项可以不填,但是没有字段名的grok pattern不解析,无法被logkit sender使用,但可以作为一个中间捕获语法
与别的捕获语法
共同组合一个新的捕获语法
。 -
字段类型
可以不填,默认为string。logkit支持以下类型。-
string
默认的类型 -
long
整型 -
float
浮点型 -
date
时间类型,包括以下格式 -2006/01/02 15:04:05
,-
2006-01-02 15:04:05 -0700 MST
, -
2006-01-02 15:04:05 -0700
, -
2006-01-02 15:04:05
, -
2006/01/02 15:04:05 -0700 MST
, -
2006/01/02 15:04:05 -0700
, -
2006-01-02 -0700 MST
, -
2006-01-02 -0700
, -
2006-01-02
, -
2006/01/02 -0700 MST
, -
2006/01/02 -0700
, -
2006/01/02
, -
Mon Jan _2 15:04:05 2006
ANSIC, -
Mon Jan _2 15:04:05 MST 2006
UnixDate, -
Mon Jan 02 15:04:05 -0700 2006
RubyDate, -
02 Jan 06 15:04 MST
RFC822, -
02 Jan 06 15:04 -0700
RFC822Z, -
Monday, 02-Jan-06 15:04:05 MST
RFC850, -
Mon, 02 Jan 2006 15:04:05 MST
RFC1123, -
Mon, 02 Jan 2006 15:04:05 -0700
RFC1123Z, -
2006-01-02T15:04:05Z07:00
RFC3339, -
2006-01-02T15:04:05.999999999Z07:00
RFC3339Nano, -
3:04PM
Kitchen, -
Jan _2 15:04:05
Stamp, -
Jan _2 15:04:05.000
StampMilli, -
Jan _2 15:04:05.000000
StampMicro, -
Jan _2 15:04:05.000000000
StampNano,
-
-
drop
表示扔掉该字段
-
-
验证自定义pattern的正确性
:http://grokdebug.herokuapp.com, 这个网站可以debug你的grok pattern
-
disable_record_errdata
默认为false
,解析失败的数据会默认出现在"pandora_stash"字段,该选项可以禁止记录解析失败的数据。
- 访问网址: http://grokdebug.herokuapp.com
- 如下图所示,填写各类信息:
[04/Jun/2016:12:41:45 +0100] 1.25 200 192.168.1.1 5.432µs 101
%{TEST_LOG_A}
# Test A log line:
# [04/Jun/2016:12:41:45 +0100] 1.25 200 192.168.1.1 5.432µs 101
DURATION %{NUMBER}[nuµm]?s
RESPONSE_CODE %{NUMBER:response_code}
RESPONSE_TIME %{DURATION:response_time}
TEST_LOG_A \[%{HTTPDATE:timestamp:date}\] %{NUMBER:myfloat:float} %{RESPONSE_CODE} %{IPORHOST:clientip} %{RESPONSE_TIME} %{NUMBER:myint:long}
# Test B log line:
# [04/06/2016--12:41:45] 1.25 mystring dropme nomodifier
TEST_TIMESTAMP %{MONTHDAY}/%{MONTHNUM}/%{YEAR}--%{TIME}
TEST_LOG_B \[%{TEST_TIMESTAMP:timestamp:date}\] %{NUMBER:myfloat:float} %{WORD:mystring:string} %{WORD:dropme:drop} %{WORD:nomodifier}
- 将
基础的grok pattern构成
里面的grok pattern填写到本地文件中,假设存储路径为/home/user/logkit/grok_pattern
。 注意,若修改这个/home/user/logkit/grok_pattern
配置文件,需要重启logkit服务(或者修改对应的grok parser的runner配置文件)才能生效 - 在 logkit的Runner配置文件中,填写grok parser的
grok_custom_pattern_files
配置项 :"grok_custom_pattern_files":"/home/user/logkit/grok_pattern"
- 将
最终使用的grok pattern
里面的模式串,填写到 grok parser的grok_patterns
配置项:"grok_patterns":"%{TEST_LOG_A}"
根据上述配置,一个完整的grok parser配置如下:
"parser":{
"name":"nginx_parser",
"type":"grok",
"grok_patterns":"%{TEST_LOG_A}",
"grok_custom_pattern_files":"/home/user/logkit/grok_pattern"
},
使用grok parser解析nginx/apache日志的过程,实际上就是利用grok pattern(正则表达式)去匹配您的nginx日志,对于像nginx/apache日志这样的成熟日志内容,日志的所有组成部分均已经有非常成熟的grok pattern可以使用,下面我们先介绍下用于解析nginx/apache日志时常用的几个内置在logkit的grok pattern。
-
NOTSPACE
匹配所有非空格的内容,这个是性能较高且最为常用的一个pattern,比如你的日志内容是abc efg
,那么你只要写两个NOTSPACE
的组合Pattern即可,如%{NOTSPACE:field1} %{NOTSPACE:field2}
。 -
QUOTEDSTRING
, 匹配所有被双引号括起来的字符串内容,跟NOTSAPCE类似,会包含双引号一起解析出来,如"abc" - "efx sx"
这样一串日志,写一个组合Pattern%{QUOTEDSTRING:field1} - %{QUOTEDSTRING:field2}
,field2就包含数据"efx sx"
,这个同样性能较高,好处是不怕有空格等其他特殊字符,缺点是解析的内容包含了双引号本身,如果要转换成long等类型需要去掉引号。 -
DATA
匹配所有字符,这个pattern需要结合一些特殊的语境使用,如双引号等特殊字符。举例来说"abc" - "efx sx"
,这样一串日志,可以写一个组合Pattern"%{DATA:field1}" - "%{DATA:field2}"
,这个就起到了QUOTEDSTRING
的效果,另外数据中不会包含双引号。 -
HTTPDATE
匹配常见的HTTP日期类型,类似nginx和Apache生产的timestamp都可以用这个Pattern解析。如[30/Sep/2017:10:50:53 +0800]
,就可以写一个组合Pattern[%{HTTPDATE:ts:date}]
,中括号里面包含HTTPDATE
这个Pattern,就把时间字符串匹配出来了。 -
NUMBER
匹配数字类型,包括整数和浮点数,利用这个Pattern就可以把nginx里面的如响应时间这样的数据解析出来。如"10.10.111.117:8888" [200] "0.002"
,就可以写"%{NOTSPACE:ip}" [%{NUMBER:status:long}] "%{NUMBER:resptime:float}"
来解析出status状态码以及resptime响应时间。
基本上,上述这些基础的grok Pattern 组合起来,就可以解决几乎所有nginx的日志解析,但有时候会遇到一些特殊情况,如某个字段可能存在也可能不存在,比如如下两行日志,我们都希望解析。
- POST中包含HTTP协议信息
"POST /resouce/abc HTTP/1.1"
- GET中不包含协议信息
"GET /resouce/abc"
此时就需要编写一种组合场景,表达或
的逻辑,此时可以在Pattern组合中融入正则表达式的组概念,如下串即可解析:
MYLOGFIANL "%{WORD:verb} %{NOTSPACE:request}\s*(?: HTTP/%{NUMBER:httpversion}|)"
其中括号就是正则表达式的组,组里面还可以包含组,每个组通过"?"问号开头表示可以存在0次或1次,":"冒号后表达匹配的内容。
在nginx日志中常常还会出现内容为空的情况,为空时nginx字段填充-
横杠,此时也可以用类似的方法写或
。
如这两种数据 0.123
以及 -
,如果把"-"当成正常的数字去解析,就会出错,所以需要去掉没有数字的情况,如:
(?:%{NUMBER:bytes}|-)
最后,假设我们遇到一种不太规则的nginx日志写法,如:
110.220.330.550 - - [12/Oct/2017:14:16:50 +0800] "POST /v2/repos/xsxsxs/data HTTP/1.1" 200 729 2 "-" "Faraday v0.13.1" "-" 127.9.2.1:80 www.qiniu.com xsxsxsxsx122dxsxs 0.019
我们就可以用上面描述的方法拼接出如下的串:
NGINX_LOG %{NOTSPACE:client_ip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:ts:date}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:http_version:float})?|%{DATA})" %{NUMBER:resp_code} (?:%{NUMBER:resp_bytes:long}|-) (?:%{NUMBER:resp_body_bytes:long}|-) "(?:%{NOTSPACE:referrer}|-)" %{QUOTEDSTRING:agent} %{QUOTEDSTRING:forward_for} %{NOTSPACE:upstream_addr} (%{HOSTNAME:host}|-) (%{NOTSPACE:reqid}) %{NUMBER:resp_time:float}
最后,你可以在logkit的web页面上调试一下。
快速开始 | Pandora | Readers | Parsers | Senders | Download | 七牛智能日志管理平台 | logkit-pro专业版