Уровни логирования: таблица соответствия и настройка в syslog, Python logging и systemd-journald | AdminWiki

Уровни логирования: таблица соответствия и настройка в syslog, Python logging и systemd-journald

01 октября 2026 13 мин. чтения
Содержание статьи

Уровень логирования задаёт приоритет сообщения и решает, попадёт ли запись в файл, увидит ли её дежурный и сработает ли алерт. Ошибка, записанная как INFO, теряется в потоке штатных событий. Та же ошибка с уровнем ERROR уходит в мониторинг и поднимает человека.

Дальше разбираем восемь уровней syslog, пять уровней Python logging и восемь приоритетов systemd-journald: где они совпадают, где расходятся и как перенести настройки между стеками. Внутри таблица соответствия, конфиги rsyslog и journald, команды проверки и разбор инцидента, который стоил трёх часов простоя.

Что такое уровни логирования и зачем они нужны в продакшене

Уровень логирования (severity, приоритет) - это числовая метка у каждого сообщения, которая отражает серьёзность события. Syslog задаёт шкалу из восьми значений с кодами от 0 (Emergency) до 7 (Debug). Python logging обходится пятью уровнями с шагом 10: DEBUG (10), INFO (20), WARNING (30), ERROR (40), CRITICAL (50). systemd-journald повторяет шкалу syslog и хранит её в поле PRIORITY.

Механика везде одна: библиотека сравнивает уровень записи с порогом и отбрасывает всё, что не проходит фильтр. В Python порог задают как level=logging.INFO, в syslog и journald - как условие severity <= 4. Разница в порядке сортировки: у Python большее число означает более серьёзное событие, у syslog и journald наоборот.

Без уровней лог превращается в один поток, где сообщение о падении базы тонет среди тысяч строк вида 'connection opened'. С уровнями вы держите в файлах то, что нужно для диагностики, а в алертинге только то, на что команда обязана реагировать.

Как уровни помогают фильтровать шум и не терять критичные события

Польза уровней видна на алертинге. Настройте правило на ERROR и CRITICAL, и дежурный получит уведомление только о сломанных операциях, а не о каждом запросе. DEBUG остаётся в коде и включается точечно, когда нужно разобрать конкретный сбой.

Обратная сторона проявляется при включённом DEBUG в продакшене. В разборе инцидента с переполнением диска (разбор на zrachok.com) автор описал, как детализированный debug-лог для одного сервиса начал генерировать сотни мегабайт логов в минуту.

Уровни управляют двумя вещами сразу: объёмом логов и приоритетом событий. Отключённый DEBUG уменьшает поток, корректно расставленные ERROR и CRITICAL гарантируют, что инцидент не потеряется.

Стандартные уровни логирования: от DEBUG до CRITICAL

В прикладном коде устоялся набор из пяти уровней. Его используют Python logging, log4j и logback, Go-пакет log/slog, большинство библиотек для Node.js и Java. Расширенный набор syslog добавляет к ним NOTICE, ALERT и EMERGENCY.

  • DEBUG: подробности выполнения, значения переменных, тела запросов. В продакшене держите выключенным.
  • INFO: штатные события. Старт и остановка сервиса, успешная транзакция, применённая миграция, вход пользователя.
  • WARNING: работа идёт, но появился риск. Повторная попытка подключения, деградация ответа внешнего API, диск заполнен на 85%.
  • ERROR: операция не выполнена. Не отправлено письмо, отклонён платёж, упал запрос к внешнему сервису.
  • CRITICAL: сервис или данные недоступны. База переведена в read-only, потеряно соединение с брокером, процесс не стартует.

В продакшене включают INFO и выше, DEBUG оставляют для стенда или включают временно. Для высоконагруженных сервисов INFO тоже бывает избыточным: 2000 запросов в секунду и две INFO-строки на запрос дают 4000 записей в секунду, а за сутки это сотни миллионов строк. Если объём мешает, ограничьте набор событий до ключевых бизнес-операций.

DEBUG и INFO: когда детализация помогает, а когда вредит

DEBUG решает узкую задачу: показать, что происходит внутри. Включайте его на одном инстансе, на короткий срок и с понятным условием выключения. Ограничивайте область: пишите только нужный модуль через именованный логгер (logging.getLogger('payment.gateway')) и не отправляйте в лог тела запросов целиком.

INFO фиксирует бизнес-события. Ценность каждой записи проверяется вопросом: если я увижу эту строку, смогу ли понять, что произошло с заказом? Если ответ отрицательный, запись лишняя.

Оценить фактический объём помогают команды:

du -sh /var/log/* | sort -rh | head
df -h
df -i

Смотрите не только на байты, но и на inode: каталоги с большим числом мелких файлов расходуют их быстрее, чем ожидается, и df -i показывает остаток.

WARNING, ERROR, CRITICAL: как не пропустить инцидент

WARNING сигналит о проблеме, которая ещё не сломала работу. Пример из практики: мониторинг срабатывал при заполнении диска на 85%, предупреждения приходили, но правила на скорость роста не было, а алерт, который должен был поймать экспоненциальное заполнение, оказался выключен (как развивался инцидент).

ERROR фиксирует неудачную операцию при живом сервисе, CRITICAL - полный отказ или угрозу данным. Алертинг настраивайте на ERROR и CRITICAL, а WARNING отправляйте в отдельный канал или в дашборд: иначе дежурный привыкнет игнорировать уведомления. Ожидаемые ошибки (неверный пароль, 404 на статике, отменённый заказ) в ERROR не пишите.

Уровни логирования в syslog: соответствие и особенности

RFC 5424 фиксирует восемь уровней серьёзности. Чем меньше код, тем серьёзнее событие.

КодИмяКогда использовать
0emerg (Emergency)Система неработоспособна, нужно немедленное вмешательство
1alert (Alert)Реакция требуется сейчас: отказ диска в массиве, недоступность БД
2crit (Critical)Критическая ошибка, сервис или данные под угрозой
3err (Error)Операция не выполнена
4warning (Warning)Предупреждение, работа продолжается
5notice (Notice)Значимое штатное событие: перезапуск сервиса, смена конфигурации
6info (Informational)Обычные информационные сообщения
7debug (Debug)Отладочная информация

Приоритет сообщения кодируется формулой PRI = facility * 8 + severity, поэтому фильтровать можно и по источнику, и по уровню. Например, при facility = local0 (код 16) и PRI = 134 severity = 6, то есть информационный тип важности (пример расчёта PRI в документации Eltex). rsyslog принимает селекторы по имени (err, warning, debug) и условия по свойствам $syslogseverity и $syslogfacility.

Как настроить фильтрацию по уровням в rsyslog

Разведите сообщения по файлам: ошибки в отдельный журнал, предупреждения в свой, всё остальное в общий.

# /etc/rsyslog.d/10-levels.conf
*.err        /var/log/errors.log
*.=warning   /var/log/warnings.log
*.info       /var/log/app-info.log

Селектор *.err выбирает сообщения уровня err и серьёзнее, *.=warning - только warning, *.info - от info и серьёзнее. Селектор *.debug совпадает с любым уровнем, поэтому его применяют как catch-all. Если нужно точное условие, используйте свойства:

if $syslogseverity <= 3 then /var/log/errors.log
if $syslogseverity == 4 then /var/log/warnings.log

Порядок правил важен: директива & stop останавливает дальнейший разбор сообщения. Проверьте конфигурацию и отправьте тестовое сообщение:

rsyslogd -N1
logger -p user.err 'Test error message'
tail -n 5 /var/log/errors.log

DEBUG в проде отключайте на уровне приложения, а не только в конфиге rsyslog: запись всё равно сформируется и уйдёт в сокет, а фильтр лишь уберёт её из файла. Схему сбора, ротацию и отправку логов на центральный сервер разбираем в статье про системное логирование в Linux: journald, rsyslog и Grafana.

Уровни логирования в Python logging: настройка и соответствие

Числовые значения уровней позволяют сравнивать их напрямую: DEBUG (10), INFO (20), WARNING (30), ERROR (40), CRITICAL (50). Запись отбрасывается, если её уровень ниже порога логгера или порога хендлера.

import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s %(name)s %(message)s',
)
log = logging.getLogger('billing')

log.debug('payload: %s', payload)
log.info('invoice %s created', invoice_id)
log.warning('retry %s for gateway', attempt)
log.error('payment failed for order %s', order_id)
log.critical('database is read-only, service stopped')

Порог задаётся отдельно у логгера и у хендлера. Если у логгера стоит DEBUG, а у хендлера WARNING, в вывод попадут только warning и серьёзнее. Так удобно держать один хендлер для файла с полной детализацией и второй для stderr с высоким порогом.

На производительность влияет не только уровень, но и способ форматирования строк. Приёмы с ленивым форматированием, асинхронными хендлерами и буферизацией разобраны в статье как сохранить скорость приложения при логировании в Python.

Как сопоставить уровни Python logging и syslog

Стандартный SysLogHandler умеет отправлять записи в syslog, но точное сопоставление уровней Python и приоритетов syslog зависит от версии и конфигурации обработчика. В документации Python, доступной в рамках этого разбора, таблица соответствия CRITICAL → LOG_CRIT, ERROR → LOG_ERR, WARNING → LOG_WARNING, INFO → LOG_INFO, DEBUG → LOG_DEBUG не подтверждена, поэтому перед продакшеном проверьте фактический приоритет на своей версии Python: отправьте тестовое сообщение каждого уровня и посмотрите, с каким PRIORITY оно дошло до journald или файла rsyslog.

from logging.handlers import SysLogHandler

handler = SysLogHandler(address='/dev/log', facility=SysLogHandler.LOG_DAEMON)
handler.setFormatter(logging.Formatter('%(name)s: %(levelname)s %(message)s'))
log.addHandler(handler)

По умолчанию SysLogHandler использует facility LOG_USER, для демонов указывайте LOG_DAEMON. Проверить доставку можно командой journalctl -t billing или через /var/log/syslog, если в системе работает rsyslog. Уровни NOTICE, ALERT и EMERGENCY в стандартной таблице Python отсутствуют: чтобы отправить их в syslog, задайте кастомный уровень числом больше 50 или формируйте приоритет явно. Настройка логгеров, хендлеров и форматов подробно разобрана в статье про настройку логирования в Python: от основ до промышленного развёртывания.

Уровни логирования в systemd-journald: приоритеты и фильтрация

journald использует ту же шкалу, что syslog: 0 emerg, 1 alert, 2 crit, 3 err, 4 warning, 5 notice, 6 info, 7 debug. Уровень хранится в поле PRIORITY, и по нему работает фильтр journalctl -p.

Практические команды journalctl для фильтрации по уровням

journalctl -p err -b
journalctl -p warning -f
journalctl -p crit..alert -b
journalctl -u nginx -p err --since '1 hour ago'
journalctl --disk-usage

Диапазоны записываются через две точки: -p crit..alert показывает сообщения от crit до alert включительно. Проверка фильтра занимает две команды:

logger -p user.err 'Test error message'
journalctl -p err -n 1

Ограничьте объём журнала, иначе journald займёт раздел целиком. Минимальный набор параметров в /etc/systemd/journald.conf:

[Journal]
Storage=persistent
SystemMaxUse=2G
SystemMaxFileSize=200M
SystemMaxFiles=10
RateLimitIntervalSec=30s
RateLimitBurst=10000

После правки выполните systemctl restart systemd-journald. Параметры RateLimitIntervalSec и RateLimitBurst задают порог подавления потока: при его превышении journald отбрасывает сообщения и помечает это записью о числе подавленных строк. Эти параметры настраиваются в /etc/systemd/journald.conf и связанных drop-in файлах, а в man-странице journald.conf(5) они присутствуют наряду с настройками, добавленными в версиях 190 и 246 (описание параметров в journald.conf, man-страница journald.conf(5)). Конкретные значения по умолчанию и их изменения между версиями systemd в доступных источниках не подтверждены, поэтому сверьтесь с man journald.conf на своих машинах. Фильтры по сервису, времени и PID, а также постоянное хранение и ротацию разбираем в статье про journalctl: фильтры, хранение и ротация логов.

Таблица соответствия уровней логирования в популярных системах

Сводная таблица для переноса настроек между syslog, Python logging и systemd-journald.

syslog (код, имя)Python loggingsystemd-journaldТиповое применение
0 emergCRITICAL (50)0 emergСистема или данные недоступны
1 alertнет прямого аналога, ближайший CRITICAL (50)1 alertРеакция нужна немедленно
2 critCRITICAL (50)2 critКритическая ошибка
3 errERROR (40)3 errОперация не выполнена
4 warningWARNING (30)4 warningПотенциальная проблема
5 noticeнет прямого аналога, ближайший INFO (20)5 noticeЗначимое штатное событие
6 infoINFO (20)6 infoИнформационное сообщение
7 debugDEBUG (10)7 debugОтладочные детали

Что учитывать при переносе: Python не различает notice, alert и emerg, поэтому сообщение с уровнем CRITICAL при отправке через SysLogHandler получит приоритет crit (2), а не alert или emerg. Обратное преобразование тоже неполное: прочитанный из syslog notice в Python отобразится как INFO. Если в вашем стеке важно различать эти события, заведите набор констант и маппинг в коде, а в конфиге отправки укажите приоритет явно.

Как выбрать уровень для конкретного сообщения: практические правила

Проходите четыре вопроса по порядку и останавливайтесь на первом подходящем.

  1. Сервис или данные недоступны, восстановления нет? CRITICAL.
  2. Операция не выполнена, но сервис работает? ERROR.
  3. Работа идёт, но появился риск или сработал защитный механизм? WARNING.
  4. Событие штатное и его стоит зафиксировать? INFO.

Пятый вопрос про детали: нужна ли запись, чтобы понять порядок вызовов или содержимое данных? Тогда DEBUG.

Уровень отражает последствия, а не источник сообщения. Таймаут внешнего API в пользовательском запросе и тот же таймаут в фоновом воркере с ретраями имеют разную цену, и уровень у них может отличаться.

Примеры выбора уровня для типовых событий в продакшене

  • Запуск и остановка сервиса - INFO.
  • Успешная транзакция или созданный заказ - INFO.
  • Смена конфигурации - NOTICE в syslog, INFO в Python.
  • Повторная попытка подключения к базе - WARNING.
  • Ответ внешнего API медленнее обычного - WARNING.
  • Диск заполнен на 85% - WARNING.
  • Таймаут внешнего API, запрос пользователя не выполнен - ERROR.
  • Не удалось записать файл или отправить письмо - ERROR.
  • База переведена в read-only, сервис не принимает запросы - CRITICAL.
  • Подозрительная активность (серия неудачных входов, обращение к закрытому пути) - WARNING, если действие заблокировано, и ERROR, если нет.

Ожидаемые ошибки не поднимайте до ERROR: неверный пароль пользователя, 404 на статике, отменённый заказ - это INFO или WARNING плюс метрика. Иначе алертинг теряет сигнал. Если сомневаетесь между INFO и WARNING, выбирайте WARNING. Если между ERROR и CRITICAL, проверьте, есть ли у сервиса запасной путь: пока запросы обслуживает хотя бы один инстанс, это ERROR. Критерии того, что вообще стоит записывать в лог, разобраны в статье что логировать, а что нет: критерии для мониторинга.

Типичные ошибки при настройке уровней и как их избежать

Пять ошибок закрывают большинство проблем с логированием в продакшене. Каждая приводит либо к потере события, либо к переполнению диска.

Кейс: как debug-логи и отсутствие алертов привели к трёхчасовому простою

Разбор инцидента (полный разбор инцидента) показывает цепочку целиком. Детализированный debug-лог включили для одного сервиса в проде. Накопление логов пошло со скоростью 300-400 МБ в минуту, за 15 минут это дало до 6 ГБ.

Диск на 500 ГБ был заполнен на 460 ГБ, и потерянных 40 ГБ хватило, чтобы WAL Postgres перестал писать и СУБД перевела базу в режим read-only. Сервис обработки писем и платежей упал. Мониторинг срабатывал при 85% заполнения, но правила на скорость роста не было, а алерт на экспоненциальное заполнение был выключен.

Хронология: 11:10 предупреждение о 85%, 11:40 - 95%, 12:05 диск заполнен почти полностью, 12:12 база ушла в read-only. Около 14:30 инженер откатил часть логов вручную, к 15:00 сервис вернулся в работу. Итог: примерно 3 часа простоя, 1.2k задач в очередях на отправку писем и около 300 платёжных транзакций в состоянии retry.

После инцидента добавили алерт на скорость заполнения: рост за 15 минут и порог более 1 ГБ за 15 минут. Ротацию тоже пересмотрели: logrotate был настроен только по размеру, без ограничения суммарного объёма и числа файлов, а медленное сжатие оставляло временные .gz.tmp файлы, которые занимали место.

  1. DEBUG в продакшене без ограничения объёма. Поток растёт до сотен мегабайт в минуту. Держите INFO как минимальный уровень, а DEBUG включайте на одном инстансе и на короткий срок.
  2. ERROR для ожидаемых ошибок. Неверный пароль, 404 на статике, отменённый заказ зашумляют алертинг. Переведите их в WARNING или INFO.
  3. Нет алерта на скорость роста. Порог по абсолютному значению (85% диска) не ловит экспоненту. Добавьте правило вида 'более 1 ГБ за 15 минут'.
  4. Ротация только по размеру. Без rotate и лимита на общий объём архивы копятся, а сжатие оставляет .gz.tmp. Задайте maxsize, rotate и delaycompress.
  5. journald без лимитов. Журнал растёт и забивает раздел. Установите SystemMaxUse и SystemMaxFileSize.

Как выстроить единые правила логирования для команды

Политика логирования занимает одну-две страницы и отвечает на пять вопросов: какой минимальный уровень в продакшене, какие события относятся к каждому уровню, в каком формате пишутся логи, какие данные запрещено логировать, как включается DEBUG.

Формат: структурированный вывод (JSON или logfmt) с обязательными полями timestamp, level, service, message и trace_id. Одинаковые поля позволяют фильтровать по уровню в Loki, Elasticsearch или Grafana без регулярных выражений. Запрет на пароли, токены, номера карт и персональные данные закрепите отдельным пунктом и вынесите в чек-лист код-ревью.

Правило по умолчанию для новых сервисов: INFO на старте, ERROR для сломанных операций, CRITICAL для отказов. Уровень DEBUG включается переменной окружения или конфигом, а не правкой кода.

Чек-лист для настройки уровней логирования в продакшене

  1. Убедитесь, что DEBUG отключён и включается только по флагу.
  2. Оцените скорость роста логов: du -sh /var/log и приращение за сутки.
  3. Настройте алертинг на ERROR и CRITICAL.
  4. Добавьте алерт на скорость роста, например больше 1 ГБ за 15 минут.
  5. Проверьте свободное место и inode: df -h и df -i.
  6. Проверьте ротацию: maxsize, rotate по числу файлов, сжатие с delaycompress.
  7. Для journald задайте SystemMaxUse и SystemMaxFileSize.
  8. Проверьте фильтры: journalctl -p err -b и содержимое errors.log.
  9. Отправьте тестовые сообщения всех уровней через logger и убедитесь, что они попали в нужные файлы и каналы.
  10. Проведите ревью нового сервиса: уровни, формат, обязательные поля, отсутствие секретов.

Проверка и отладка настроек логирования: команды и примеры

du -sh /var/log/* | sort -rh | head
df -h
df -i
find /var/log -type f -mtime +30 -printf '%s %p\n' | sort -rn | head
journalctl --disk-usage
rsyslogd -N1
logrotate -d /etc/logrotate.conf

logrotate -d показывает, что утилита сделает с каждым файлом, и не трогает сами логи. Пример конфигурации с ограничением объёма и числа файлов:

/var/log/app/*.log {
    daily
    rotate 14
    maxsize 500M
    compress
    delaycompress
    missingok
    notifempty
}

rotate 14 ограничивает число архивных файлов, maxsize запускает ротацию раньше суточного срока при превышении размера, delaycompress откладывает сжатие на один цикл и снижает нагрузку на диск. Для Python проверьте, что уровень действительно отсекает записи: временно поставьте DEBUG у логгера, посмотрите объём за минуту, верните INFO и сравните.

Заключение: ключевые принципы работы с уровнями логирования

  1. Уровень отражает серьёзность последствий, а не источник сообщения.
  2. В продакшене минимальный уровень - INFO, DEBUG включается точечно и временно.
  3. Алертинг строят на ERROR и CRITICAL плюс на скорости роста логов.
  4. Таблица соответствия из этой статьи переносит настройки между syslog, Python и journald за пару минут.
  5. Единое правило в команде дешевле любого инцидента: формат, уровни и запрет на секреты фиксируются в документе и проверяются на код-ревью.

Начните с двух действий: проверьте скорость роста логов командой du -sh /var/log/* | sort -rh | head и посмотрите, есть ли у вас алерт на рост заполнения диска. Инцидент из разбора стоил трёх часов простоя и сотен задач в очередях, а начинался с одной включённой строки debug-лога.

Поделиться: