Конвейер анализа логов
Собери find, grep, cut, sort, uniq -c и awk в многоступенчатый конвейер, извлекающий реальные данные из access-логов — топ клиентских IP, распределение кодов ответа и всплески ошибок — единственной командой в оболочке.
Сервер генерирует гигабайты логов Nginx. Что-то вызвало всплеск P99-задержки в 03:47 этим утром. Нужен ответ за две минуты, а не за два часа написания Python. Все необходимые инструменты — find, grep, cut, sort, uniq -c, awk — уже на машине и чисто соединяются через конвейеры. Этот урок строит такой конвейер поэтапно: одна стадия за раз, чтобы понять, что вносит каждая из них, и адаптировать под любой формат логов в продакшне.
После этого урока ты сможешь собрать инкрементальный конвейер анализа логов с помощью find | xargs grep, cut, sort | uniq -c | sort -rn и awk для извлечения топ клиентских IP, подсчёта кодов ответа и частоты ошибок из стандартных access-логов в формате Combined Log Format.
Начни с find для поиска файлов логов среди ротированных архивов. На продакшн-сервере обычно есть access.log, access.log.1, access.log.2.gz и так далее. find находит все; xargs передаёт их как аргументы следующей команде, а не перенаправляет содержимое — это важно, потому что некоторые команды (например, grep -h) нуждаются в именах файлов, а не в stdin.
find /var/log/nginx -name 'access.log*' -not -name '*.gz'Вывод: список совпавших путей, разделённых переводом строки.
Добавь -mtime -1 для ограничения файлами, изменёнными за последние 24 часа — важно, когда логи ротируются ежедневно и нужны только свежие данные.
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1Никогда не передавай вывод find напрямую в cat для длинных списков — используй xargs, чтобы объединить пути в меньшее количество вызовов grep.
Добавь grep для фильтрации по временному окну или классу ошибок. Временная метка Combined Log Format выглядит как [21/Jun/2026:03:. Ищи по префиксу часа, чтобы ограничиться периодом всплеска.
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep '21/Jun/2026:03:'-h подавляет префикс имени файла в выводе grep (чище для последующего разбора):
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep -h '21/Jun/2026:03:'Теперь на stdout каждый запрос, залогированный в этот час — потенциально миллионы строк, но все релевантные.
Извлеки поле кода статуса с помощью cut. Строка Combined Log Format выглядит так:
192.0.2.1 - alice [21/Jun/2026:03:47:12 +0000] "GET /api/users HTTP/1.1" 200 1234Поля разделены пробелами. Код статуса — поле 9. cut -d' ' -f9 его извлекает.
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep -h '21/Jun/2026:03:' \
| cut -d' ' -f9Вывод: столбец кодов статуса — 200, 404, 503, … по одному на строку. Это входные данные для стадии подсчёта.
Подсчитай и ранжируй с помощью sort | uniq -c | sort -rn. Эта трёхкомандная последовательность — канонический идиом гистограммы:
sort— группирует одинаковые строки рядом (требованиеuniq)uniq -c— сворачивает серии и добавляет перед каждой её счётчикsort -rn— сортирует по числовому счётчику по убыванию (максимум сначала)
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep -h '21/Jun/2026:03:' \
| cut -d' ' -f9 \
| sort | uniq -c | sort -rnПример вывода:
4821 200
312 503
87 404
14 401Теперь видно: 503-ошибок в этот час было 312 — это и есть сигнал. Весь конвейер работает секунды на миллионах строк.
Расширь с помощью awk для многопольного анализа и вычисленных показателей. awk — швейцарский армейский нож для обработки текста по полям. Используй его для вычисления частоты ошибок за один проход или для извлечения клиентского IP (поле 1) с целью анализа топ-«болтунов».
Топ клиентских IP во время всплеска:
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep -h '21/Jun/2026:03:' \
| awk '{print $1}' \
| sort | uniq -c | sort -rn \
| head -10Частота ошибок в процентах с помощью awk:
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep -h '21/Jun/2026:03:' \
| awk '$9 >= 500 {err++} {total++} END {printf "5xx rate: %.1f%%\n", err/total*100}'awk обрабатывает каждую строку за один проход — промежуточная сортировка не нужна. Используй awk, когда нужна арифметика, условия или несколько выходных столбцов. Используй sort | uniq -c, когда нужны ранжированные счётчики.
Полный анализ инцидента: найти 5 IP, которые генерируют больше всего 503-ошибок в 10-минутном окне.
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -mtime -1 \
| xargs grep -h '21/Jun/2026:03:4[0-9]:' \
| awk '$9 == 503 {print $1}' \
| sort | uniq -c | sort -rn \
| head -5Разбор:
grep '21/Jun/2026:03:4[0-9]:'— регулярное выражение4[0-9]совпадает с минутами 40–49 (10-минутное окно).awk '$9 == 503 {print $1}'— оставляет только строки с 503 и выводит клиентский IP (поле 1).sort | uniq -c | sort -rn | head -5— идиом ранжирования, ограниченный 5 результатами.
Пример вывода:
142 192.0.2.47
89 192.0.2.23
61 192.0.2.105
44 192.0.2.8
31 192.0.2.66Один IP дал 142 из ~329 общих 503-ошибок в этом окне — это застрявший клиент или retry-петля зависимости, долбящая сервис. Источник найден менее чем за 10 секунд.
▸Почему это работает
На macOS / BSD sort в некоторых старых версиях не принимает -rn как единый флаг — используй sort -r -n явно. awk на macOS — это one-true-awk (BWK awk), а не gawk; большинство идиомов обработки полей работают идентично. Для сжатых ротированных логов (access.log.2.gz) замени xargs grep на zgrep: find /var/log/nginx -name '*.gz' | xargs zgrep -h 'шаблон'.
▸Частая ошибка
uniq -c требует отсортированного ввода. Если передать прямо в uniq -c без предварительной сортировки, получишь счётчики для каждой последовательной серии — одинаковые значения в разных позициях считаются отдельно. Всегда sort | uniq -c, но не uniq -c в одиночку. Вторая распространённая ошибка: использование sort -n (по возрастанию) без -r, когда нужен максимум сначала — придётся читать вывод с конца.
Ты запускаешь: cat access.log | cut -d' ' -f9 | uniq -c | sort -rn. Вывод выглядит неправильно — счётчики по '1' для каждой строки. Какова наиболее вероятная причина?
Конвейер анализа логов объединяет шесть инструментов последовательно: find находит файлы логов по всем ротациям; xargs grep ограничивает временным окном или шаблоном; cut -d' ' -fN извлекает одно поле; sort | uniq -c | sort -rn — идиом ранжирования для любой гистограммы счётчиков; awk обрабатывает многопольную арифметику и вычисленные показатели за один проход. Строй конвейер инкрементально — добавляй одну стадию за раз и проверяй вывод перед добавлением следующей. uniq -c требует отсортированного ввода. awk правильно использовать, когда нужны условия или арифметика; sort | uniq -c — когда нужны ранжированные счётчики. Вместе они отвечают на вопросы инцидентов за секунды на гигабайтных логах без установки чего-либо дополнительного.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.