Хорошо, так что я наконец нашел решение.Сначала немного изменим шаблон grok следующим образом:
%{TIMESTAMP_ISO8601:timestamp} avg:%{NUMBER:avg:float}(?<avgUnit>[unm]?s)
Это дает нам два элемента в событиях ' avg ' и ' avgUnit ', таких какзначения могут быть переданы в сценарий ruby, который выполняется плагином: сценарий читается как потоки:
# filter runs for every event
# # return the list of events to be passed forward
# # returning empty list is equivalent to event.cancel
def filter(event)
#convert operates on event
convert(event ,"maxUnit", "max")
convert(event, "minUnit", "min")
convert(event, "avgUnit", "avg")
convert(event, "99thUnit", "99th")
return [event]
end
def convert(event, unitField, valueField)
if event.get(valueField).nil?
event.tag("__#{valueField}__not_found")
return [event]
end
if event.get(unitField).nil?
event.tag("__#{unitField}_not_found")
return [event]
end
unit = event.get(unitField)
value = event.get(valueField)
fieldName = "#{valueField}InMs"
case unit
when "ns"
event.set(fieldName, value / 1.0e6)
when "us"
event.set(fieldName, value / 1.0e3)
when "ms"
event.set(fieldName, value)
when "s"
event.set(fieldName, value * 1.0e3)
else
event.tag("__not_supported_unit_#{unit}")
end
return [event]
end
Конвейер должен иметь конфигурацию для включения сценария после сопоставления:
grok {
match => {
"message" => ["%{TIMESTAMP_ISO8601:tstamp} avg:%{NUMBER:avg:float}(?<avgUnit>[unm]?s)]
}
}
ruby {
path => "script.rb"
}