[Nginx] Логи Nginx в JSON

Привет, %username%! Далее будет совсем короткая заметка о том, как в Nginx настроить access-лог в формате JSON.

Почему JSON?

Использование стандартного формата лога для access-лога в Nginx вполне себе оправдано ровно до тех пор, пока можешь их руками посмотреть/распарсить/поgrepать/catнуть/awkнуть. Как только начинается ситуация когда у тебя access-лог растет на несколько сотен мегабайт (а порой и нескольких гигабайт) в сутки – парсить такое становится сложно. Выход простой — ELK/Graylog. Что именно выбрать — каждый сам решает. Я же пока останавливаюсь на стэке ELK. Собственно под него и заточен мой конфиг.

Сам конфиг

Сам конфиг выглядит довольно просто:

log_format main '{"@timestamp":"$time_iso8601",'
                '"@source":"$server_addr",'
                '"hostname":"$hostname",'
                '"ip":"$http_x_forwarded_for",'
                '"client":"$remote_addr",'
                '"request_method":"$request_method",'
                '"scheme":"$scheme",'
                '"domain":"$server_name",'
                '"referer":"$http_referer",'
                '"request":"$request_uri",'
                '"args":"$args",'
                '"size":$body_bytes_sent,'
                '"status": $status,'
                '"responsetime":$request_time,'
                '"upstreamtime":"$upstream_response_time",'
                '"upstreamaddr":"$upstream_addr",'
                '"http_user_agent":"$http_user_agent",'
                '"https":"$https"'
                '}';

Данную старшную портянку необходимо добавть в главный файл настроек /etc/nginx/nginx.conf, а для каждого своего сайта в директиве access_log дополнительно указать данный формат. Вот в таком виде:

server {
...
    access_log /var/log/nginx/blog.jtprog.ru.log main;
...
}

После чего в лог-файл /var/log/nginx/blog.jtprog.ru.log будут прилетать строки вот такого вида:

{
  "@timestamp": "2020-09-11T01:04:51+03:00",
  "@source": "123.123.123.123",
  "hostname": "jtprog-lb",
  "ip": "321.321.321.321",
  "client": "213.213.213.213",
  "request_method": "GET",
  "scheme": "https",
  "domain": "jtprog.ru",
  "referer": "https://jtprog.ru/",
  "request": "/api/v3/social/insta",
  "args": "-",
  "size": 2814,
  "status": 200,
  "responsetime": 0,
  "upstreamtime": "0.000",
  "upstreamaddr": "10.213.213.12:9000",
  "http_user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 YaBrowser/20.8.1.210.10 Mobile/15E218 Safari/684.1",
  "https": "on"
}

Итого

Далее этот файл можно скармливать filebeat’у и он его уже будет парсить как полноценный JSON, а не с помощью регулярок и grok’ов.