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))
"
}