Шаблон Grok для настраиваемого времени отклика в нс, сша, мс или с - logstash - PullRequest
0 голосов
/ 03 декабря 2018

Мне нужно проанализировать время отклика из пользовательского формата журнала, чтобы оно могло перейти через конвейер Logstash к эластичному.

Пример записи в журнале:

2018-11-19 23:40:00-0500 avg:30.5ms max:135ms min:6.61ms reqs:20 rsps:20 errs:0 maxcon:3 99th:135ms 95th:134ms 90th:111ms 75th:22.6ms 50th:15.6ms heap:36.7% load:1.43/0.75/0.60 cpu:26.3%

Среднее, максимальное, минимальноеможет быть в формате ns, us, ms или s.Я начал с:

%{TIMESTAMP_ISO8601:timestamp} avg:%{NUMBER:avg}ms

Конечно, он не будет работать для ns и т. Д., Поэтому мне нужно что-то вроде:

%{TIMESTAMP_ISO8601:timestamp} avg:%{NUMBER:avg}(ns|us|ms|s)

Однако я потеряю информацию, так как я долженшкала значений, чтобы сказать мс.Таким образом, ns умножают на 1e6, мс -> 1e3, мс -> 1, s -> 1e-3.

Каков наилучший подход для решения этой проблемы?

1 Ответ

0 голосов
/ 04 декабря 2018

Хорошо, так что я наконец нашел решение.Сначала немного изменим шаблон 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"
}
...