2016-08-19 112 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