Logstash:使用静态csv文件中的数据丰富日志文件中的事件

Logstash:使用静态csv文件中的数据丰富日志文件中的事件,logstash,Logstash,总结: 在logstash中使用过滤器,从事件字段中读取值,在外部文件(如csv)中查找该值,并从匹配的外部文件中检索值。使用外部文件中的值作为额外字段添加到事件中 更多信息: 我有一个包含事件的日志文件。这些事件看起来像: {"@timestamp":"2014-06-18T11:52:45.370636+02:00","location":{"MainId":3,"SubId":"5"},"EndRequest":{"Duration":{"Main":0,"Page":6720}}} 我

总结: 在logstash中使用过滤器,从事件字段中读取值,在外部文件(如csv)中查找该值,并从匹配的外部文件中检索值。使用外部文件中的值作为额外字段添加到事件中

更多信息: 我有一个包含事件的日志文件。这些事件看起来像:

{"@timestamp":"2014-06-18T11:52:45.370636+02:00","location":{"MainId":3,"SubId":"5"},"EndRequest":{"Duration":{"Main":0,"Page":6720}}}
我有一个静态csv文件,如:

1,left
2,right
3,top
在logstash中处理事件时,我希望能够使用一个过滤器来检查MainId的值(在示例event=3中),并在csv文件中找到该值。如果找到,则事件必须有一个标记:“top”

这是一种类似于过滤“GeoIP”的方法。事件有一个字段值,匹配“数据库”中的值,并返回可添加到事件中的值


我找不到一个当前的过滤器,它可能会影响上述过程。我需要自己做一个自定义过滤器吗?如果是这样的话,有人能给我一个如何处理这个问题的提示吗?

我从未见过为它编写的插件,所以我继续写了一个非常基本的插件:

# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
require "csv"

# The cvslookup filter allows you to add fields to an event
# base on a csv file

class LogStash::Filters::CSVLookup < LogStash::Filters::Base
  config_name "csvlookup"
  milestone 1

  # Example:
  #
  #     filter {
  #       csvlookup {
  #     file => 'key_value.csv'
  #     key_col => 1
  #     value_col => 2
  #     default => 'some_value'
  #         map_field => { "from_field" => "to_field" }
  #       }
  #     }
  # 
  # the default is used if the key_col's value is not present in the CSV file

  config :file, :validate => :string, :required => true
  config :key_col, :validate => :number, :default => 1, :required => false
  config :value_col, :validate => :number, :default => 2, :required => false
  config :default, :validate => :string, :required => false
  config :map_field, :validate => :hash, :required => true

  public
  def register
    @lookup = Hash.new

    CSV.foreach(@file) do |row|
      @lookup[row[@key_col - 1]] = row[@value_col - 1]
    end
    #puts @lookup.inspect
  end # def register

  public
  def filter(event)
    return unless filter?(event)

    @map_field.each do |src_field,dest_field|
      looked_up_val = @lookup[event[src_field].to_s]
      if looked_up_val.nil?
          if !@default.nil?
            event[dest_field] = @default
          end
      else
        if event[dest_field].nil?
          event[dest_field] = looked_up_val
        elsif !event[dest_field].is_a?(Array)
          event[dest_field] = [ event[dest_field], looked_up_val ]
        else
          event[dest_field].push(looked_up_val)
        end
      end
    end 
  end # def filter
end # class LogStash::Filters::CSVLookup
编码:utf-8 需要“日志存储/过滤器/基础” 需要“日志存储/命名空间” 需要“csv” #cvslookup筛选器允许您向事件添加字段 #基于csv文件 类LogStash::Filters::CSVLookup'key_value.csv' #键列=>1 #值_col=>2 #默认值=>'some_value' #映射_字段=>{“从_字段”=>“到_字段”} # } # } # #如果CSV文件中不存在密钥的值,则使用默认值 config:file,:validate=>:string,:required=>true 配置:key\u col,:validate=>:number,:default=>1,:required=>false 配置:value\u col,:validate=>:number,:default=>2,:required=>false config:default,:validate=>:string,:required=>false 配置:map_字段,:validate=>:hash,:required=>true 公众的 def寄存器 @lookup=Hash.new CSV.foreach(@file)do|行| @查找[行[@key\u col-1]]=行[@value\u col-1] 结束 #放置@lookup.inspect 结束#def寄存器 公众的 def过滤器(事件) 除非过滤,否则返回?(事件) @map_字段。每个do|src_字段,dest_字段| looked_up_val=@lookup[event[src_field]。to_s] 如果查到值为零? 如果@默认为0.nil? 事件[dest_字段]=@默认值 结束 其他的 如果事件[dest_字段].nil? 事件[目的地字段]=查找值 埃尔西夫!事件[dest\u字段]。\u是?(数组) 事件[目的地字段]=[事件[目的地字段],查找值] 其他的 事件[dest\u field]。推送(查找值) 结束 结束 结束 结束#def过滤器 结束#类LogStash::Filters::CSVLookup
还可以对它做进一步的工作——例如,如果src_字段是一个数组,它可以对它进行迭代,但它应该按照您的情况工作。

这里有Translate过滤器

与CSV不同,您有一个YAML文件,对于单键值对,这应该是一个简单的sed YAML转换


撰写本文时的最新文档:

非常感谢。你的解决方案非常适合我!我没料到会有这么快、这么完整的安瑟尔。当然,如果你开始使用这个插件,你会有新的问题。我对Ruby完全不熟悉。但是正在寻找一种在查找不存在时提供默认值的方法。顺便说一句,我确实删除了“分隔符”,因为它给出了一个错误,可能是因为它没有被使用?我将用一个默认选项更新代码,因为这似乎很有用添加了可选的
default
config值,当值不在csv文件中时,这很好!谢谢。虽然此链接可以回答问题,但最好在此处包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能会变得无效。@UwePlonus是的,答案的核心/要点在那里,只是不在底部:(