date时区 es logstash_elastic date时区问题解决办法

之前介绍filter date插件时就谈到时区问题,但是没有说明白。最近在使用range查询时间范围内的数据时出现了数据量不一致的情况。特地了解了下ELK Stack中关于时区的问题。

问题:

使用kibana discovery界面搜索时,数据量一致。使用curl 搜索时少了数据。

再说时间问题前,简单了解下UTC:

UTC(Universal Time Coordinated) 叫做世界统一时间,中国大陆和 UTC 的时差是 + 8 ,也就是 UTC+8。

UTC时区参考文档

查看官方文档后得到的结论:

ELK Stack集群各服务对时间处理的介绍:

logstash :根据所在机器的时区并对date类型数据进行处理,整理成UTC时间

elastic :所有date类型数据都存储为GMT(毫秒级)

kibana :根据kibana配置的时区,从elastic取出的timestamp时间转换为相应时区的时间。

问题原因:

logstash处理后以UTC时间存储进elastic,kibana取出来后,在恢复成相应时区的时间。因为我机器都是CST的时间,所以使用kibana搜索没有问题,但是curl命令不会对所取出来的时间进行时区转换,所以就少了8小时数据。

解决方法:

一:

logstash 过滤字段信息时,删除或分开匹配时间和时区信息,timestamp只匹配具体时间,timezone则匹配+0800这样的时区信息,并同时定义timezone为UTC,这样从根本上就得到原始的时间。

UTC时间的示例:

$ bin/logstash -f text.conf

[26/Mar/2019:00:00:08 +0800] #这里以nginx日志中的时间为例

{

"timestamp" => "26/Mar/2019:00:00:08",

"message" => "[26/Mar/2019:00:00:08 +0800]",

"@timestamp" => 2019-03-26T00:00:08.000Z, #@timestamp的时间和输入的时间一致

"@version" => "1",

"timezone" => "+0800",

"host" => "node2007"

}

$ cat text.conf

input {

stdin {}

}

filter {

grok {

match => {

"message" => "\[%{NOTSPACE:timestamp} %{INT:timezone}\]"

}

}

date {

match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss" ]

timezone => "UTC" #无法从timestamp中提取时区。设置时区为UTC时间,忽略系统时区,如果date插件中的match匹配到了时区,则此处的时区不生效。所以在grok插件中将timezone和timestamp分隔开

}

}

output {

stdout{

codec => rubydebug

}

}

正常时间处理:

$ bin/logstash -f text.conf

[26/Mar/2019:00:00:08 +0800]

{

"@version" => "1",

"@timestamp" => 2019-03-25T16:00:08.000Z, #转换成UTC时间,减少8小时,

"message" => "[26/Mar/2019:00:00:08 +0800]",

"host" => "node2007",

"timestamp" => "26/Mar/2019:00:00:08 +0800"

}

$ cat text.conf

input {

stdin {}

}

filter {

grok {

match => {

"message" => "\[%{HTTPDATE:timestamp}\]"

}

}

date {

match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]

timezone => "UTC"

}

}

output {

stdout{

codec => rubydebug

}

}

系统日志中不带有时区信息,则可以直接在配置文件中指定timezone => "UTC"即可。无需要做匹配工作。

二:

匹配到时区时间没有关系,可以在过滤时,在把时间补回来。

...

date {

match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]

target => "time"

}

ruby {

code => "event.set('timestamp', event.get('time').time.localtime + 8*60*60)" #处理时将logstash自动减少的时间在给加回来

}

ruby {

code => "event.set('@timestamp',event.get('timestamp'))"

}

...

以上代码经过我测试,可以正常使用。这里使用ruby插件,我不懂,time -> timestamp -> @timestamp需要经由两个变量才能最后赋值给@timestamp,为什么不能直接使用@timestamp处理并赋值,如果有懂得的人,还请留言告知。

对时间进行处理后,我们可以使用curl命令随意进行查询啦,但是使用kibana时,还需要设置一下默认的时区: Management -> kibana(高级设置) -> Timezone for date formatting 并选择UTC时间展示。

![](https://img2018.cnblogs.com/blog/1202606/201903/1202606-20190328154358262-1829927564.png)

总结:

ELK Stack一整套组合拳的时区特性特别好用,但是在国内还是统一时区吧。统一时区还是再数据存储前做调整,否则后期查询会流泪的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值