2016-08-19 111 views
2

我使用jdbc-plugin針對MSSQL數據庫每分鐘查詢一次。 在這個數據庫中,我的時間戳存儲在滴答。字段名稱是lastupdate。 現在我想將lastupdate字段轉換爲時間戳格式,然後用轉換後的lastvalue字段覆蓋@timestamp字段。 我試圖用從另一篇文章提供的方法提供的方法從ticks到datetime(Parse ticks to datetime)轉換,但無法實現轉換並得到_rubyexception和_dateparsefailure的ruby過濾器插件。使用Ruby插件將刻度轉換爲logstash中的@timestamp

我的過濾器看起來是這樣的:

filter { 
    if [type] == "mydb" { 
    ruby { 
     init => "require 'time'" 
     code => "lastupdate = Time.at(event['lastupdate'].to_s)" 
    } 
    date { 
     match => [ "lastupdate", "MM/dd/YY HH:mm:ss,SSS" ] 
    } 
    } 
} 

舉例LASTUPDATE:轉換後636062509024728064

日期與 http://tickstodatetime.com/:2016年8月8日T11:01:42.472Z

附加Ticks中的信息:https://msdn.microsoft.com/en-us/library/system.datetime.ticks%28v=vs.110%29.aspx

+0

請用一個例子日誌信息編輯你的問題你正試圖解析 – pandaadb

+0

@pandaadb添加示例。使用上面的過濾器,lastupdate字段的值根本不會改變。提前致謝! – cvanhalt

+0

你沒有分配它。什麼樣的時間映射? :) Time.at給我:「281182817-11-03 04:01:49 +0000」 – pandaadb

回答

2

此處使用的刻度值是specified,如下所示:

此屬性的值表示從0001年1月1日午夜12:00:00開始經過的100納秒間隔的數量(0001年1月1日0:00:00 UTC ,在公曆中),代表DateTime.MinValue。它不包括可歸因於閏秒的滴答數。

在Ruby中,內部時間表示遵循Unix約定自1970年1月1日UTC 00:00:00以來的秒數。因此,要轉換該值,您必須執行一些額外的步驟。在膨脹的紅寶石,這看起來像這樣:

epoch = 621_355_968_000_000_000 # 1970-01-01T00:00:00Z in ticks 
ticks_per_second = 10_000_000.0 

lastupdate = 636062509024728064 # the value in ticks we would like to convert 
seconds_since_epoch = (lastupdate - epoch)/ticks_per_second 
Time.at(seconds_since_epoch).utc 
# => 2016-08-08 11:01:42 UTC 

爲了應用這logstash,可以冷凝有點:

filter { 
    if [type] == "mydb" { 
    ruby { 
     code => "event['@timestamp'] = LogStash::Timestamp.at((event['lastupdate'].to_i - 621355968000000000)/10_000_000.0)" 
    } 
    } 
} 

此代碼剪斷執行上述所示的計算並將結果傳遞作爲Time.at的參數。最後,它以logstash使用的格式生成時間對象formats,並將其存儲在@timestamp字段中。

+0

對於上述命令我得到了rubyexception。因此,lastupdate的值不會更改,並且@timestamp字段不會更新。感謝您的幫助:) – cvanhalt

+0

我有一個類似的解決方案,但繼續看到「不能重複fixnum」,可悲的是我的紅寶石不夠好找出原因:/ – pandaadb

+0

@cvanhalt:請檢查您的logstash日誌文件。它應該包含更多關於提出的豁免的信息。 –

1

隨着Holger的回答,我修好了我的。 (謝謝!)

他對轉換完全正確。滴答聲是一個奇怪的時間單位:P我不會在這裏重複他完美的解釋。

這將解析字符串(!)刻度值,並創建一個Logstash時間對象寫入到@timestamp領域:

ruby { 
     init => "require 'time'" 
     code => " 
     ts = (event['message'].to_i - 621355968000000000)/10000000 
     event['@timestamp'] = LogStash::Timestamp.new(Time.at(ts)) 
     " 
    } 

有趣的問題:)還認爲霍爾格值得打勾)

注意:您不需要「需要時間」部分。當lambda在logstash中執行時,它已經被導入。注意2:logstash 5.0打破了事件(我認爲它變成了一個java bean),所以不需要像數組那樣訪問它,你需要通過一個set方法來訪問它。

問候,

阿圖爾

附:例如:

[email protected]:~/dev/logstash$ ./logstash-2.3.2/bin/logstash -f conf2/ 
Settings: Default pipeline workers: 8 
Pipeline main started 
636062509024728064 
{ 
     "message" => "636062509024728064", 
     "@version" => "1", 
    "@timestamp" => "2016-08-08T11:01:42.000Z", 
      "host" => "pandaadb" 
} 

Ps2的:我認爲「不能DUP Fixnum對象」是從我試圖調用解析上的整數值(確保雖不)

+0

你說得對,logstash使用自己的Timestamp類(基於Ruby的'Time'類)而不是String。我相應地調整了我的答案,並+1了你:) –

+0

是的 - 它有點奇怪,他們這樣做:)我不認爲這是非常有記錄的,我只寫了一個插件時遇到它,並想知道爲什麼它吹up :) – pandaadb

+0

@HolgerJust和pandaadb非常感謝!它現在就像一個魅力=) – cvanhalt