Что такое уровни логирования в Syslog и зачем они нужны
Syslog описывает формат системных сообщений в RFC 5424, и severity в нём - числовой код от 0 до 7. Ноль соответствует emerg, семёрка - debug. Уровень выставляет то приложение или демон, которое формирует сообщение, а сервер логирования только читает приоритет из заголовка и раскладывает записи по правилам. Повысить или понизить severity на стороне приёмника нельзя, можно лишь отфильтровать сообщение или перенаправить его в другой файл.
Ценность шкалы в том, что она даёт единый язык для фильтрации и маршрутизации. Одна строка конфига отправляет все ошибки в отдельный файл, оставляет отладку на хосте и пересылает предупреждения на центральный сервер. Без уровней пришлось бы разбирать текст сообщений регулярками, а формулировки меняются между версиями сервисов. Фильтр по числовому коду стабилен и не зависит от языка, на котором написано приложение.
Уровни закрывают четыре прикладные задачи: разделение файлов и ротации, алертинг по критичным событиям, экономия диска и сетевого трафика, разграничение доступа к журналам аудита. Как выбрать архитектуру сбора под эти задачи, разбирали в материале про централизованное логирование и выбор архитектуры.
Шкала severity: emerg, alert, crit, err, warning, notice, info, debug
| Код | Уровень | Что означает | Типичный пример |
|---|---|---|---|
| 0 | emerg | Система неработоспособна | Паника ядра, потеря корневой файловой системы |
| 1 | alert | Нужно немедленное вмешательство | Вышел из строя диск в RAID-массиве |
| 2 | crit | Критическое состояние | Приложение не может подключиться к базе данных |
| 3 | err | Ошибка выполнения | Не удалось открыть конфиг, отклонён запрос |
| 4 | warning | Предупреждение | Раздел заполнен на 90%, истекает сертификат |
| 5 | notice | Нормальное, но значимое событие | Перезапуск сервиса, смена пользователя |
| 6 | info | Информационное сообщение | Старт сервиса, успешный вход |
| 7 | debug | Отладочные данные | Пошаговые логи, тексты SQL-запросов |
Ключевая логика, на которой строятся все селекторы: чем меньше число, тем выше приоритет. Фильтр с порогом err пропускает коды 3, 2, 1 и 0. Это не «только ошибки», а «ошибки и всё, что серьёзнее». Разница между соседними уровнями в том, кто должен реагировать: emerg и alert требуют человека немедленно, crit и err означают сбой функции, warning - сигнал к проверке, notice и info фиксируют нормальный ход событий, debug нужен только при разборе инцидента.
По RFC 5424 значения severity обязаны находиться в диапазоне от 0 до 7 включительно, а значения facility - от 0 до 23 включительно. Итоговый приоритет сообщения (PRIVAL) вычисляется как facility × 8 + severity. Именно поэтому числовой код уровня и источник сообщения удобно хранить и сравнивать как единое число.
Facility и severity: как они работают вместе
Facility указывает источник сообщения. Severity отвечает за важность. Вместе они образуют адрес записи, по которому строится маршрутизация.
| Код | Facility | Источник |
|---|---|---|
| 0 | kern | Ядро |
| 1 | user | Пользовательские процессы |
| 2 | Почтовая подсистема | |
| 3 | daemon | Системные демоны |
| 4 | auth | Аутентификация |
| 5 | syslog | Сам демон логирования |
| 6 | lpr | Печать |
| 7 | news | Подсистема сетевых новостей (NNTP) |
| 8 | uucp | UUCP |
| 9 | cron | Планировщик |
| 10 | authpriv | Приватная аутентификация |
| 11 | ftp | FTP |
| 15 | clock daemon | Демон времени |
| 16-23 | local0-local7 | Свободные метки для своих приложений |
В rsyslog пара записывается как selector: authpriv.* или *.err. В syslog-ng facility и уровень задаются отдельными функциями filter: facility(auth, authpriv) и level(warning..emerg). Пример комбинации: логи аутентификации от warning и выше - это authpriv.warning в rsyslog и filter с двумя условиями в syslog-ng.
Диапазон local0-local7 - стандартный способ пометить кастомные приложения, чтобы отделить их от системных демонов. Приложение указывает facility в своей конфигурации или в параметре syslog-драйвера. Контейнеры передают сообщения так же: драйвер syslog в Docker добавляет теги, а уровень задаёт само приложение через собственный log_level. Если приложение пишет всё на info, фильтр по severity на сервере не сможет отделить шум, потому что уровень уже потерян.
Маршрутизация логов по уровням в rsyslog
rsyslog читает основной файл /etc/rsyslog.conf и подключает всё из /etc/rsyslog.d/*.conf. Маршрутизация строится на селекторах вида facility.severity либо на условиях RainerScript. Правила обрабатываются сверху вниз, а директива stop прерывает обработку сообщения.
Селекторы facility.severity: синтаксис и примеры
Селектор состоит из facility, точки и severity. Звёздочка означает «любой». В официальной документации rsyslog facility перечисляется ключевыми словами: auth, authpriv, cron, daemon, kern, lpr, mail, mark, news, security (то же, что auth), syslog, user, uucp и local0-local7. Priority перечисляется в возрастающем порядке: debug, info, notice, warning, warn (то же, что warning), err, error (то же, что err), crit, alert, emerg, panic (то же, что emerg); ключевые слова error, warn и panic считаются устаревшими.
- *.err - все сообщения уровня err и выше, то есть коды 3, 2, 1 и 0;
- authpriv.* - всё, что пишет подсистема аутентификации, независимо от уровня;
- mail.info - почта от info и выше;
- *.=warning - только warning, без crit и err;
- *.!=debug - всё, кроме отладки;
- auth,authpriv.* - два facility в одном селекторе через запятую.
Читайте селектор как «этот уровень и всё, что важнее». Запись *.err не включает info и debug, зато включает crit, alert и emerg, потому что их числовые коды меньше порога. Если нужен строго один уровень, ставьте знак равенства: *.=err даст только ошибки кода 3 и не пропустит сообщение о падении базы данных с уровнем crit. Расширение с «=» перед priority - это синтаксическое расширение rsyslog поверх исходного синтаксиса BSD, оно и позволяет указать единственный уровень вместо «этот и все более важные».
Условия RainerScript: if $syslogseverity и $syslogfacility
Условия гибче селекторов: они позволяют сравнивать числовые коды и текстовые имена источников. Property-based фильтры rsyslog работают со свойствами сообщения, включая $syslogfacility-text, и поддерживают булевы операции.
if $syslogseverity <= 3 then {
action(type="omfile" file="/var/log/errors.log")
}
if $syslogfacility-text == "authpriv" and $syslogseverity <= 4 then {
action(type="omfile" file="/var/log/auth-warnings.log")
}
$syslogseverity хранит числовой код от 0 до 7, поэтому условие <= 3 означает err и выше. $syslogfacility-text отдаёт имя facility, $syslogfacility - его номер. Блоки выполняются сверху вниз, а stop внутри блока не даёт сообщению дойти до следующих правил. Официальный пример такого подхода выглядит так: if $syslogfacility-text == 'local0' and $msg startswith 'DEVNAME' and ($msg contains 'error1' or $msg contains 'error0') then /var/log/somelog.
Готовый конфиг: разделение логов по уровням
# /etc/rsyslog.d/10-levels.conf # Аутентификация: пишем полностью, включая crit и err authpriv.* action(type="omfile" file="/var/log/auth.log") # Критичные события: emerg, alert, crit *.emerg;*.alert;*.crit action(type="omfile" file="/var/log/critical.log") # Только ошибки уровня err *.=err action(type="omfile" file="/var/log/errors.log") # Отладка в отдельный файл *.=debug action(type="omfile" file="/var/log/debug.log") # Общий поток от info и выше *.info action(type="omfile" file="/var/log/messages.log") # Свои приложения на local0 и local1 local0.*;local1.* action(type="omfile" file="/var/log/apps.log")
Без stop сообщение уровня crit попадёт сразу в critical.log и в messages.log. Иногда дублирование удобно, иногда мешает считать события. Чтобы запись обработалась один раз, завершите нужный блок директивой stop:
if $syslogseverity <= 2 then {
action(type="omfile" file="/var/log/critical.log")
stop
}
Проверяйте синтаксис командой rsyslogd -N1 и только после неё перезапускайте сервис. Новые файлы нужно добавить в logrotate, иначе диск заполнится быстрее, чем вы заметите:
/var/log/debug.log {
daily
rotate 3
compress
missingok
notifempty
}
Маршрутизация логов по уровням в syslog-ng
Конфигурация syslog-ng строится из четырёх типов блоков: source, filter, destination и log. Один source можно использовать в нескольких log-блоках, а фильтры комбинируются операторами and, or и not. Файл по умолчанию - /etc/syslog-ng/syslog-ng.conf.
Фильтры level() и facility(): синтаксис и примеры
Фильтр facility() принимает имя facility, числовой код facility или диапазон имён facility. Коды 0-23 предопределены и могут указываться по обычному имени, коды выше 24 являются пользовательскими. Нотация диапазона поддерживается только для именованных значений, а не для числовых.
- filter f_err { level(err..emerg); }; - диапазон от err до emerg;
- filter f_auth { facility(auth, authpriv); }; - два источника через запятую;
- filter f_not_debug { not level(debug); }; - всё, кроме отладки;
- filter f_warning_only { level(warning); }; - строго один уровень.
Функция level() принимает и числовые коды, но имена читаемее и меньше подвержены опечаткам. Диапазон записывается двумя точками: level(err..emerg) охватывает коды 3, 2, 1 и 0. В официальной документации и примерах ArchWiki тот же фильтр по уровню встречается и в форме severity(), например severity(info) или severity(info..warn), а комбинированный фильтр выглядит как level(info..warn) and not facility(cron, auth, authpriv, mail, news). В строке @version указывайте версию своего syslog-ng, иначе демон применит режим совместимости со старым синтаксисом.
Готовый конфиг: разделение логов по уровням
@version: 4.0
@include "scl.conf"
source s_sys {
system();
internal();
};
destination d_auth { file("/var/log/auth.log"); };
destination d_err { file("/var/log/errors.log"); };
destination d_debug { file("/var/log/debug.log"); };
destination d_main { file("/var/log/messages.log"); };
filter f_auth { facility(auth, authpriv); };
filter f_err { level(err..emerg); };
filter f_debug { level(debug); };
log { source(s_sys); filter(f_auth); destination(d_auth); };
log { source(s_sys); filter(f_err); destination(d_err); };
log { source(s_sys); filter(f_debug); destination(d_debug); };
log { source(s_sys); filter { not level(debug); }; destination(d_main); };
Каждый log-блок независим, поэтому одно и то же сообщение легко попадает в несколько файлов. Если нужна взаимоисключающая раскладка, добавляйте в фильтры not: например, filter { not level(debug) and not level(err..emerg); } для общего потока. В примерах документации фильтр отладки часто исключает шумные источники: filter f_debug { not facility(auth, authpriv, news, mail); }.
Отправка логов на удалённый syslog-сервер
Оба демона умеют пересылать сообщения по UDP, TCP и TLS. Для продакшена выбирайте TCP или TLS: UDP не подтверждает доставку и теряет пакеты при перегрузке сети, а для критичных событий и журналов аудита потеря записи означает дыру в расследовании инцидента.
По портам картина такая: syslog использует UDP-порт 514 по умолчанию, а TCP-порт 6514 закреплён как порт по умолчанию для syslog over TLS (RFC 5425, ключевое слово syslog-tls в диапазоне Registered Port Numbers). При этом TCP 514 официально принадлежит службе rsh, и использование его для syslog - широко распространённая практика, а не назначение IANA.
rsyslog: omfwd, TCP/UDP и TLS
Модуль omfwd пересылает логи на удалённые системы по UDP, TCP или TLS. Драйвер потока выбирается параметром StreamDriver.Name: по умолчанию это plain tcp, также доступны «ossl» или «gtls» для TLS-шифрования. Режим драйвера задаётся параметром StreamDriver.Mode.
# TCP с очередью на диске: сообщения переживут перезапуск сервиса
action(
type="omfwd"
target="log.example.com"
port="514"
protocol="tcp"
template="RSYSLOG_ForwardFormat"
queue.type="linkedList"
queue.filename="fwd_queue"
queue.saveOnShutdown="on"
action.resumeRetryCount="-1"
)
# TLS: тот же модуль плюс драйвер потока
action(
type="omfwd"
target="log.example.com"
port="6514"
protocol="tcp"
template="RSYSLOG_ForwardFormat"
streamDriver="gtls"
streamDriverMode="1"
streamDriverAuthMode="x509/name"
streamDriverPermittedPeers="log.example.com"
)
Шаблон RSYSLOG_ForwardFormat сохраняет hostname и timestamp, поэтому на центральном сервере видно, какой хост прислал запись. Очередь на диске защищает от потери при обрыве связи: параметр queue.saveonshutdown="on" сохраняет очередь при остановке демона и читает её после запуска, а без него буфер теряется при перезагрузке. Параметр action.resumeRetryCount="-1" означает бесконечные повторные подключения с интервалом 30 секунд. Как устроена такая очередь и как её проверить, разбирали в материале о настройке сбора логов и отправке на удалённый сервер.
syslog-ng: network() и syslog()
destination d_remote {
network("log.example.com" port(514) transport("tcp"));
};
destination d_remote_tls {
syslog("log.example.com" port(6514) transport("tls")
tls(peer-verify(required-trusted) ca-dir("/etc/ssl/certs")));
};
log { source(s_sys); filter { level(warning..emerg); }; destination(d_remote); };
log { source(s_sys); filter { facility(authpriv); }; destination(d_remote_tls); };
Драйвер syslog() рассчитан на RFC 5424 и умеет то, чего нет у универсального network(): строгий формат, метку времени с часовым поясом, работу с TLS и взаимную проверку сертификатов. Фильтр по уровню ставьте в log-блоке перед destination, тогда на удалённый сервер уйдёт только нужный поток.
Что отправлять на удалённый сервер, а что оставить локально
Рабочая схема: на центральный сервер уходят warning и выше, а info и debug остаются на хосте или включаются точечно. Это снижает трафик и нагрузку на коллектор в разы, потому что основной объём записей даёт именно информационный поток.
Исключение одно и оно важное: authpriv централизуйте целиком, без ограничения по уровню. Локальные журналы аутентификации исчезают вместе с компрометированным хостом, а записи о неудачных входах нужны именно тогда, когда машина уже под контролем атакующего. Схему защищённой передачи таких журналов с TLS описывали в руководстве по сбору логов аудита через rsyslog и auditd.
Типичные ошибки при настройке уровней и фильтров
Ошибка 1: неверное направление шкалы severity
Самая частая причина пропавших инцидентов. Фильтр *.err не исключает crit и emerg, а включает их. Обратная ситуация опаснее: администратор пишет *.=err, ожидая увидеть все проблемы, и теряет сообщения уровня crit о падении базы. Проверка занимает секунду: отправьте тестовое сообщение logger -p user.crit "test crit" и убедитесь, что оно оказалось в нужном файле.
Ошибка 2: debug на проде и переполнение диска
Отладка на продакшене генерирует объём в десятки раз больше обычного потока, ускоряет износ диска и добавляет нагрузку на сервис. Включайте debug точечно: отдельный фильтр, отдельный файл, короткий срок хранения и обязательный logrotate.
if $syslogseverity == 7 then {
action(type="omfile" file="/var/log/debug.log")
stop
}
Директива stop в этом блоке не даёт отладочным записям попасть в общий журнал. Если приложение умеет менять уровень на лету, включайте debug через его собственный log_level, а не через правку конфига демона: так вы отключите шум одним запросом к API.
Ошибка 3: порядок правил и потеря сообщений
В rsyslog правила читаются сверху вниз, и stop прерывает обработку. Ранний stop отрезает сообщение от всех последующих файлов. Ставьте его после тех правил, которые должны увидеть запись, и проверяйте, не перекрывает ли общее правило специфичное.
# Сначала специфичное правило для аутентификации authpriv.* action(type="omfile" file="/var/log/auth.log") # Затем критичное и stop authpriv.crit action(type="omfile" file="/var/log/auth-critical.log")
В syslog-ng блоки независимы, поэтому потеря сообщений случается по другой причине: пересекающиеся фильтры дают дубли, а их отсутствие в каком-то блоке оставляет часть записей без адресата.
Ошибка 4: отсутствие проверки конфига перед перезапуском
Перезапуск с ошибкой в конфиге оставит хост без логирования до ручного вмешательства. Проверяйте синтаксис до применения и держите резервную копию предыдущего файла.
Проверка и отладка настроек логирования
Проверка синтаксиса и перезапуск сервиса
rsyslogd -N1 syslog-ng -s systemctl restart rsyslog systemctl restart syslog-ng
Команда rsyslogd -N1 разбирает конфигурацию и при успехе завершается строкой «rsyslogd: End of config validation run. Bye.». Успешная проверка синтаксиса не гарантирует логическую правильность: демон не знает, что вы ожидали увидеть crit в файле errors.log. После перезапуска смотрите journalctl -u rsyslog -n 50 и состояние сервиса. Подробный разбор системного логирования, journald и сборки дашбордов есть в отдельном руководстве по системному логированию в Linux.
Тестовая отправка и подтверждение доставки
logger -p user.err "test err" logger -p authpriv.warning "test auth" logger -p local0.debug "test debug" tail -f /var/log/errors.log ss -tlnp | grep 514 tcpdump -i any port 514 -A
Порядок действий простой: отправить сообщение нужного уровня, посмотреть локальный файл, затем проверить сеть. На удалённой стороне подтверждайте доставку через tail по целевому файлу. Для порта 6514 с TLS tcpdump покажет только зашифрованные байты, поэтому единственный надёжный способ проверки - запись в файле коллектора.
Отладку самого демона включайте через его параметры, а не через приложения: для rsyslog это директива с уровнем отладки в отдельном конфиге, для syslog-ng - ключ запуска с повышенной детализацией. Так вы не зальёте прод отладочными записями со всех сервисов сразу.
Чек-лист перед применением конфига на проде
- Сохраните копию текущего конфига: cp /etc/rsyslog.conf /etc/rsyslog.conf.bak.
- Проверьте синтаксис: rsyslogd -N1 или syslog-ng -s.
- Убедитесь, что crit и выше не отбрасываются ни одним фильтром и попадают в файл или на удалённый сервер.
- Проверьте, что debug не пишется в общий журнал и лежит в отдельном файле.
- Добавьте все новые файлы в logrotate с ограничением по количеству копий.
- Отправьте тестовые сообщения через logger на каждый уровень и проверьте их место.
- Подтвердите доставку на коллектор: tail по целевому файлу, затем проверка сети через ss и tcpdump.
- Убедитесь, что authpriv уходит централизованно, без ограничения по уровню.
- Проверьте порядок правил: специфичные условия выше, stop после них.
- Заранее решите, где хранить debug и как быстро его удалять, чтобы не переполнить диск.
Если логи возвращаются не с того хоста или теряются при обрыве связи, начните с очереди на диске и состояния канала, а архитектуру конвейера сбора пересмотрите по обзору архитектуры централизованного сбора и анализа логов.