Grok условный синтаксический анализ для стека ELK

#logging #logstash #kibana #logstash-grok

#ведение журнала #logstash #кибана #logstash-grok

Вопрос:

У меня есть такой журнал:

 2020-09-02 14:29:22,854 [http-something] [ERROR] JavaClass(JavaLine) - [6652942]: Error message with no stack trace
2020-09-02 14:29:08,976 [http-something] [INFO] JavaClass(JavaLine) - [6791732]: Some message
2020-09-02 14:29:09,116 [http-something] [ERROR] JavaClass(JavaLine) - [6791732]: Error message with stack trace
JavaException: This is not going well
    at JavaClass
    at JavaClass
    at JavaClass
    at JavaClass
    at JavaClass
Caused by: JavaClass: This is a problem
    at JavaClass
    at JavaClass
    at JavaClass
    at JavaClass
    ... 48 more
  

и я использую этот фильтр, чтобы иметь более читаемый журнал на Kibana:

 filter {

    # INFO and ERROR
    grok {
        tag_on_failure => ["_stackTraceFailure"]
        match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}%{SPACE}([%{DATA:thread}])?%{SPACE}[%{LOGLEVEL:log_level}]%{SPACE}%{GREEDYDATA}%{SPACE}-%{SPACE}%{GREEDYDATA:action}" }
        overwrite => [ "message" ]
    }

    # JAVA ERROR
    if ("_stackTraceFailure" in [tags]) {
        grok { 
            tag_on_failure => ["_grokParseFailure"]
            match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}%{SPACE}([%{DATA:thread}])?%{SPACE}[%{LOGLEVEL:log_level}]%{SPACE}%{GREEDYDATA}%{SPACE}-%{SPACE}%{DATA:issue}(r|n) (?m)%{GREEDYDATA:stack-trace}" }
            overwrite => [ "message" ]
            remove_tag => "_stackTraceFailure"
        }
    }
}
  

Проблема в том, что первый шаблон сопоставляет все, помещая всю трассировку стека (когда она есть) в тег действия, и в результате второй шаблон никогда не будет использоваться. Я знаю, что эта проблема вызвана GREEDYDATA, но я не очень разбираюсь в регулярных выражениях и не нахожу решения, чтобы делать то, что я хочу.

Я не хочу менять положение шаблонов, потому что ИНФОРМАЦИЯ и ОШИБКА (без трассировки стека) встречаются гораздо чаще, поэтому мне нужен способ сделать первый сбой в случае многострочного журнала или чего-либо, что приведет к сбою первого, если есть какая-то трассировка стека. Но могу ли я сделать это, исходя из того, что я сделал до сих пор?

Ответ №1:

Вам нужно использовать условные выражения перед вашими groks. Вы можете использовать условное выражение для фильтрации всего сообщения и использовать два разных grok фильтра, или вы можете оставить свой первый grok фильтр таким же и использовать условное выражение для анализа только action поля, я бы предложил второй вариант.

В обоих случаях вам нужно, чтобы ваше условие фильтровалось на основе чего-то, что существует только в вашем многострочном сообщении, в данном случае это может быть "at JavaClass" строка.

Итак, вам понадобится что-то вроде этого:

 if "at JavaClass" not in [message] {
  grok { your first grok }
} else {
    grok { your second grok }
}
  

Если вы хотите сохранить свой первый grok и использовать второй для анализа только поля действия, это будет что-то вроде этого.

 if "at JavaClass" in [action] {
    grok {
        tag_on_failure => ["_grokParseFailure"]
        match => { "action" => "%{DATA:issue}(r|n) (?m)%{GREEDYDATA:stack-trace}" }
    }
}
  

Вы не сказали, как вы собираете свои журналы, если вы используете filebeat или logstash с multiline закодированным во входных данных, вы также можете фильтровать на основе тегов, поскольку у вас будет тег с именем multiline для ваших журналов.

Комментарии:

1. Я использую filebeat для сбора журналов с многострочным шаблоном ( ^[0-9]{4}-[0-9]{2}-[0-9]{2} ). Многострочный тег действительно присутствует при наличии многострочных журналов, поэтому, я думаю, я также могу использовать его, чтобы разрешить сбой первого из них в случае, если этот тег имеет значение true (или аналогичное значение). Я протестирую ваше решение.