Logstash filter 的使用
Filter插件(过滤器插件)是Logstash功能强大的主要原因,它可以对Logstash Event进行丰富的处理,比如说解析数据、删除字段、类型转换等等,常见的有如下几个:
grok:正则匹配解析
date: 日期解析
dissect:分割符解析
mutate:对字段做处理,比如重命名、删除、替换等
json:按照json解析字段内容到指定字段中
geoip:增加地理位置数据
ruby: 利用ruby代码来动态修改Logstash Event
Grok插件
grok是一个十分强大的logstash filter插件,他可以通过正则解析任意文本,将非结构化日志数据解析成结构化和方便查询的结构内容,将其定义成我们平时容易理解的一些字段名称。他是目前logstash 中解析非结构化日志数据最好的方式。
使用grok filter需要在logstash的配置文件中加上这样的内容:
filter {
grok {
match => {
"message" => "grok_pattern"
}
}
}
这段代码中除了grok_pattern(grok表达式,[ˈpætərn]模式)以外都是logstash的关键字。grok_pattern部分需要使用者填充自己的解析方式。
grok_pattern由零个或多个%{SYNTAX:SEMANTIC}组成
其中SYNTAX是表达式的名字,即文本匹配的模式的名称,是由grok提供的,例如数字表达式的名字是NUMBER,IP地址表达式的名字是IP。
SEMANTIC表示解析出来的这个字符的名字,即为匹配的文本提供的标识符,由自己定义,例如IP字段的名字可以是client。【syntax [ˈsɪntæks]语法,semantic [sɪˈmæntɪk]语义】
对于下面这条日志:
192.168.10.3 GET /index.html 15824 0.043
可以这样解析:
将会得到这样的结果:
* client: 192.168.10.3
* method: GET
* request: /index.html
* bytes: 15824
* duration: 0.043
数字表达式的名字是NUMBER,%{NUMBER:duration}可以匹配数值类型,但是grok匹配出的内容都是字符串类型,可以通过在最后指定为int或者float来强制转换类型。%{NUMBER:duration:float}
data_type 目前只支持两个值:int 和 float。
grok提供了哪些SYNTAX?可以查看文件grok-patterns,它默认放在路径/usr/local/logstash-7.3.0/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/目录下。
测试:创建一个测试配置文件,如test.conf,内容如下:
[root@elk01 ~]# vim /usr/local/logstash-7.3.0/config/test.conf
input {stdin{}}
filter {
grok {
match => {
"message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
}
}
}
output {stdout{codec => rubydebug}}
使用test.conf启动一个logstash实例,通过键盘输入如下内容:
192.168.10.3 GET /index.html 15824 0.043
[root@elk01 ~]# logstash -f /usr/local/logstash-7.3.0/config/test.conf #之前有实例可以--path.data=换个路径
默认grok调用的是:
/usr/local/logstash-7.3.0/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/这个目录下的正则
假设现在要匹配一个正则表达式为regexp的字符串,而grok预定义的SYNTAX都不满足,也可以自己定义一个SYNTAX。
自定义SYNTAX方式有两种:
1)直接在grok里面使用自定义表达式
语法格式:(?<filed_name>pattern)
?<filed_name>表示要取出里面的值,pattern就是正则表达式
例如:定制化字段,取出想要的字段
“6.18 beijing sunny”,然后取出每一个字段
编辑test.conf文件,内容如下:
[root@elk01 ~]# vim /usr/local/logstash-7.3.0/config/test.conf
input {stdin{}}
filter {
grok {
match => {
"message" => "(?<date>\d+\.\d+)\s+(?<city>\w+)\s+(?<weather>\w+)"
}
}
}
output {stdout{codec => rubydebug}}
运行logstash,输入“6.18 beijing sunny”内容,并查看输出结果
[root@elk01 ~]# logstash -f /usr/local/logstash-7.3.0/config/test.conf --path.data=/aa
(2)自定义表达式文件
在某个目录下创建一个文件,文件名自定义,如在/usr/local/logstash-7.3.0/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/目录下创建正则表达式文件test
将目录加入grok路径: patterns_dir => "./patterns"
将想要增加的正则表达式写入,格式:SYNTAX_NAME regexp
使用方法和使用默认SYNTAX相同:%{SYNTAX_NAME:SEMANTIC}
例如:使用grok自定义正则去匹配下边的日志
10.173.28.112 2018-11-22 16:30:58 GET /AUTO/users/loginSuccess.do 200 46112 0.075
在/usr/local/logstash-7.3.0/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/
目录下创建正则表达式文件test,内容如下:
[root@elk01 ~]# vim /usr/local/logstash-7.3.0/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/test #简单的
USER_IPADDRESS ([0-9\.]+)\s+
DATETIME ([0-9\-]+\s[0-9\:]+)\s+
METHOD ([A-Z]+)\s+
URL ([\/A-Za-z0-9\.]+)\s+
STATUS ([0-9]+)\s+
REQUEST_SEND ([0-9]+)\s+
REQUEST_TIME ([0-9\.]+)
编辑logstash配置文件test.conf文件,内容如下:
[root@elk01 ~]# vim /usr/local/logstash-7.3.0/config/test.conf
input {stdin{}}
filter {
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{USER_IPADDRESS:user_ip} %{DATETIME:date} %{METHOD:method} %{URL:url} %{STATUS:status} %{REQUEST_SEND:request_send} %{REQUEST_TIME:request_time}" }
}
}
output {stdout{codec => rubydebug}}
进入/usr/local/logstash-7.3.0/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/目录下
运行logstash程序:查看输出结果
总结:
grok是通过系统预定义的正则表达式或者通过自己定义正则表达式来匹配日志中的各个值。
正则解析式比较容易出错,建议先调试,kibana提供了grok debbuger
使用Grok Filter插件编辑解析nginx日志
grok作为一个logstash的过滤插件,支持根据正则表达式解析文本日志行。在生产环境中,nginx日志格式往往使用的是自定义的格式,我们需要把logstash中的message结构化后再存储,方便kibana的搜索和统计,因此需要对message进行解析。
Grok插件使用详解:
Grok filter plugin | Logstash Reference [7.3] | Elastic
本文采用grok过滤器,使用match正则表达式解析,根据自己的log_format定制。
Nginx日志格式
log_format配置如下:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main; #注释取消
$remote_addr变量:记录了客户端的IP地址(普通情况下)。
$remote_user变量:当nginx开启了用户认证功能后,此变量记录了客户端使用了哪个用户进行了认证。
$time_local变量:记录了当前日志条目的时间。
$request变量:记录了当前http请求的方法、url和http协议版本。
$status变量:记录了当前http请求的响应状态,即响应的状态码,比如200、404等响应码,都记录在此变量中。
$body_bytes_s