logstash @timestamp 日期及时区问题通用的解决方案

logstash @timestamp 日期及时区问题通用的解决方案

elk生态不少组件都会碰到时区问题,logstash也不例外

改系统时区都解决不了

官方的[Date filter plugin | Logstash Reference 7.16] | Elastic

虽然在时间转换时有zone设置时区设置的部分,但个人测试使用并不生效

使用插件没办法,那就用ruby插件改

例如时间字段为pdate,同时以这个字段做为@timestamp

在数值转换时自已pdate以用+8*60*60更改时区没有问题,使用时以pdate查询

但是有个问题是@timestamp和pdate不一致

而logstash相关生态,例如写es,通过时间按 月/天/小时,划分索引时是以@timestamp计算的,会出现8小时的偏差

其实如果是大范围的日志类查询(实际查询条件使用的是pdate),@timestamp 导致index 数据滚动后延的偏差可以忽略

但毕竟不完美,线上当然要尽可能保持没有偏差

以 event.set('@timestamp',pdate) 启动logstash却报异常

Ruby exception occurred: wrong argument type Timestamp (expected LogStash::Timestamp)

大意是pdate和期望的Timestamp类型不匹配,这种错在java里也挺常见了

以为是哪里小细节搞错了,多试几次,还是解决不了

那就是说,pdate和@timestamp的类型确实不一致

要把pdate转为LogStash::Timestamp

查logstash代码,找找LogStash::Timestamp这个类相关信息

logstash/event_spec.rb at 7.10 · elastic/logstash (github.com)

logstash/JrubyTimestampExtLibrary.java at 7.10 · elastic/logstash (github.com)

    it "should set timestamp" do
      e = LogStash::Event.new
      now = Time.now
      e.set("@timestamp", LogStash::Timestamp.at(now.to_i))
      expect(e.timestamp.to_i).to eq(now.to_i)
      expect(e.get("@timestamp").to_i).to eq(now.to_i)
    end

果然是类型不对,标准的Time和LogStash::Timestamp 需要一道转换

因此变更为如下结果,这样可能省掉pdate这一列

pdate 使用date filter string转为LogStash::Timestamp,由于timezone 不生效,通过ruby计算重新set

这种方法不是最优的,但应该是最通用的

      date {
          match => [ "pdate", "ISO8601" ]
          timezone => "Asia/Shanghai"
          target => "@timestamp"
      }
      ruby {
          code => "
              event.set('@timestamp', LogStash::Timestamp.at(event.get('@timestamp').time.localtime + 8*60*60))
          "
      }
posted @ 2022-01-09 16:45  cclient  阅读(3682)  评论(0编辑  收藏  举报