【问题标题】:How can I reference a field from one event to another event in logstash?如何在 logstash 中将字段从一个事件引用到另一个事件?
【发布时间】:2014-06-25 20:18:41
【问题描述】:

我目前正在处理一些内容如下所示的日志:

00:19:59.771 (07120/evtThread     ) TRC> Cem< [Core1] CALL_STATE... 
00:20:00.199 (05768/BCMApplicationThread) INF> 
#S#|Call stats, ongoing calls: 8, handled_calls: 7304
#S#+----------------------------+----------+----------+----------+----------+----------+
#S#|Peer                        |      From|        To|   MinTime|   MaxTime|   AvgTime|
#S#+----------------------------+----------+----------+----------+----------+----------+
#S#|        CallDispatcher:Core2|         0|         0|         0|         0|         0|
#S#|        CallDispatcher:Core3|         0|         0|         0|         0|         0|
#S#|                   Cem:Core1|      1632|      6207|         0|   5996522|    311685|

我这样解析包含时间的行:

grok {
    match => [ "message", "%{TIME:time} (?<bcm_comp>\(\d{5}\/\w{4,}\:*\ *\w*\)) (?<loglevel>\w{3}>{1}) %{GREEDYDATA:message}" ]
    overwrite => [ "message" ]
    add_field => [ "BCM_System", "PROD" ]
}

前面包含#S# 的行是这样解析的。忽略包含 -------- 的行以及包含表标题和呼叫统计行的行。

grok {
    match => [ "message", "(?<start>\#\S\#\|)\s* (?<peer>\w*\:\w*)(?<div2>\|)\s* %{NUMBER:From}(?<div3>\|)\s* %{NUMBER:To}(?<div4>\|)\s* %{NUMBER:MinTime}(?<div5>\|)\s* %{NUMBER:MaxTime}(?<div6>\|)\s* %{NUMBER:AvgTime}(?<div7>\|)" ]        
    remove_field => [ "start", "div2", "div3", "div4", "div5", "div6", "div7" ]
    overwrite => [ "message"]       
    add_field => [ "reference_time", "%{@time}"]
}

我要做的是从上一行中抽出时间,并将其添加为我摸索#s# 行的字段。如图所示,我尝试使用 logstash 中的 add_field 语法,但它不起作用……它只是从字面上打印出 %{@time}。

有什么方法可以让我从上一行中提取时间并将其放入另一个事件的字段中?

【问题讨论】:

    标签: regex logging logstash


    【解决方案1】:

    据我所知,您必须编写一个过滤器插件才能执行此类操作。这是我拼凑起来的一个简单插件来做类似的事情——当它看到一个字段时它会记住它,然后如果它不存在则使用它看到的最后一个值。

    # encoding: utf-8
    require "logstash/filters/base"
    require "logstash/namespace"
    require "set"
    #
    # This filter will look for a field from an event and record the last value
    # of it.  If it's not present, it will add the last value to the event
    #
    # The config looks like this:
    #
    #     filter {
    #       memorize {
    #         field => "time"
    #         default => "00:00:00.000"
    #       }
    #     }
    #
    # The `field` is the name of the field that you want to memorize
    # The `default` is the value to use for the field if you haven't seen it yet
    #   in the file (this is optional)
    
    class LogStash::Filters::Memorize < LogStash::Filters::Base
    
      config_name "memorize"
      milestone 1
    
      # The field to memorize
      config :field, :validate => :string, :required => true
      # the default value to use for the field if it's not seen before we need it
      config :default, :validate => :string, :required => false
    
      # The stream identity is how the multiline filter determines which stream an
      # event belongs to. See the multiline plugin if you want more details on how
      # this might work
      config :stream_identity , :validate => :string, :default => "%{host}.%{path}.%{type}"
    
      public
      def initialize(config = {})
        super
    
        @threadsafe = false
    
        # This filter needs to keep state.
        @memorized = Hash.new
      end # def initialize
    
      public
      def register
        # nothing needed
      end # def register
    
      public
      def filter(event)
        return unless filter?(event)
    
        if event[@field].nil?
          val = @memorized[@stream_identity]
          if val.nil?
            val = @default
          end
          event[@field] = val
          filter_matched(event)
        else
          @memorized[@stream_identity] = event[@field]
        end
      end
    end
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多