使用Ruby-plugin在logstash中将刻度转换为@时间戳

mhd8tkvw  于 2022-12-09  发布在  Logstash
关注(0)|答案(3)|浏览(174)

我用jdbc-plugin每分钟查询一次MSSQL数据库。在这个数据库中,我的时间戳是以ticks存储的。字段名是lastupdate。现在我想把lastupdate字段转换成时间戳格式,然后用转换后的lastvalue字段覆盖@timestamp字段。我尝试了ruby filter-plugin,方法来自另一篇关于ticks到datetime转换的文章(Parse ticks to datetime),但无法实现转换,并得到_rubyexception和_dateparsefailure。
我的筛选器如下所示:

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

上次更新的示例:636062509024728064
http://tickstodatetime.com/转换后的日期:2016年8月8日上午11时01分:42.472秒
刻度中的附加信息:https://msdn.microsoft.com/en-us/library/system.datetime.ticks%28v=vs.110%29.aspx

fcwjkofz

fcwjkofz1#

此处使用的刻度值为specified,如下所示:
此属性的值表示自0001年1月1日午夜12:00:00(公历中0001年1月1日的0:00:00 UTC)以来所经过的100纳秒间隔数,它表示DateTime.MinValue。它不包括可归因于闰秒的刻度数。
在Ruby中,内部时间表示遵循Unix约定,即从1970年1月1日00:00:00 UTC开始计算秒数。因此,要转换该值,必须执行一些额外的步骤。在扩展的Ruby中,如下所示:

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使用的格式,并将其存储在@timestamp字段中。

qhhrdooz

qhhrdooz2#

有了霍尔格的回答,我修正了我的问题。(谢谢!)
他对转换的看法是完全正确的,滴答是一个奇怪的时间单位:P我不会在这里重复他完美的解释。
这将解析String(!!!)tick值,并创建一个Logstash时间对象以写入@timestamp字段:

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

有趣的问题:)仍然认为霍尔格值得打勾;)
注意:你不需要“require time”部分。当lambda在logstash中执行时,它已经被导入了。
注2:logstash 5.0中断了该事件(我相信它会变成一个java bean),因此您需要通过set方法来访问它,而不是将其作为数组来访问。
此致!
阿图尔
P.s.示例:

artur@pandaadb:~/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"
}

P.s.2:我认为“cannotdupFixnum”是我在尝试调用整数值解析时发出的(虽然不确定)

nfzehxib

nfzehxib3#

这将解析String和tick值,并创建一个Logstash时间对象以写入@timestamp字段。
注意:event.set和event.get用于检索和分配logstash中的数据

if [logmessage.logtime]
{
    ruby 
    {
        code => "event.set('@timestamp', LogStash::Timestamp.at((event.get('logmessage.logtime').to_i - 621355968000000000) / 10_000_000.0))"
    }
}

相关问题