为什么要用date
插件:
我们希望日志展示的时间就是日志生成的时间,一般日志中都会附加时间,这样方便根据时间查找问题。但在logstash中,默认使用
@timestamp
时间值来表示日志的时间,@timestamp值的获取是根据logstash本身什么时候处理这条日志数据而产生的。也就是说
@timestamp并不是日志中的时间,所以不管日志是实时的还是非实时的日志,都无法保证日志产生的精确时间。所以我们就需要使用
date插件来匹配日志中产生的时间并将值赋给
@timestamp`,这样最后展示的时间就是日志生成时间。
常用选项:
match
[field,formats...],匹配日期型字段的格式,并统一处理成ISO8086时间戳。locale
用于指定本地语言,比如设置为es,es-US等,主要用于解析非数字的月和天,比如Monday,Jan等。如果时间日期都是数字的话,不用关心这个值。target
默认@timestamp
,用于指定转化后的日期保存的字段名。timezone
指定用于日期解析的时区规范。如果无法从值中提取时区,则使用此处定义的时区。如果未指定,则使用此机器上的时区
match format语法的更多详细介绍:
y year
yyyy // 全年号码,例如:2018
yy // 两位数年份,例如:2018年的18
M month
M // 最小数字月份,如1-12
MM // 两位数月份,如01-12
MMM // 缩短的月份文本,如Jan,Feb,Dec...
MMMM // 全月文本,如January..
d day
d //最少数字的一天,如1-31
dd //两位数日子,如01-31
H hour
H //最小数字小时,如0表示午夜
HH //两位数小时,如果需要填零,如午夜00
m minutes
m //最小数字分钟,如0
mm //两位数字分钟,如00
s seconds
s //最小数字秒,如0
ss //最小数字秒,如00
S 秒的小数部分,最大精度是毫秒(SSS)。除此之外,零附加
S //十分之一秒
SS //百分之一秒
SSS //千分之一秒
Z 时区偏移或身份。不能被分析
Z //时区偏移,如+0800
ZZ //时区偏移,如+08:00
ZZZ //时区身份,如America/Los_Angeles
W 一年中的一周
W //最小数字周,如1
WW //两位数字周,如01
E 一周中的天
E,EE,EEE //星期几缩写,如Mon,Tue,Wed...
EEEE //星期几全拼,如Monday,Tuesday...
例: 如果想要解析ISO8601的时间"2018-01-01T01:12:23",可以写成"yyyy-MM-dd'T'HH:mm:ss"
示例:
匹配nginx日志中的时间。
[root@node2006 logstash]# cat text.conf
input {stdin {}
}filter {dissect {mapping => {"message" => "[%{time}]|%{remote_addr}|%{verb} %{request} HTTP/%{httpversion}|%{status}|%{body_bytes_sent}"}remove_field => [ "request_all" ]remove_field => [ "message" ]}
# date {
# match => [ "time", "dd/MMM/yyyy:HH:mm:ss Z" ]
# locale => "en"
# target => "@timestamp"
# }}
output {stdout{codec => rubydebug}
}
未添加date
插件(注释date代码块):
[root@node2006 logstash]# bin/logstash -f text.conf
[21/Jan/2019:14:59:49 +0800]|183.212.160.154|GET /siteapp/regionInfoApp/regions HTTP/1.1|502|166 #提供的一行nginx日志数据
....
{"body_bytes_sent" => "166","time" => "21/Jan/2019:14:59:49 +0800", #这个是匹配的time字段"@timestamp" => 2019-01-23T06:57:40.923Z, #这个是logstash处理这条日志的时间,我们肯定需要logstash处理的时间"host" => "node2006","remote_addr" => "183.212.160.154","@version" => "1","status" => "502","httpversion" => "1.1","verb" => "GET","request" => "/siteapp/regionInfoApp/regions"
}
增加date
插件(打开date代码块注释):
[root@node2006 logstash]# bin/logstash -f text.conf
[21/Jan/2019:14:59:49 +0800]|183.212.160.154|GET /siteapp/regionInfoApp/regions HTTP/1.1|502|166
...
{"remote_addr" => "183.212.160.154", "status" => "502","body_bytes_sent" => "166","httpversion" => "1.1","@timestamp" => 2019-01-21T06:59:49.000Z, #timestamp的时间和time的年月日已经相同了,只是小时比time少了8小时,因为logstash将timestamp改成了UTC时间,原time时间是UTC+8,但不用担心,在kibana上,会将此时间根据你系统时进行自动调整显示。"time" => "21/Jan/2019:14:59:49 +0800", #"host" => "node2006","verb" => "GET","request" => "/siteapp/regionInfoApp/regions","@version" => "1"
}
QA:
问:为什么一定要在logstash中将日志中获取到的时间转换成UTC时间,然后在kibana在根据实际时间在转换回来。直接使用日志的时间不可以吗?非要转换UTC时间然后再转换成展示时间。
答(个人见解):估计是为了当日志系统跨越多个时区时,方便统一查询才把时间进行统一转换。这样在UTC +0700时区发生的事故,但是人在UTC +0800时区的时间看的肯定以当地时间来看待事故发生的时间并查询日志。这样就不用考虑跨时区日志时间的问题了。