Как создать логику фильтра grok для журнала ошибок Nginx

#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})"]?