希望通过这篇文章能解释清楚elk中的时区问题

由于kibana包括es默认是使用UTC时间,对于我们这种常年驻扎在东八的社畜来说十分不友好。比如我们日志是按照东八时间记录的,但到了elk中间你会发现@timestamp会莫名奇妙的少了8个小时。这是因为底层用的就是UTC。

于是找到一种方案是在Logstash中对齐@timestamp和日志时间:

  ruby { 
    code => "event['timestamp'] = LogStash::Timestamp.new(event['@timestamp']+ 8*60*60)" 
  }
  
  ruby {
    code => "event['@timestamp']= event['timestamp']"
  }

这样做后的结果呢?

由于默认设置kibana用浏览器时间,所以档这个对齐后,上午11点却只能现实凌晨3点的日志。。。感觉越搞越糟糕了。

仔细想下,我们其实强行同步这两个时间是有点多余的。因为kibana默认是按照@timestamp来交割,并且用的是utc时区来展示。当我们切换设置为browser,它自动将@timestamp转换到对应时区,而不影响日志展示本身。所以一旦你强行对齐这两个时间,反而会导致部分日志无法展示出来了。如果你服务器一开始就设定UTC时间来记录日志,这种对齐是没有任何问题得。但是一旦设定了其他时区,其实最好得做法就是简单的把日志时间和时区信息设置到@timestamp,剩下的就让elk自己转换即可。

  date {
    match => ["[log_json][log_datetime]", "yyyy-MM-dd HH:mm:ss"]
    target => "@timestamp"
    timezone => "+08:00"
  }

但是要记得在查询语句里面和时间相关的条件都带上timezone就好了。其实这么看来,最优雅的做法还是一开始就把服务器时间设置成UTC,可以少走很多弯路。

这里多说一点,elk用这个@timestamp除了展示用还有什么作用呢?索引分割用。由于我们日志是按天分割,日志文件是按小时记录。由于存在8小时时差,所以索引的一天24小时是跨了日志的两天的。比如索引7号的日志,实际是从7号早上8点到8号早上7点为止。这点明白后,在调整索引时候,最好延迟两天再做,防止对正在写入的索引产生影响。别我是怎么知道的,反正都是血泪史。