【发布时间】:2015-06-26 14:56:20
【问题描述】:
我在尝试更改 logstash conf 文件中弹性搜索索引的命名约定时遇到问题。我需要使用将通过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"
}
但是本节不能使用“年”或“月”:conf文件中没有编译问题,只是这不是获取这些值的方法。也许使用 ruby 可能是一种方法,但我的尝试都错了。我怎样才能做到这一点?
因此,对于可能遇到相同问题的每个人来说,这是一个适合我的解决方案。
我的插件代码是:
# 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 过滤器,它实际上使更改在过滤器之外可见。
就是这样。我希望这对任何需要它的人有用。
【问题讨论】:
标签: ruby elasticsearch logstash