logstash elasticsearch输出

时间:2015-04-14 16:27:32

标签: ruby elasticsearch logstash

当我尝试在logstash conf文件中更改elasticsearch索引的命名约定时,我遇到了问题。我需要使用将通过logstash管道传递的文件名部分,这正是设置文件所包含数据日期的部分。 因此,我可以阅读标准命名约定,而不是使用标准命名约定:logstash - %{+ YYYY.MM.DD}, 我需要这个: -

我试图获取当前通过管道传递的文件的实际名称,但我不知道如何获取它。 然后我决定使用过滤器部分中正在处理的当前行的年份和月份。这是我使用的grok模式:

  grok {
    match => [ "message", "%{IP:client} %{NOTSPACE:sep} %{NOTSPACE:ident} %{NOTSPACE:inbracket}%{MONTHDAY:day}/%{MONTH:month}/%{YEAR:year}:%{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second} %{ISO8601_TIMEZONE:tz}%{NOTSPACE:outbracket} \"%{WORD:method} %{NOTSPACE:uri} %{NOTSPACE:http_version}\" %{NUMBER:code} %{NUMBER:size} %{NOTSPACE:action_hierarchy} %{NOTSPACE:content_type}" ]
    remove_field => ["sep"]
    remove_field => ["inbracket"]
    remove_field => ["outbracket"]
  }

可以看出,“年”和“月”是我应用grok模式后可以恢复的两个字段。所以我以为我能做到这一点:

elasticsearch {
    action => "index"
    index => "myindexname-%{year}.%{month}"
    index_type => "logs"
    node_name => "Node001"
}

但本节中也不能使用“year”或“month”:conf文件中没有编译问题,只是这不是获取这些值的方法。也许使用红宝石可能是一种方式,但我的尝试都是错误的。我怎样才能做到这一点?


因此,对于每个可能遇到同样问题的人来说,这是一个适合我的解决方案。

我的插件的代码是:

# Call this file 'ordinalmonth.rb' (in logstash/filters, as above)
require "logstash/filters/base"
require "logstash/namespace"

class LogStash::Filters::OrdinalMonth < LogStash::Filters::Base

# Setting the config_name here is required. This is how you
# configure this filter from your logstash config.
#
# filter {
#   ordinalmonth { ... }
# }
  config_name "ordinalmonth"

# New plugins should start life at milestone 1.
milestone 2

# Replace the message with this value.
config :month_field, :validate => :string, :default => "month"

public
def register
  # nothing to do
end # def register

public
def filter(event)
  # return nothing unless there's an actual filter event
  return unless filter?(event)
  if event[@month_field]
    # Replace the event message with our message as configured in the
    # config file.
    tmp = case event[@month_field]
      when "Jan" then "01"
      when "Feb" then "02"
      when "Mar" then "03"
      when "Apr" then "04"
      when "May" then "05"
      when 'Jun' then '06'
      when "Jul" then "07"
      when "Aug" then "08"
      when "Sep" then "09"
      when "Oct" then "10"
      when "Nov" then "11"
      when "Dec" then "12"
      else "Unknown"
      end
    event["month"] = tmp
  end
  # filter_matched should go in the last line of our successful code 
  filter_matched(event)
end # def filter
end # class LogStash::Filters::OrdinalMonth

基本上,插件会收到包含3个字母的月份名称的字段名称,以大写字母开头。然后输入case语句,这样就可以实现更新。然后,它会改变字段中包含的旧值。

因此,为了以预期的方式工作,我必须更改我的logstash作业的配置文件中的代码:

filter {
  if [type] == "nauta_navroom" {
      grok {
        match => [ "message", "%{IP:client} %{NOTSPACE:sep} %{NOTSPACE:ident} %{NOTSPACE:inbracket}%{NOTSPACE:day}/%{MONTH:month}/%{YEAR:year}:%{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second} %{ISO8601_TIMEZONE:tz}%{NOTSPACE:outbracket} \"%{WORD:method} %{NOTSPACE:uri} %{NOTSPACE:http_version}\" %{NUMBER:code} %{NUMBER:size} %{NOTSPACE:action_hierarchy} %{NOTSPACE:content_type}" ]
        remove_field => ["sep"]
        remove_field => ["inbracket"]
        remove_field => ["outbracket"]
      }
      ordinalmonth {}
      kv {
        source => "@message"
      }
  }
}

检查ordinalmonth插件的调用,不带任何参数。另一个神奇的事情是使用kv过滤器,它实际上使过滤器外部的变化可见。

就是这样。我希望这对任何需要它的人都有用。

2 个答案:

答案 0 :(得分:1)

Logstash根据@timestamp字段中的时间构建索引名称(默认为&#34;现在&#34;)。您要做的是从文件中解析时间并使用它来设置时间戳。

例如,您的文件中有%{MONTHDAY:day}/%{MONTH:month}/%{YEAR:year}:%{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second} %{ISO8601_TIMEZONE:tz}模式,因此您可以在配置文件中执行以下操作:

mutate {
  add_field => [ "timestamp", "%{year}-%{month}-%{day}T%{hour}:%{minute}:%{second}%{tz}" ]
}
date {
  match => [ "timestamp", "ISO8601" ]
  remove_field => ["timestamp" ]
}

根据您解析的内容为您的事件添加时间戳字段,然后根据它设置@timstamp并删除已添加的字段。

然后您只需将elasticsearch输出更改为

即可
elasticsearch {
    action => "index"
    index => "myindexname-%{+YYYY-MM}"
    index_type => "logs"
    node_name => "Node001"
}

答案 1 :(得分:0)

因此,对于每个可能遇到同样问题的人来说,这是一个适合我的解决方案。

我的插件的代码是:

# Call this file 'ordinalmonth.rb' (in logstash/filters, as above)
require "logstash/filters/base"
require "logstash/namespace"

class LogStash::Filters::OrdinalMonth < LogStash::Filters::Base

# Setting the config_name here is required. This is how you
# configure this filter from your logstash config.
#
# filter {
#   ordinalmonth { ... }
# }
  config_name "ordinalmonth"

# New plugins should start life at milestone 1.
milestone 2

# Replace the message with this value.
config :month_field, :validate => :string, :default => "month"

public
def register
  # nothing to do
end # def register

public
def filter(event)
  # return nothing unless there's an actual filter event
  return unless filter?(event)
  if event[@month_field]
    # Replace the event message with our message as configured in the
    # config file.
    tmp = case event[@month_field]
      when "Jan" then "01"
      when "Feb" then "02"
      when "Mar" then "03"
      when "Apr" then "04"
      when "May" then "05"
      when 'Jun' then '06'
      when "Jul" then "07"
      when "Aug" then "08"
      when "Sep" then "09"
      when "Oct" then "10"
      when "Nov" then "11"
      when "Dec" then "12"
      else "Unknown"
      end
    event["month"] = tmp
  end
  # filter_matched should go in the last line of our successful code 
  filter_matched(event)
end # def filter
end # class LogStash::Filters::OrdinalMonth

基本上,插件会收到包含3个字母的月份名称的字段名称,以大写字母开头。然后输入case语句,这样就可以实现更新。然后,它会改变字段中包含的旧值。

因此,为了以预期的方式工作,我必须更改我的logstash作业的配置文件中的代码:

filter {
  if [type] == "nauta_navroom" {
      grok {
        match => [ "message", "%{IP:client} %{NOTSPACE:sep} %{NOTSPACE:ident} %{NOTSPACE:inbracket}%{NOTSPACE:day}/%{MONTH:month}/%{YEAR:year}:%{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second} %{ISO8601_TIMEZONE:tz}%{NOTSPACE:outbracket} \"%{WORD:method} %{NOTSPACE:uri} %{NOTSPACE:http_version}\" %{NUMBER:code} %{NUMBER:size} %{NOTSPACE:action_hierarchy} %{NOTSPACE:content_type}" ]
        remove_field => ["sep"]
        remove_field => ["inbracket"]
        remove_field => ["outbracket"]
      }
      ordinalmonth {}
      kv {
        source => "@message"
      }
  }
}

检查ordinalmonth插件的调用,不带任何参数。另一个神奇的事情是使用kv过滤器,它实际上使过滤器外部的变化可见。

就是这样。我希望这对任何需要它的人都有用。 感谢您的关注。 乔治。