2015-04-14 171 views
0

我在嘗試更改logstash conf文件中elasticsearch索引的命名約定時出現問題。我需要使用將通過logstash管道傳遞的文件名部分,該部分正好是設置文件所包含數據的日期的部分。 因此,而不是使用標準的命名約定,也就是說,只要我可以閱讀:logstash - %{+ YYYY.MM.DD}, 我需要這個: - 。logstash elasticsearch輸出

我想獲得當前通過管道傳遞的文件的實際名稱,但我不知道如何獲取它。 然後我決定使用過濾器部分正在處理的當前行的年份和月份。這是我用的是神交模式:

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

如可以看出,「年」和「月」這兩個應用神交模式後,我可以恢復領域。所以我想我能做到這一點:

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

,但也不是「一年」,也不是「月」,可以在本節中:有一個在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過濾器,他實際上使更改在過濾器外部可見。

就是這樣。我希望這對任何需要它的人都有用。

回答

1

Logstash從@timestamp字段(默認爲「now」)開始建立索引名稱。你需要做的是從文件中解析出時間並用它來設置你的時間戳。

爲您例如,你有%{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" 
} 
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過濾器,他實際上使更改在過濾器外部可見。

就是這樣。我希望這對任何需要它的人都有用。 感謝您的關注。 豪爾赫。