
Введение
Эта статья — справочник по утилитам, которые помогают читать логи и быстро находить в них причину проблем. Для одного сервера или домашней лаборатории (homelab) этого набора хватает в большинстве случаев.
journalctl— чтение журнала systemd, главный инструмент;dmesg— сообщения ядра;tail— конец файла и слежение за логом в реальном времени;less— постраничный просмотр больших логов;grep— поиск по шаблону;zgrep— поиск по сжатым, уже ротированным логам;last,lastb,lastlog— бинарные журналы входов в систему.
Для каждой утилиты вы найдёте, для чего она нужна, и таблицу со всеми ключами.
Примеры выполнены на Ubuntu. Команды, начинающиеся с sudo, требуют прав администратора. На своём сервере они вам понадобятся, на чужом сначала убедитесь, что вам можно.
Базовая информация
Что такое логи
Лог (log) — журнал событий: запись о том, что произошло, с временем и источником. Зачем они нужны? Ну, например, для того, чтобы посмотреть, почему N-й сервис не работает. Если вы обращаетесь, к примеру, за помощью в тематический чат с вопросом «у меня не работает nginx, помогите», вам в большинстве случаев скажут смотреть или прислать логи. Большая часть текстовых логов находится в каталоге /var/log:
Файл |
Что внутри |
|---|---|
|
Общий системный журнал: сообщения служб, ядра, планировщика |
|
Входы в систему, |
|
Сообщения ядра |
|
Что и когда ставилось и удалялось |
|
Бинарные журналы входов, читаются командами |
Часть файлов, возможно, вы не найдёте в своей системе, поскольку на разных дистрибутивах логи пишут сразу два механизма: journald и rsyslog.
journald — служба журналирования из состава systemd. Она перехватывает вывод всех служб и ядра, начиная с самой ранней стадии загрузки, и хранит его в бинарном индексированном виде. Читается командой journalctl.
rsyslog — демон (daemon, фоновая программа), который раскладывает сообщения по текстовым файлам в /var/log.
Так вот, на некоторых сборках или минимальных установках rsyslog может отсутствовать, тогда /var/log/syslog и /var/log/auth.log не существуют, а всё лежит только в journald.
Проверить можно командами systemctl is-active rsyslog (проверка, запущен ли rsyslog) и ls -lh /var/log/syslog /var/log/auth.log (проверка, есть ли текстовые файлы). Если у вас работают эти два механизма, то учитывайте, что сообщение обычно хранится дважды: в журнале и в текстовом файле. На Ubuntu journald пересылает копию в rsyslog: параметр ForwardToSyslog=yes включён в файле /usr/lib/systemd/journald.conf.d/syslog.conf, который поставляется вместе с systemd. В основном конфиге /etc/systemd/journald.conf этот параметр закомментирован (#ForwardToSyslog=no), так что искать yes там бесполезно.
Наверняка вы задались вопросом: а зачем нам эти два механизма? Если вкратце, journald мгновенно собирает логи в единую бинарную базу, а rsyslog забирает этот поток и раскладывает по привычным текстовым файлам в /var/log для совместимости со старым софтом, скриптами и системами мониторинга. Есть и второй плюс: если бинарный журнал повредится из-за сбоя, текстовые файлы читаются чем угодно, и часть логов удастся спасти.
Только не путайте это с резервной копией. Это не считается: оба хранилища лежат на одном диске, и при выходе диска из строя пропадут оба. От этого защищает, например, отправка логов на другой сервер.
Типы логов
Тип |
Где искать |
Когда смотреть |
|---|---|---|
Системные |
|
Общая картина: что делали службы и ядро |
Безопасность и входы |
|
Кто заходил, перебор паролей, |
Пакетные менеджеры |
|
Что ставилось и обновлялось перед тем, как всё сломалось |
Службы и приложения |
|
Работа конкретного сервиса |
Контейнеры |
|
Вывод контейнеров лежит не в |
Установка и первый запуск |
|
Почему свежий VPS настроился не так, как ожидалось |
Типы логов знать необязательно, но рекомендуется, если вы хотите запомнить, где что находится, или пишете своё ПО и хотите понимать, в чём разница между текстовыми (rsyslog) и бинарными (journald) логами. Текстовые читаются cat, less, grep. Бинарные так читать нельзя: нужны свои команды, например:
Бинарный лог |
Чем читать |
|---|---|
Журнал journald |
|
|
|
|
|
|
|
Если сделать grep по btmp, вы получите сообщение типа binary file matches и подумаете, что искомого там нет. А оно там есть, grep просто отказался печатать бинарные данные.
Как устроена строка лога
В зависимости от того, где вы и что смотрите, структура логов может меняться, но базовые вещи всё же вы поймёте по этому примеру:
сен 17 18:10:13 veilos kernel: Linux version 7.0.0-31-generic (buildd@lcy02-amd>
сен 17 18:10:13— время события. Формат упрощён (в syslog дату и прочие параметры можно увидеть детальнее).veilos— имя компьютера (hostname).kernel:— источник сообщения (тут он указывает, что запись сделана ядром операционной системы).Linux version 7.0.0-31-generic— текст сообщения.(buildd@lcy02-amd>— обрезанный хвост строки (её обрезал пейджерless:journalctlзапускает его с обрезкой длинных строк, а символ>показывает, что текст не поместился в ширину терминала. Остальное видно, если прокрутить вправо, а с ключом--no-pagerстроки переносятся).
Не хватает уровней важности, о них ниже.
Уровни важности
У каждого сообщения есть уровень (приоритет). Их восемь, от самого серьёзного к самому незначительному:
Число |
Имя |
Значение |
|---|---|---|
0 |
|
Система непригодна к работе |
1 |
|
Действовать нужно немедленно |
2 |
|
Критическая ошибка |
3 |
|
Ошибка |
4 |
|
Предупреждение (в |
5 |
|
Обычное, но значимое событие |
6 |
|
Информационное сообщение |
7 |
|
Отладка |
Эти уровни нужны, например, в journalctl -p и dmesg -l, и ведут они себя по-разному:
journalctl -p errпоказывает уровеньerrи всё серьёзнее: 0, 1, 2 и 3;dmesg -l errпоказывает толькоerr, аcritи выше не покажет. Чтобы получить то же, что даётjournalctl, перечислите уровни:dmesg -l emerg,alert,crit,err.
Ротация логов
Текстовые логи растут, поэтому их периодически ротируют (rotate): текущий файл переименовывают, а вместо него создают новый пустой. Этим занимается logrotate. Он запускается по расписанию (таймером systemd или через cron), а настройки лежат в /etc/logrotate.conf и /etc/logrotate.d/.
Поэтому в /var/log рядом с syslog вы увидите такие файлы:
ls -lh /var/log/syslog*
-rw-r----- 1 syslog adm 6,6M окт 3 18:52 /var/log/syslog -rw-r----- 1 syslog adm 13M сен 27 12:09 /var/log/syslog.1 -rw-r----- 1 syslog adm 1,8M сен 20 12:27 /var/log/syslog.2.gz -rw-r----- 1 syslog adm 1,3M сен 13 08:36 /var/log/syslog.3.gz -rw-r----- 1 syslog adm 987K сен 6 00:00 /var/log/syslog.4.gz
syslog.1 — предыдущий лог, он остаётся несжатым, потому что служба ещё может дописывать в него хвост. Начиная с .2 файлы сжаты gzip. Сколько копий хранится и как часто идёт ротация, зависит от конфигурации. На Ubuntu в /etc/logrotate.d/rsyslog стоят weekly и rotate 4: ротация раз в неделю, хранятся 4 копии. Именно поэтому даты в списке выше отстоят друг от друга на неделю.
Из этого следуют две вещи. Во-первых, grep по syslog не увидит событий недельной давности, для этого понадобится zgrep. Во-вторых, tail -f может «потерять» файл после ротации. Как с этим бороться, написано в разделе про tail.
Хранение журнала journald
Журнал journald может храниться в двух режимах:
постоянный: файлы лежат в
/var/log/journalи переживают перезагрузку;временный: файлы лежат в
/run/log/journal, то есть в памяти, и пропадают при перезагрузке. Режим выбирает параметрStorage=в/etc/systemd/journald.conf. По умолчанию стоитauto: журнал постоянный, если каталог/var/log/journalсуществует. На Ubuntu он есть сразу.
Для разбора «почему сервер упал и перезагрузился» это может быть критично, т.к. если журнал временный, логи предыдущей загрузки уже исчезли. Проверить режим можно так:
ls -d /var/log/journal journalctl --list-boots
Права доступа
Многие логи читаются только от root или от групп adm и systemd-journal. Чтобы не писать sudo перед каждой командой, вы можете добавить себя в эти группы:
# Группа adm даёт чтение файлов в /var/log, systemd-journal даёт чтение журнала journald sudo usermod -aG adm,systemd-journal $USER
Изменения применятся после нового входа в систему. Флаг
-aобязателен. Без него команда заменит все ваши дополнительные группы, и вы потеряете, например,sudo.
Учтите, что группа adm даёт чтение auth.log, а в нём видны имена пользователей, IP-адреса и попытки входа. Выдавайте её только тем, кому это действительно нужно. Исключение: файл /var/log/btmp принадлежит группе utmp, а не adm. Поэтому lastb потребует sudo, даже если вы состоите в adm.
Перед тем как выложить лог
Если вы собираетесь показать кусок лога на форуме, в issue или в чате, сначала проверьте его. В логах бывают токены в URL, пароли в параметрах запроса, имена пользователей, внутренние адреса и IP клиентов. Замените их заглушками до отправки. Это касается и вывода journalctl, и access.log, и логов приложений (да, в принципе, любого лога практически).
На этом базовое ознакомление с логами заканчивается, переходим к утилитам.
journalctl
journalctl читает журнал journald: вывод всех служб, сообщения ядра и сообщения ранней загрузки в одном месте. Его преимущество перед текстовыми файлами в том, что фильтровать можно по службе, времени, уровню и номеру загрузки, не прибегая к grep. Для разбора проблем это первая команда, с которой стоит начинать.
Общий вид: journalctl [ключи] [фильтры], где фильтры — это пары ПОЛЕ=значение, например _PID=1234 или _SYSTEMD_UNIT=cron.service.
Если у вас нет прав, команда напишет подсказку вида You are currently not seeing messages from other users and the system и покажет только ваш пользовательский журнал. Решение — группа systemd-journal из раздела про права доступа или sudo. Набор ключей зависит от версии systemd, свою версию покажет journalctl --version.
Флаг |
Что делает |
|---|---|
|
Показать системный журнал |
|
Показать журнал текущего пользователя |
|
Работать с локальным контейнером |
|
Показать записи из всех доступных журналов |
|
Взять файлы журнала из каталога |
|
Прочитать конкретный файл журнала |
|
Работать с другим корнем файловой системы |
|
Работать с образом диска как с корнем файловой системы |
|
Политика разбора образа диска |
|
Показать данные из указанного пространства имён журнала |
|
Записи не старше указанной даты. Формат: |
|
Записи не новее указанной даты |
|
Начать с записи, на которую указывает курсор |
|
Показать записи после курсора |
|
Показать записи после курсора из файла и обновить файл. Удобно для скриптов, которые читают журнал порциями |
|
Текущая загрузка или указанная. |
|
Логи указанной службы. Ключ можно повторять |
|
Логи указанной пользовательской службы |
|
Записи с указанным идентификатором syslog, обычно это имя программы |
|
Фильтр по уровню. Одиночный уровень включает и всё серьёзнее. Диапазон задаётся так: |
|
Записи указанных категорий: |
|
Записи, в тексте сообщения которых есть совпадение с шаблоном (регулярное выражение). Если шаблон в нижнем регистре, регистр не учитывается |
|
Принудительно включить или выключить учёт регистра в |
|
Сообщения ядра за текущую загрузку, аналог |
|
Формат вывода: |
|
Какие поля печатать в режимах |
|
Сколько записей показать |
|
Новые записи сверху |
|
Напечатать курсор после всех записей |
|
Показывать время в UTC |
|
Добавить пояснения к известным сообщениям, где они есть |
|
Не выводить имя хоста |
|
Обрезать длинные поля многоточием |
|
Показать все поля целиком, включая длинные и непечатаемые |
|
Следить за журналом в реальном времени, выход по |
|
В режиме слежения показать все строки, а не только последние |
|
Обрезать запись по первому символу перевода строки |
|
Не выводить служебные сообщения и предупреждение о правах |
|
Не использовать пейджер: в терминале вывод печатается сразу, без |
|
Сразу перейти в конец в пейджере |
|
Интервал смены ключа запечатывания FSS |
|
Ключ для проверки запечатанного журнала FSS |
|
Перезаписать существующую пару ключей FSS при |
|
Показать справку |
|
Показать версию |
|
Перечислить все имена полей, которые встречаются в журнале |
|
Перечислить все значения поля. |
|
Краткий список загрузок, сохранённых в журнале |
|
Сколько места занимают все файлы журнала |
|
Удалить старые файлы, чтобы журнал занимал меньше указанного размера |
|
Оставить только указанное число файлов журнала |
|
Удалить файлы старше указанного срока |
|
Проверить целостность файлов журнала |
|
Сбросить несохранённые сообщения журнала на диск |
|
Прекратить запись на диск, писать во временную файловую систему |
|
То же, но ничего не делать, если каталог журнала лежит на корневом разделе |
|
Перенести журнал из |
|
Запросить немедленную ротацию файлов журнала |
|
Показать заголовок журнала |
|
Показать все идентификаторы сообщений каталога |
|
Показать записи каталога сообщений |
|
Обновить базу каталога сообщений |
|
Сгенерировать новую пару ключей FSS |
dmesg
dmesg печатает кольцевой буфер ядра (kernel ring buffer). Туда ядро пишет всё про железо и драйверы: нашлись диски, поднялась сетевая карта, пошли ошибки ввода-вывода, сработал OOM killer. Буфер небольшой и фиксированного размера. Когда он заполняется, новые сообщения затирают старые, а после перезагрузки он пустой. Получается, что dmesg видит только текущую загрузку. Что было до неё, я смотрю через journalctl -k -b -1, но это работает только если журнал постоянный.
Файл /var/log/dmesg с командой не путайте. Это снимок буфера, который делается в конце загрузки, дальше он не обновляется. Также на Ubuntu и новых Debian от обычного пользователя dmesg может ругнуться: read kernel buffer failed: Operation not permitted. Дело в kernel.dmesg_restrict, значение смотрится командой sysctl kernel.dmesg_restrict. Там 1, значит, нужен sudo.
Без -T время в начале строки идёт в секундах с момента загрузки, вида [ 1234.567890]. Читать неудобно, зато оно точное. А вот -T иногда врёт, подробности в таблице.
Флаг |
Что делает |
|---|---|
|
Очистить буфер ядра |
|
Прочитать все сообщения и очистить буфер |
|
Отключить вывод сообщений на консоль |
|
Включить вывод сообщений на консоль |
|
Взять данные из файла вместо буфера ядра |
|
Оставить только указанные категории (facility). Есть |
|
Вывод для человека: пейджер, цвета, относительное время |
|
Вывод в JSON |
|
Показать сообщения ядра |
|
Цвет: |
|
Оставить только указанные уровни через запятую: |
|
Задать уровень сообщений, которые идут на консоль |
|
Не использовать пейджер |
|
Метка времени в каждой строке многострочного сообщения |
|
Сырой буфер |
|
Не экранировать непечатаемые символы |
|
Работать через |
|
Размер буфера при запросе к кольцевому буферу ядра |
|
Показать сообщения пользовательского уровня |
|
Ждать новых сообщений |
|
Ждать новых сообщений и печатать только их |
|
Расшифровать категорию и уровень в названия |
|
Показать разницу во времени между сообщениями |
|
Локальное время и разница между сообщениями в читаемом виде |
|
Время в виде даты. Может быть неточным: после suspend и hibernate оно сбивается |
|
Не показывать время |
|
Формат времени: |
|
Показать строки с указанного времени |
|
Показать строки до указанного времени |
|
Показать справку |
|
Показать версию |
tail
tail печатает конец файла. Для логов это самое подходящее поведение: проблема обычно в последних строках. А с ключом -f команда не завершается, а продолжает печатать строки по мере их появления, и вы видите, что происходит, прямо сейчас.
Если файлов несколько, перед каждым печатается заголовок с именем. Если файл не указан или указан -, команда читает стандартный ввод.
Различие для логов — между -f и -F. -f следит за дескриптором, то есть за самим открытым файлом. Когда logrotate переименовывает syslog в syslog.1, tail -f продолжает смотреть на этот переименованный файл, в который уже никто не пишет, и вывод просто замолкает. -F следит за именем: после ротации он замечает, что под именем syslog появился новый файл, и переключается на него. Для долгого слежения за логом на реальном сервере используйте -F.
Флаг |
Что делает |
|---|---|
|
Показать последние N байт. |
|
Выводить поступающие данные по мере роста файла. Без значения используется |
|
То же, что |
|
Показать последние N строк вместо 10. |
|
С |
|
С |
|
Не выводить заголовки с именами файлов |
|
Продолжать пытаться открыть файл, даже когда он недоступен |
|
С |
|
Всегда выводить заголовки с именами файлов |
|
Разделитель строк — NUL, а не перевод строки |
|
Показать справку |
|
Показать версию |
У N в -c и -n могут быть суффиксы-множители: b — 512, kB — 1000, K — 1024, MB — 10001000, M — 10241024, GB, G и так далее до Y, R, Q. Двоичные приставки тоже работают: KiB = K, MiB = M.
less
less — постраничный просмотр файла. Он не загружает файл целиком, поэтому спокойно открывает логи на гигабайты, и в нём можно двигаться вперёд и назад, искать, фильтровать строки. Это основной способ изучать большой лог, когда tail уже мало.
Выход — q, справка внутри программы — h. Режим слежения за файлом включается клавишей F внутри или запуском less +F файл: остановка по Ctrl+C позволяет пролистать историю, повторное F возвращает слежение. Клавиши, помеченные *, можно предварять числом N, оно меняет их поведение. Большинство ключей командной строки можно переключить и внутри less клавишей - (короткий) или -- (длинный).
В таблице ниже сначала идут ключи командной строки, затем клавиши внутри программы. Строки, относящиеся к работе внутри less, помечены словом «внутри».
Флаг |
Что делает |
|---|---|
|
Показать справку |
|
Поиск пропускает текущий экран |
|
Поиск начинается сразу после целевой строки |
|
Количество буферов |
|
Не выделять буферы автоматически для каналов |
|
Перерисовывать экран очисткой, а не прокруткой |
|
Режим «глупого» терминала |
|
Задать цвета экрана |
|
Выходить при достижении конца файла |
|
Открывать и не обычные файлы |
|
Выйти, если файл целиком помещается на первый экран |
|
Подсвечивать только последнее найденное |
|
Не подсвечивать найденное вообще |
|
Предел прокрутки назад |
|
Игнорировать регистр в поиске, если в шаблоне нет заглавных |
|
Игнорировать регистр в любом поиске |
|
Позиция найденной строки на экране |
|
Показывать колонку состояния слева |
|
Использовать файл lesskey |
|
Выходить из |
|
Игнорировать переменную окружения |
|
Стиль подсказки внизу экрана |
|
Не использовать номера строк ( |
|
Копировать ввод в файл (только для стандартного ввода) |
|
То же, но существующий файл перезаписывается без вопросов |
|
Начать с первого совпадения с шаблоном |
|
Задать собственную подсказку |
|
Отключить звуковой сигнал терминала |
|
Выводить управляющие символы как есть. Нужен для цветного вывода |
|
Сжимать несколько пустых строк в одну |
|
Обрезать длинные строки, а не переносить |
|
Найти тег |
|
Использовать другой файл тегов |
|
Изменить обработку backspace |
|
Показать версию |
|
Подсвечивать первую новую строку после прокрутки экрана вперёд |
|
Подсвечивать первую новую строку после любого движения вперёд |
|
Задать позиции табуляции |
|
Не использовать строки инициализации и деинициализации termcap (экран не очищается при выходе) |
|
Предел прокрутки вперёд |
|
Размер окна |
|
Символы кавычек оболочки |
|
Не показывать тильды после конца файла |
|
Шаг горизонтальной прокрутки (0 — пол-ширины экрана) |
|
Автоматически определять размер входного файла |
|
Команда |
|
Искать по мере ввода каждого символа шаблона |
|
Ширина поля номера строки в |
|
Включить ввод мышью |
|
Не посылать строки инициализации и деинициализации клавиатуры termcap |
|
Убрать повторы из истории команд |
|
Символ, которым помечаются обрезанные строки |
|
Сохранять закладки между запусками |
|
Ширина колонки состояния |
|
Следующие ключи используют обратную косую черту как экранирующий символ |
|
Включить цветной текст |
|
На сколько строк прокручивать за один щелчок колеса мыши |
|
Показать справку |
|
Выйти |
|
На строку вперёд (или на N строк) |
|
На строку назад (или на N строк) |
|
На окно вперёд (или на N строк) |
|
На окно назад (или на N строк) |
|
На окно вперёд и задать размер окна N |
|
На окно назад и задать размер окна N |
|
На окно вперёд, не останавливаясь на конце файла |
|
На полокна вперёд (и задать размер полокна N) |
|
На полокна назад (и задать размер полокна N) |
|
Вправо на пол-ширины экрана (или на N позиций) |
|
Влево на пол-ширины экрана (или на N позиций) |
|
Вправо до последнего показанного столбца |
|
Влево до первого столбца |
|
Следить вперёд бесконечно, как |
|
Как |
|
Перерисовать экран |
|
Перерисовать экран, отбросив буферизованный ввод |
|
Искать вперёд N-ю подходящую строку |
|
Искать назад N-ю подходящую строку |
|
Повторить предыдущий поиск (N-е вхождение) |
|
Повторить предыдущий поиск в обратном направлении |
|
Повторить предыдущий поиск, переходя между файлами |
|
Повторить предыдущий поиск в обратном направлении между файлами |
|
Включить или выключить подсветку найденного |
|
Снять подсветку найденного |
|
Показать только подходящие строки. Вернуть всё: |
|
Искать строки, которые не подходят |
|
Искать по нескольким файлам, переходя через конец файла |
|
Начать поиск с первого файла (для |
|
Подсветить совпадения, но не перемещаться |
|
Не использовать регулярные выражения |
|
Зациклить поиск, если совпадений не нашлось |
|
В первую строку файла (или в строку N) |
|
В последнюю строку файла (или в строку N) |
|
В начало файла (или на N процентов вглубь файла) |
|
К следующему тегу (N-му) |
|
К предыдущему тегу (N-му) |
|
Найти закрывающую скобку |
|
Найти открывающую скобку |
|
Найти закрывающую скобку |
|
Найти открывающую скобку |
|
Поставить закладку на верхнюю строку. Закладкой может быть любая буква |
|
Поставить закладку на нижнюю строку |
|
Перейти к закладке. Заранее определены |
|
Вернуться на предыдущую позицию |
|
То же, что |
|
Снять закладку |
|
Открыть другой файл |
|
Следующий файл из командной строки (N-й) |
|
Предыдущий файл из командной строки (N-й) |
|
Первый файл из командной строки (или N-й) |
|
Убрать текущий файл из списка командной строки |
|
Показать имя текущего файла |
|
Переключить ключ командной строки |
|
Переключить ключ командной строки по длинному имени |
|
Показать значение ключа |
|
Показать значение ключа по длинному имени |
|
Выполнять команду |
|
Выполнить команду в оболочке |
|
Передать участок файла между текущей позицией и закладкой X в команду оболочки |
|
Сохранить ввод в файл |
|
Открыть текущий файл в |
|
Показать версию |
|
Курсор на символ вправо |
|
Курсор на символ влево |
|
Курсор на слово вправо |
|
Курсор на слово влево |
|
Курсор в начало строки |
|
Курсор в конец строки |
|
Удалить символ слева от курсора |
|
Удалить символ под курсором |
|
Удалить слово слева от курсора |
|
Удалить слово под курсором |
|
Удалить всю строку |
|
Предыдущая введённая команда |
|
Следующая введённая команда |
|
Дополнить имя файла и перебирать варианты |
|
Дополнить имя файла и перебирать в обратном порядке |
|
Дополнить имя файла и показать все варианты |
Окно по умолчанию равно высоте экрана, полокна — половине высоты. Строка команд — это строка внизу экрана, которую вы вводите, например, при поиске.
grep
grep ищет строки по шаблону. Он работает с текстовыми файлами и с выводом других команд через конвейер. Для логов это основной инструмент поиска: найти все неудачные входы, все строки одной службы, посчитать количество ошибок.
Общий вид: grep [ключи] ШАБЛОНЫ [ФАЙЛ...]. Шаблонов можно указать несколько, разделяя их переводом строки. Если файл указан как -, читается стандартный ввод. Если файл не указан, читается текущий каталог при -r и стандартный ввод в остальных случаях. Код завершения: 0, если что-то найдено, 1, если ничего не совпало, 2 при ошибках (если не задан -q).
Флаг |
Что делает |
|---|---|
|
Шаблоны — расширенные регулярные выражения |
|
Шаблоны — обычные строки, без регулярных выражений |
|
Шаблоны — простые регулярные выражения (режим по умолчанию) |
|
Шаблоны — регулярные выражения Perl |
|
Использовать указанные шаблоны для поиска |
|
Брать шаблоны из файла |
|
Игнорировать регистр |
|
Учитывать регистр (режим по умолчанию) |
|
Совпадение только с целым словом |
|
Совпадение только с целой строкой |
|
Строки разделяются нулевым байтом, а не символом конца строки |
|
Не показывать сообщения об ошибках |
|
Выбирать строки, которые не подходят |
|
Показать версию |
|
Показать справку |
|
Остановиться после указанного числа совпавших строк |
|
Печатать смещение в байтах вместе со строкой |
|
Печатать номер строки вместе со строкой |
|
Сбрасывать буфер после каждой строки. Нужен в конвейерах со слежением, иначе вывод приходит с задержкой |
|
Печатать имя файла для каждой строки |
|
Не печатать имя файла |
|
Использовать метку в качестве имени файла для стандартного ввода |
|
Показывать только совпавшие непустые части строк |
|
Подавить весь обычный вывод |
|
Как считать бинарный файл: |
|
То же, что |
|
То же, что |
|
Как обрабатывать каталоги: |
|
Как обрабатывать устройства, FIFO и сокеты: |
|
То же, что |
|
То же, но с переходом по всем символьным ссылкам |
|
Обрабатывать только файлы, подходящие под маску |
|
Пропускать файлы, подходящие под маску |
|
Пропускать файлы, подходящие под маски из файла |
|
Пропускать каталоги, подходящие под маску |
|
Печатать только имена файлов без выбранных строк |
|
Печатать только имена файлов с выбранными строками |
|
Печатать только количество выбранных строк на файл |
|
Выравнивать табуляцией, если нужно |
|
Печатать нулевой байт после имени файла |
|
Напечатать указанное число строк перед совпадением |
|
Напечатать указанное число строк после совпадения |
|
Напечатать указанное число строк вокруг совпадения |
|
То же, что |
|
Печатать SEP в строке между группами совпадений с контекстом |
|
Не печатать разделитель между группами |
|
Подсвечивать совпавшие строки: |
|
Не удалять символы CR в конце строки (MS-DOS и Windows) |
zgrep
zgrep — это grep, который умеет читать сжатые gzip-файлы. Из-за ротации логи недельной давности лежат в syslog.2.gz, auth.log.3.gz и так далее, и обычный grep по ним ничего не найдёт. zgrep распаковывает их на лету и ищет внутри, а обычные несжатые файлы читает как grep. Поэтому одна команда по маске (/var/log/syslog*) охватывает и текущий лог, и все архивные.
Общий вид: zgrep [ключи] [-e] ШАБЛОН [ФАЙЛ...]. Порядок файлов при маске лексикографический, а не по времени: syslog.1, syslog.10.gz, syslog.2.gz. Для сжатия другими алгоритмами есть bzgrep (.bz2), xzgrep (.xz) и zstdgrep (.zst).
Ключи те же, что у grep (таблица выше). Не поддерживаются:
Флаг |
Что делает в |
|---|---|
|
Рекурсивный поиск с переходом по символьным ссылкам |
|
Рекурсивный поиск |
|
Действие над каталогами |
|
Обрабатывать только файлы, подходящие под маску |
|
Пропускать файлы, подходящие под маску |
|
Пропускать файлы по маскам из файла |
|
Пропускать каталоги, подходящие под маску |
|
Печатать нулевой байт после имени файла |
|
Строки разделяются нулевым байтом |
Из-за этого zgrep -r по каталогу не работает: файлы нужно перечислять явно или задавать маской оболочки.
Журналы входов: last, lastb, lastlog
Журналы входов в систему бинарные, и читать их можно только специальными командами, а не grep или less. last читает /var/log/wtmp: историю входов, выходов, перезагрузок и выключений. lastb читает /var/log/btmp: неудачные попытки входа. lastlog читает /var/log/lastlog: время последнего входа каждого пользователя. Исходные записи в текстовом виде показывает utmpdump, например sudo utmpdump /var/log/wtmp. last и lastlog работают без sudo, а lastb нужен sudo, потому что btmp закрыт для всех, кроме root и группы utmp.
Общий вид: last [ключи] [имя_пользователя...] [tty...], у lastb то же самое, у lastlog просто lastlog [ключи]. Ключи last и lastb одинаковые, отличается только файл по умолчанию: /var/log/wtmp у last и /var/log/btmp у lastb.
Команда |
Ключ |
Что делает |
|---|---|---|
|
|
Сколько строк вывести |
|
|
Имя хоста в последней колонке |
|
|
Перевести IP-адрес обратно в имя хоста |
|
|
Взять указанный файл вместо |
|
|
Полное время и дата входа и выхода |
|
|
IP-адреса в виде «числа и точки» |
|
|
Сколько строк вывести |
|
|
Не выводить поле с именем хоста |
|
|
Строки начиная с указанного времени |
|
|
Строки до указанного времени |
|
|
Кто был в системе в указанное время |
|
|
Полные имена пользователя и домена |
|
|
Добавить записи о выключениях системы и смене уровня запуска |
|
|
Формат меток времени: |
|
|
Справка |
|
|
Версия |
|
|
Записи старше указанного числа дней |
|
|
Очистить запись lastlog пользователя. Только вместе с |
|
|
Справка |
|
|
Каталог, в который выполняется chroot |
|
|
Записать в lastlog пользователя текущее время. Только вместе с |
|
|
Записи за последние указанные дни |
|
|
Запись только для этой учётной записи |
Что чаще всего используется для разбора проблем
Вообще на практике многие ключи и флаги вы можете не встретить или не использовать, но гарантированно возникнет ситуация, когда вам понадобится сделать следующее:
вывести лог целиком до и после запуска N-го сервиса (например, чтобы посмотреть, что происходит при его запуске);
вывести последние, условно, 50 строк, чтобы посмотреть причину падения сервиса;
вывести только строки с нужным словом (например, со статусом err или warn и т.п.);
проверить на нехватку памяти (чтобы посмотреть, например, сработал ли OOM killer);
вывести логи полностью и т.п.
Попробуйте самостоятельно составить такие команды, если у вас развёрнут Docker или какой-нибудь другой сервис/служба. (Ну так, чисто для практики :) ) Если справились, то вы большой молодец!)
Заключение
В статье мы разобрали базовые утилиты для работы с логами и то, на чём они держатся: где лежат логи, чем текстовые отличаются от бинарных, что такое уровни важности, ротация и постоянный журнал journald. Для одного сервера или homelab этого набора хватает. Но бывают случаи потяжелее. Например, нужно сопоставить по времени сразу несколько логов разных служб, разобраться в файлах с разными форматами или перекопать гигабайты записей. Тут даже эти утилиты начинают мешать: вы гоняете один и тот же grep по десятку файлов и сшиваете результат руками. В таких ситуациях подключают инструменты вроде lnav: он сам разбирает форматы логов, склеивает несколько файлов в одну ленту по времени и читает сжатые архивы напрямую. Это уже тема для отдельной статьи.
© 2026 ООО «МТ ФИНАНС»
Комментарии (2)

nojecom
09.11.2026 09:11И вся статья - просто пересказ man’ов? Выкинуть эти криво сверстанные таблички и останется с десяток предложений. Тоже по сути бесполезных. Если уж совсем плохо с английским - пользуйтесь ru-manpages
predpremi
Я всегда начинаю отладку любого сбоя в своих проектах именно с логов, это экономит кучу времени.