Журнал ошибок nginx Шаблон Grok

У меня проблемы с получением следующего сообщения журнала ошибок nginx для анализа в отладчике grok. У меня есть ощущение, что есть глупая уловка, которую я должен использовать, но не могу понять, что это может быть.

2015/03/20 23:35:52 [ошибка] 8#0: *10241823 не удалось проверить существование "/www" (2: такой файл или каталог отсутствуют) во время запроса журнала, клиент: 201.45.203.78, сервер: $domain, запрос: "GET / Ritikapuri_"

Вот мой образец Грока:

(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER}: %{GREEDYDATA:errormessage} client: %{IP:client}

Этот шаблон возвращает меня в раздел "сервер", но я не могу разобрать остальные, и мне не понятно почему.

Если я использую другой шаблон%{GREEDYDATA} для захвата конца журнала, он иногда не будет анализировать журналы, которые не соответствуют вышеприведенному, и дает мне _grokparsefailure.

Будет ли лучший способ использовать операторы if для отлова различных вариантов сообщений журнала в nginx?

Я следовал методам, включая этот, но не могу заставить их работать.

3 ответа

Я использовал ответ @dr01, чтобы улучшить рецепт регистрации ошибок в nginx 1.15 используя формат уведомления - этот ответ будет разделять версию HTTP, метод и запрос HTTP.

(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER:threadid}\: \*%{NUMBER:connectionid} %{GREEDYDATA:message}, client: %{IP:client}, server: %{GREEDYDATA:server}, request: "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion}))", host: %{GREEDYDATA:host}

образец строки

2015/03/20 23:35:52 [error] 8#0: *10241823 testing "/www" existence failed (2: No such file or directory) while logging request, client: 201.45.203.78, server: $domain, request: "GET /dsfadsfe HTTP/1.1", host: "localhost:8080"

Выход из отладчика Grok

{
  "timestamp": [
    [
      "2015/03/20 23:35:52"
    ]
  ],
  "severity": [
    [
      "error"
    ]
  ],
  "pid": [
    [
      "8"
    ]
  ],
  "threadid": [
    [
      "0"
    ]
  ],
  "connectionid": [
    [
      "10241823"
    ]
  ],
  "message": [
    [
      "testing "/www" existence failed (2: No such file or directory) while logging request"
    ]
  ],
  "client": [
    [
      "201.45.203.78"
    ]
  ],
  "server": [
    [
      "$domain"
    ]
  ],
  "verb": [
    [
      "GET"
    ]
  ],
  "request": [
    [
      "/dsfadsfe"
    ]
  ],
  "httpversion": [
    [
      "1.1"
    ]
  ],
  "host": [
    [
      ""localhost:8080""
    ]
  ]
}

Не видя, как вы пробовали шаблоны, которые не работали, я не могу прокомментировать, почему они не работают. Поскольку вы указали, что предоставленный вами шаблон соответствует серверу, я немного изменил ваше утверждение и добавил немного в конец, чтобы захватить остальные:

(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER}: %{GREEDYDATA:errormessage},\ client: %{IP:client}, server: \$domain, request: \"%{WORD:method} %{URIPATH:path}\"

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

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

число рейнольдса: Наилучшим ли способом будет использование операторов if для отлова различных вариантов сообщений журнала в nginx?

Я не совсем понимаю, о чем вы спрашиваете, но вы можете поместить операторы вокруг вашего фильтра или его частей, как в этом ответе. Вы можете сделать то же самое, используя теги, если вы можете найти способ пометить их. Эти два варианта, вероятно, являются "лучшими" с точки зрения вычислительной мощности, используемой для каждой линии, так как я полагаю, что потребуется меньше работы, чем что-то вроде этого ответа, поскольку каждое событие необходимо будет проверять по каждому шаблону. Вы также можете написать очень сложный шаблон, который может соответствовать любой другой ситуации, но я не думаю, что это идеальный вариант, поскольку шаблон расширится до такого количества возможных совпадений, что каждый раз потребуется много сил для проверки.

Надеюсь, это поможет!

Этот рецепт Грок также работает, независимо от значения server поле:

(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER:threadid}\: \*%{NUMBER:connectionid} %{GREEDYDATA:errormessage}, client: %{IP:client}, server: %{GREEDYDATA:server}, request: %{GREEDYDATA:request}

Шаблон ошибки Grok с добавлением дополнительных полей восходящего и реферера. Протестировано с nginx:1.17.3

(?<timestamp>%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}) \[%{LOGLEVEL:severity}\] %{POSINT:pid}#%{NUMBER:threadid}\: \*%{NUMBER:connectionid} %{GREEDYDATA:message}, client: %{IP:client}, server: %{GREEDYDATA:server}, request: "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion}))"(, upstream: "%{GREEDYDATA:upstream}")?, host: "%{DATA:host}"(, referrer: "%{GREEDYDATA:referrer}")?
Другие вопросы по тегам