Перейти к содержимому
Разделы
ЯзыкRUEN

v2.1Рецепты

Лог доступа nginx

Найти медленные и упавшие запросы в access.log, посчитать топ путей и ошибки по минутам.

Формат combined стоит в nginx по умолчанию. Чтобы получать время ответа, добавьте его в log_format:

nginx
log_format timed '$remote_addr - $remote_user [$time_local] "$request" '
                 '$status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
access_log /var/log/nginx/access.log timed;

Сверло распознаёт этот вариант как nginx-combined и добавляет поле request_time.

Медленные запросы#

bash
sverlo parse /var/log/nginx/access.log --format nginx-combined \
  --query 'request_time>1.5' --out table --limit 20

Топ путей с ошибками сервера#

js
const counts = new Map();
const failed = parser.query('status:5xx');
for await (const rec of parser.stream(createReadStream('access.log'))) {
  if (!failed(rec)) continue;
  const path = rec.fields.path.split('?')[0];
  counts.set(path, (counts.get(path) ?? 0) + 1);
}
console.table([...counts].sort((a, b) => b[1] - a[1]).slice(0, 10));

Отрезание query-строки важно: иначе каждый запрос с уникальным параметром станет отдельной строкой.

Ошибки по минутам#

js
const bucket = (d) => d.toISOString().slice(0, 16);
const perMinute = {};
for await (const rec of parser.stream(src)) {
  if (rec.fields.status < 500) continue;
  perMinute[bucket(rec.ts)] = (perMinute[bucket(rec.ts)] ?? 0) + 1;
}

На что обратить внимание#

  • Ротация: access.log.1 и access.log читайте как отдельные источники, а не склеивайте через cat, если нужны номера строк.
  • Прокси перед nginx: адрес клиента в ip будет адресом прокси. Настоящий лежит в заголовке X-Forwarded-For, и его нужно явно выводить в log_format.
  • Персональные данные: адреса и пути могут быть персональными. Перед отправкой логов наружу уберите ip и agent из fields.

Обновлено: