labctl
войти регистрация

Топ-10 источников 4xx из access-лога

имя
nginx-log-top
образ
python:3.12-slim
таймаут
30с
проверка…

Задание

Топ-10 источников 4xx из access-лога

В /var/log/nginx/access.log лежит ~50 000 строк настоящего nginx-формата
(combined). Напишите однострочник (pipeline), который найдёт топ-10 IP-адресов
по числу запросов с HTTP-статусом 4xx
и сохранит результат в /tmp/top4xx.csv
в формате count,ip (count по убыванию, без заголовка).

Формат лога

203.0.113.1 - - [10/Jul/2026:03:42:11 +0000] "GET /api/users HTTP/1.1" 404 178 "-" "curl/8"
198.51.100.7 - - [10/Jul/2026:03:42:11 +0000] "POST /login HTTP/1.1" 200 45 "-" "Mozilla/5.0"

Первое поле — IP, после кавычек запрос, затем статус (поле №9 по пробелу),
затем размер.

Ожидаемый результат

/tmp/top4xx.csv содержит ровно 10 строк вида:

429,203.0.113.1
312,198.51.100.7
...
17,192.0.2.55

Сортировка — по убыванию count. При равном count порядок не важен.

Почему это hard

Нужно скомбинировать awk (фильтр по статусу + агрегация по ключу),
sort + uniq -c (или целиком внутри awk), head -10, и записать в файл.
Тонкости:
- статусное поле — девятое, его достают $9, но только при правильном
разделителе (по умолчанию awk делит по пробелам — это работает для
combined-формата).
- «4xx» = статус от 400 до 499 включительно.
- uniq -c дописывает лидирующие пробелы — их обычно отрезают sed/awk.
В CSV 42,1.2.3.4 (с пробелами) ≠ 42,1.2.3.4.

Подсказки

  • Один из рабочих путей: awk '$9 >= 400 && $9 < 500 {print $1}' "$LOG" | sort | uniq -c | sort -rn | head -10 | awk '{print $1","$2}' > "$OUT".
  • Можно и целиком в одном awk-скрипте ({a[$1]++} END {for (...) ...}), но это
    длиннее.
  • Проверьте себя: wc -l /tmp/top4xx.csv должно дать 10.
Подсказки

Hints: nginx-log-top

  • Откройте лог и посмотрите на формат: head -1 /var/log/nginx/access.log.
  • IP — первое поле ($1 в awk). Статус — девятое ($9).
  • 4xx = статус от 400 до 499 включительно. Проверка: $9 >= 400 && $9 < 500.
  • Базовый конвейер:
    awk '$9 >= 400 && $9 < 500 {print $1}' /var/log/nginx/access.log \ | sort | uniq -c | sort -rn | head -10 \ | awk '{print $1","$2}' > /tmp/top4xx.csv
  • uniq -c дописывает ведущие пробелы — без финального awk/sed строки будут
    вида 42,1.2.3.4, а не 42,1.2.3.4. check это ловит.
  • Альтернатива — полностью в awk через ассоциативный массив ({a[$1]++} END { ... }),
    но это многословнее.
  • Самопроверка: wc -l /tmp/top4xx.csv должно дать 10.

Последние попытки

  • Загрузка…

Разовый запуск (smoke-тест)

Атомарный цикл up → check → down. Полезно для CI; без предварительной подготовки состояния проверка завершится с ошибкой.