Большинство категорий из табл. 37.1 входят в стандарт SUSv3 (о чем указано в столбце SUSv3). Исключением являются константы LOG_AUTHPRIV и LOG_FTP (которые встречаются в некоторых UNIX-системах), а также LOG_SYSLOG (которая поддерживается в большинстве реализаций). Значение LOG_AUTHPRIV может пригодиться в ситуациях, когда сообщения, содержащие пароли или другую деликатную информацию, записывают не в LOG_AUTH, а в какое-то другое место.

Категория LOG_KERN применяется для сообщений ядра. Сообщения этого вида не могут быть сгенерированы программами, работающими в пользовательском режиме. Константа LOG_KERN имеет значение 0. В сочетании с вызовом syslog() она приводит к задействованию «уровня по умолчанию».

Таблица 37.1. Значения категорий для openlog() и аргумент priority для syslog()

Значение — Описание — SUSv3

LOG_AUTH — Сообщения, связанные с безопасностью и авторизацией (например, su) — *

LOG_AUTHPRIV — Сообщения, связанные с частной безопасностью и авторизацией —

LOG_CRON — Сообщения, посланные демонами cron и at — *

LOG_DAEMON — Сообщения от других системных демонов — *

LOG_FTP — Сообщения от демона ftp (ftpd) —

LOG_KERN — Сообщения ядра (не могут быть сгенерированы пользовательским процессом) — *

LOG_LOCAL0 — Зарезервировано для локального использования (то же самое для значений с LOG_LOCAL1 по LOG_LOCAL7) — *

LOG_LPR — Сообщения от системы построчной печати (lpr, lpd, lpc) — *

LOG_MAIL — Сообщения от почтовой системы — *

LOG_NEWS — Сообщения, связанные с новостной сетью Usenet — *

LOG_SYSLOG — Внутренние сообщения от демона syslogd —

LOG_USER — Сообщения, сгенерированные пользовательскими процессами (используется по умолчанию) — *

LOG_UUCP — Сообщения от системы UUCP — *

Запись сообщения в журнал

Для записи сообщения в журнал нужно вызвать функцию syslog().

#include

void syslog(int priority, const char *format…);

Аргумент priority создается в связке со значениями facility и level, к которым применяется оператор побитового ИЛИ. facility обозначает основную категорию приложения, которое записывает сообщение, и может принимать одно из значений, перечисленных в табл. 37.1. Если этот аргумент опустить, по умолчанию будет использоваться значение, указанное во время предыдущего вызова openlog(), или LOG_USER, если этот вызов не был выполнен. Аргумент level обозначает степень важности сообщения и может принимать одно из значений, перечисленных в табл. 37.2 (все они входят в стандарт SUSv3).

Таблица 37.2. Значения level аргумента priority для вызова syslog() (от самого высокого до самого низкого уровня)

Значение — Описание

LOG_EMERG — Аварийная ситуация или критическая ошибка (отказ системы)

LOG_ALERT — Ситуация, требующая принятия немедленных мер (например, повреждение системной базы данных)

LOG_CRIT — Критическая ситуация (например, ошибка на дисковом устройстве)

LOG_ERR — Ошибка общего характера

LOG_WARNING — Сообщение с предупреждением

LOG_NOTICE — Штатная ситуация, которая может потребовать особого обращения

LOG_INFO — Информационное сообщение

LOG_DEBUG — Отладочное сообщение

Оставшиеся аргументы вызова syslog() представляют собой строку форматирования и сопутствующие параметры в стиле функции printf(). Отличие от printf() заключается в том, что строка форматирования может не содержать в конце символ перевода строки. В этой строке также можно указать двухсимвольную последовательность %m, вместо которой подставляется ошибка, соответствующая текущему значению errno (то есть эквивалент вызова strerror(errno)).

Следующий код демонстрирует использование функций openlog() и syslog():

openlog(argv[0], LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_LOCALO);

syslog(LOG_ERROR, "Bad argument: %s", argv[1]);

syslog(LOG_USER | LOG_INFO, "Exiting");

Поскольку категория (facility) не была указана при первом вызове syslog(), по умолчанию используется значение из вызова openlog() (LOG_LOCAL0). Во втором вызове syslog() явно заданная константа LOG_USER переопределяет значение по умолчанию, установленное вызовом openlog().

Для добавления записей в системный журнал можно воспользоваться утилитой командной строки logger(1). Эта программа позволяет указать для записываемых сообщений значения level (приоритет) и ident (метка). Больше подробностей содержится на справочной странице logger(1). Команда logger присутствует в большинстве реализаций UNIX, хотя в стандарте SUSv3 она упоминается лишь вскользь.

Нельзя передавать вызову syslog() произвольные строки, переданные пользователем:

syslog(priority, user_supplied_string);

Проблема этого кода состоит в том, что он делает приложение уязвимым к так называемым атакам строки форматирования. Если строка, которую предоставил пользователь, содержит спецификаторы форматирования (например, %s), результаты могут быть непредсказуемыми и потенциально опасными (эти замечания относятся и к применению стандартной функции printf()). Вызов, представленный выше, нужно переписать следующим образом:

Перейти на страницу:

Похожие книги