原文:https://blog.csdn.net/wuyinggui10000/article/details/77879016
一、原文
公司线上日志是通过logstash接收并上传的,使用版本是logstash2.3,发现@timestamp经常少8个小时;
处理逻辑如下,无需修改插件源码
input { stdin {} }
output { stdout { codec => rubydebug } }
filter {
date {
match => ["message","UNIX_MS"] #message在实际应用中修改为自己的字段
target => "@timestamp"
}
ruby {
code => "event['timestamp'] = LogStash::Timestamp.new(event['@timestamp']+ 8*60*60)"
}
ruby {
code => "event['@timestamp']= event['timestamp']"
}
mutate {
remove_field => ["timestamp"]
}
}
另外在5.x版本logstash配置有不同
input { stdin {} }
output { stdout { codec => rubydebug } }
filter {
date {
match => ["message","UNIX_MS"]
target => "@timestamp"
}
ruby {
code => "event.set('timestamp', event.get('@timestamp').time.localtime + 8*60*60)"
}
ruby {
code => "event.set('@timestamp',event.get('timestamp'))"
}
mutate {
remove_field => ["timestamp"]
}
}
测试方法
echo '1504744911000' | ./logstash -f ~/test.conf
二、补充
1. filter 中 date 的作用:
获取测试数据中表示日期的数据(其格式使用的是 UNIX_MS 时间),并将其赋值给 @timestamp。
UNIX_MS:记录的是从1970年起始至今的总毫秒数。JavaScript经常使用这个时间格式。
UNIX:记录的是从1970年起始至今的总秒数。Squid的默认日志时间格式。
ISO8601:
2. 两个 ruby
第一个:获取 @timestamp的值并加上 8*60*60(北京时间比 logstash 中@timestamp 晚了 8 小时),然后赋值给变量 timestamp。
第二个 ruby:将 timestamp 值重新赋值给 @timestamp
3. mutate
删除变量 timestamp。
如果只是需要修改@timestamp时间,不需要从日志获取时间,则 date{} 这部分可以取消。
三、时区问题的解释
很多中国用户经常提一个问题:为什么 @timestamp 比我们晚了 8 个小时?怎么修改成北京时间?
其实,Elasticsearch 内部,对时间类型字段,是统一采用 UTC 时间,存成 long 长整型数据的!对日志统一采用 UTC 时间存储,是国际安全/运维界的一个通识——欧美公司的服务器普遍广泛分布在多个时区里——不像中国,地域横跨五个时区却只用北京时间。
对于页面查看,ELK 的解决方案是在 Kibana 上,读取浏览器的当前时区,然后在页面上转换时间内容的显示。所以,建议大家接受这种设定。否则,即便你修改了 @timestamp,也要面临在 Kibana 上反过去修改,以及 Elasticsearch 原有的 ["now -ih", "now"] 这种方便的搜索语句无法正常使用的尴尬。