#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 (или аналогичное значение). Я протестирую ваше решение.