#logstash #logstash-grok
Вопрос:
Я пытаюсь написать фильтр Logstash, используя логический шаблон grok. Я веду журнал ошибок nginx. Моя проблема в том, что журнал из nginx содержит 2 поля, которые присутствуют не во всех журналах ошибок. Я использовал этот логический шаблон для фильтрации журнала. Я могу написать 2 шаблона и добавить эти 2 шаблона в конфигурационный файл фильтра logstash. Но есть ли какой-нибудь способ сделать это в рамках единой логической схемы?
Логический шаблон:
(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) [%{LOGLEVEL:severity}] %{POSINT:pid}#%{NUMBER:threadid}: *%{NUMBER:connectionid} %{GREEDYDATA:message}, client: %{IP:client}, server: %{GREEDYDATA:server}, request: "%{GREEDYDATA:request}", upstream: "%{URI:upstream}", host: "%{IPORHOST:host}", referrer: "(?:%{URI:referrer})"
Пример Журнала 1:
2021/09/16 15:58:59 [предупреждение] 104255#104555: *611541 восходящий ответ буферизуется во временный файл /var/кэш/nginx/proxy_temp/6/06/0000000066 при чтении вверх по потоку клиент: 100.16.127.2, сервер: webservice.example.com, запрос: «ПОЛУЧИТЬ /пример/содержимое/общий/img/имя.png HTTP/1.1», вверх по течению: «https://120.27.2.87:43/example/contents/common/img/somename.png», ведущий: «webservice.example.com», реферер: «https://webservice.example.com/example/view/common/api_use/»
Пример Журнала 2:
2021.09.16 10:38:54 [ошибка] 104555#104555: *611070 открыть() «/usr/share/nginx/html/веб-сервис.пример.com/xxxxxxxx» ошибка (2: Такого файла или каталога нет), клиент: 120.36.230.2, сервер: webservice.example.com, запрос: «GET /xxxxxxxx HTTP/1.1», хост: «webservice.example.com
Как вы можете видеть, пример журнала 2 не содержит поля «Вверх по течению» и «Ссылка». Мой шаблон логики работает для журналов, содержащих поле «Вверх по течению» и «Ссылка». Пожалуйста, подскажите, что мне делать? Следует ли мне использовать шаблон 2 логики в конфигурации фильтра Logstash или мне нужно изменить текущий шаблон логики, чтобы он соответствовал обоим типам журналов.
Комментарии:
1. Будьте внимательны, это выглядит отсутствующим » в конце примера журнала 2
Ответ №1:
Если ваша проблема заключается только в том, что некоторые поля отсутствуют, то я бы посоветовал вам не сопоставлять поля напрямую, а использовать kv
фильтр регистрационных данных. Это позволяет вам определить параметры для структур типа ключ-значение внутри строки, затем он разбивает ее и создает карту внутри события.
Вам нужно будет записать всю часть вашего журнала, содержащую значение ключа, в одно поле, содержащее все поля и значения, а затем задать параметры, field_split_pattern
соответствующие вашему случаю, а затем указать target
поле, в котором вы хотите использовать карту, после kv
завершения анализа.
Более подробная информация здесь.
В вашем случае это было бы что-то вроде этого
kv {
field_split_pattern => ", "
value_split_pattern => ": "
target => "field_name"
}
Ответ №2:
Вы можете управлять этим 2 образцом в выражении grok, просто скажите, что восходящий поток и реферер являются опциональными, как это :
[, referrer: "(?:%{URI:referrer})"]?
Итак, наконец, полная строка, которую я протестировал на инструментах grokdebug, и она работает для вашего образца 2 журналов :
%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME} [%{LOGLEVEL:severity}] %{POSINT:pid}#%{NUMBER:threadid}: *%{NUMBER:connectionid} %{GREEDYDATA:message}, client: %{IP:client}, server: %{GREEDYDATA:server}, request: "%{GREEDYDATA:request}", [upstream: "%{URI:upstream}", ]?host: "%{IPORHOST:host}"[, referrer: "(?:%{URI:referrer})"]?