广杰博客

  • 首页
  • IT资讯
  • IT运维
  1. 首页
  2. IT运维
  3. 正文

ELK中修改Logstash的@timestamp字段为日志生成时间

05/31/2019 4131点热度 10人点赞 0条评论

Logstash在处理数据的时候,会自动生成一个字段@timestamp,默认该字段存储的是Logstash收到消息/事件(event)的时间。很多时候我们用ELK是处理日志的,日志里面一般都是有时间的。而且很多时候我们只关注日志里面的时间,而不关注Logstash收到这条日志的时间。这个时候,一种方法是再增加一个字段,用来存储日志里面的时间,这种很简单;另一种方法是使用日志中的时间替换掉@timestamp字段默认的时间。本文介绍第二种方法并总结一些关键知识点。

现在有如下一条日志:

2018-02-26 15:48:32.708-[INFO ] main RestfulApiProvider - initializing restful api provider

我们先用最简单的Logstash规则解析,规则文件test.conf如下:

# 从标准输入读入数据

input { stdin {} }

# 只解析时间戳,其它信息不管

filter {
grok {
match => { "message" => "(?<timestamp>%{TIMESTAMP_ISO8601})" }
}
}

# 输出到标准输出

output {
stdout { codec => rubydebug }
}

启动Logstash:bin/logstash -f test.conf

在标准输入粘贴上面的日志并回车,输出如下:

{
"host" => "NiYanchuns-MacBook-Air.local",
"@timestamp" => 2018-10-18T12:20:51.603Z,
"timestamp" => "2018-02-26 15:48:32.708",
"message" => "2018-02-26 15:48:32.708-[INFO ] main RestfulApiProvider - initializing restful api provider",
"@version" => "1"
}

这里需要注意以下几个点:

解析规则里面的grok是Logstash的一个正则解析插件,Logstash强大的解析能力主要来自于它,使用文档看这里。
@timestamp字段是内置的,和之前说的一样,时间是Logstash收到消息的时间,而且注意使用的是UTC时间,我电脑的时间是北京时间晚上八点多。
timestamp字段是我们解析规则里面定义的字段(字段名随便起,不能有特殊符号,比如@),该字段存储的是从日志里面解析出来的时间,注意这个时间格式完全是日志里面时间的格式。要注意我们加的timestamp和系统内置的@timestamp不是同一个字段。
message:也是程序内置字段,内容为消息原始内容。
既然如此,那我们能不能通过自定义一个与程序内置的@timestamp同名的字段来覆盖掉程序内置字段呢?比如将上面解析规则里面的timestamp改为@timestamp。

答案是不行。刚才已经说了,系统内置字段名前可以加@,但我们定义字段的时候字段名不能加@,也就是说我们不能通过定义一个@timestamp字段覆盖掉系统默认的,那样配置语法检查就通不过。有(bu)兴(xin)趣(xie)的可以试一下。

那如何做呢?Logstash提供了一个Date插件可以实现该功能,使用文档见这里。我们修改一下刚才的规则:

input { stdin {} }

filter {
grok {
match => { "message" => "(?<timestamp>%{TIMESTAMP_ISO8601})" }
}
date {
match => [ "timestamp", "ISO8601" ]
}
}

output {
stdout { codec => rubydebug }
}

重启Logstash后,输入日志后,解析输出如下:

{
"@version" => "1",
"host" => "NiYanchuns-MacBook-Air.local",
"timestamp" => "2018-02-26 15:48:32.708",
"@timestamp" => 2018-02-26T07:48:32.708Z,
"message" => "2018-02-26 15:48:32.708-[INFO ] main RestfulApiProvider - initializing restful api provider"
}

OK,@timestamp字段里面的值已经和timestamp字段很像了,但不完全一样。Logstash将timestamp的时间根据系统的时区转换为UTC时间存到了@timestamp字段里面。

这个时候timestamp就成多余的了,我们可以通过mutate插件移除该字段。再次修改解析规则文件:

input { stdin {} }

filter {
grok {
match => { "message" => "(?<timestamp>%{TIMESTAMP_ISO8601})" }
}
date {
match => [ "timestamp", "ISO8601" ]
}
mutate {
remove_field => [ "ts_tmp","date", "time", "end_time_tmp", "end_time_tmp1" ]
}
}

output {
stdout { codec => rubydebug }
}

重启Logstash后,输入日志后,解析输出如下:

{
"message" => "2018-02-26 15:48:32.708-[INFO ] main RestfulApiProvider - initializing restful api provider",
"@version" => "1",
"@timestamp" => 2018-02-26T07:48:32.708Z,
"host" => "NiYanchuns-MacBook-Air.local"
}

timestamp字段已经在输出中去掉了。

我们简单介绍一下Date插件。Date常见的配置如下:

date {
match => [ "time_field", "yyyyMMdd HH:mm:ss.SSS" ]
# timezone => "UTC"
target => "end_time"
}

上述配置的含义是,将time_field字段按照yyyyMMdd HH:mm:ss.SSS格式解析后存到target指定的字段end_time字段去。time_field必须是已经定义的字段,最常见的就是在grok里面解析出来的某个时间字段。时间格式可查看Date插件的文档。如果没有指定target,默认就是@timestamp字段,这就是为什么我们可以使用该插件来修改@timestamp字段值的原因。

另外,timezone字段在某些场景下也非常重要,如果从时间的值里面解析不出来时区,而且我们也没有指定时区的话,程序就会认为我们的时间字段的时区就是系统所处时区。比如上面从timestamp转到@timestamp的时候,时间值里面没有时区,所以使用了系统的时区东八区。当然,我们可以使用该字段指定时区。

转自:https://niyanchun.com/modify-attimestamp-field-in-logstash.html

标签: elk logstash
最后更新:05/31/2019

guangjie

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >
最新 热点 随机
最新 热点 随机
Red Hat Enterprise Linux 9 发布,大量组件升级 windows10 家庭版添加hyper-v虚拟机组件 Red Hat Enterprise Linux 8.5 GA 发布 Rocky Linux 8.4 GA正式版发布下载 Rocky Linux 8.3 首个候选版本发布 CentOS 8.3 (2011) ISO镜像下载发布 CentOS Linux 落幕 CentOS Stream 上位 CentOS Linux 7.9 (2009) iso镜像下载 Windows 10 2020年10月更新ISO下载 ubuntu ssh通过密钥登陆服务器
Google Drive推出5G免费空间 2007年世界顶级杀毒软件排名顺序依旧 Windows7简体中文版主页 卸载危险组件 Hyper-V安装CENTOS后 /dev/cdrom消失光驱无法使用 关于授予域用户安装软件的权限问题 centos的启动方式和语言设置 mysql5.7.14 主从复制 flv网页播放器代码 目录8.3命名约定
标签聚合
Windows Server 2012 nginx redhat android php_curl Hyper-V linux springboot
友情链接
  • linux运维
  • 郑州SEO

COPYRIGHT © 2021 gjie.cn. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备07002435号-8