Технологические интерфейсы
Функции и утилиты для работы с системным журналом
Под системным журналом в стандарте POSIX-2001 понимается некое средство хранения и/или отображения данных, предназначенных для изучения системным администратором . Средство это, разумеется, зависит от реализации. Это может быть обычный локальный файл (например, /var/log/messages ), список рассылки, удаленный сетевой ресурс и т.д.
Для работы с системным журналом стандарт предлагает функции записи сообщений ( syslog() ), установки фильтра ( маски журналируемых сообщений, setlogmask() ) и других параметров журналирования ( openlog() ) и, наконец, завершения работы с системным журналом ( closelog() ) (см. листинг 9.1). Средства чтения системного журнала, как и все, что связано с администрированием, в стандарт POSIX-2001 не входят.
#include <syslog.h> void syslog (int priority, const char *message, ... /* аргументы */); int setlogmask (int maskpri); void openlog (const char *ident, int logopt, int facility); void closelog (void);Листинг 9.1. Описание функций для работы с системным журналом.
Сообщение, которое помещает в системный журнал функция syslog(), включает заголовок и тело.
В заголовок входит по крайней мере временной штамп и идентифицирующая цепочка символов .
Тело сообщения формируется из аргумента message, играющего роль формата, и следующих за ним необязательных аргументов аналогично тому, как если бы использовалась функция printf(), только допускается один дополнительный спецификатор преобразования – %m, не требующий аргумента и осуществляющий вывод текущего значения переменной errno .
Значение аргумента priority формируется как побитное ИЛИ флагов двух видов, задающих, соответственно, уровень серьезности и источник сообщения.
Уровень серьезности может принимать следующие значения.
LOG_EMERG
Катастрофическая ситуация.
LOG_ALERT
Ситуация, требующая немедленного вмешательства (например, повреждение системной базы данных ).
LOG_CRIT
Опасная ситуация (например, ошибки в работе аппаратуры).
LOG_ERR
Сообщение об ошибке.
LOG_WARNING
Предупреждающее сообщение.
LOG_NOTICE
Ситуация, не являющаяся ошибочной, но, возможно, требующая специальных действий.
LOG_INFO
Информационное сообщение.
LOG_DEBUG
Отладочное сообщение.
Из источников сообщений стандартизован только один (естественно, являющийся подразумеваемым) – пользовательский процесс (флаг LOG_USER ). Зарезервированы флаги для системных источников, имена которых говорят сами за себя ( LOG_KERN, LOG_MAIL, LOG_NEWS, LOG_UUCP, LOG_DAEMON, LOG_AUTH, LOG_CRON, LOG_LPR ) и для абстрактных локальных сущностей ( LOG_LOCAL0 – LOG_LOCAL7 ).
Функция setlogmask() в качестве результата возвращает предыдущую и устанавливает новую маску журналируемых сообщений вызывающего процесса. В системный журнал будут помещаться только те сообщения, уровень серьезности которых присутствует в маске, заданной аргументом maskpri. Для формирования этого аргумента по одному уровню серьезности стандартом предусмотрен макрос LOG_MASK ( pri ). Для задания маски, включающей несколько уровней, нужно взять побитное ИЛИ подобных выражений.
Если значение maskpri равно нулю, текущая маска остается неизменной. Подразумевая маска является "полной", она специфицирует журналирование всех событий.
Функция openlog() устанавливает значения атрибутов журналирования вызывающего процесса, влияющие на последующие обращения к syslog(). Аргумент ident задает идентифицирующую цепочку, фигурирующую в заголовках всех сообщений. Аргумент logopt специфицирует опции журналирования. Он формируется как побитное ИЛИ следующих флагов.
LOG_PID
Записывать вместе с сообщением идентификатор процесса.
LOG_CONS
Выдавать сообщение на системную консоль, если его не удается поместить в журнал.
LOG_NDELAY
Немедленно открыть системный журнал (обычно открытие откладывается до записи первого сообщения ).
LOG_ODELAY
Отложить открытие системного журнала до первого вызова syslog() (выбор между немедленным или отложенным открытием способен повлиять на распределение файловых дескрипторов ).
LOG_NOWAIT
Не ждать завершения процессов, которые могли быть порождены в ходе журналирования сообщения. Эту опцию следует использовать в процессах, которые уведомляются о завершении потомков сигналом SIGCHLD.
Аргумент facility устанавливает подразумеваемое значение для источника тех сообщений, где он ( источник ) не указан явным образом.
Функции openlog() и syslog() могут открывать (расходовать) файловые дескрипторы. Функция closelog() закроет их.
Вообще говоря, вызывать openlog() до syslog() и setlogmask() не обязательно.
К рассматриваемой прикладной области можно отнести служебную программу logger:
logger цепочка_символов ...
которая неким неспецифицированным образом сохраняет сообщение, содержащее заданные аргументы – цепочки символов. Предполагается, что со временем это сообщение прочитает системный администратор.
Подобная возможность полезна для выдачи диагностических сообщений неинтерактивными приложениями. Например, программа, запущенная в пакетном режиме, может уведомить системного администратора об отсутствии какого-либо файла:
logger $LOGNAME $(date) : не удалось прочитать файл report.txt
Рассмотрим пример применения функций для работы с системным журналом (см. листинг 9.2).
/* * * * * * * * * * * * * * * * * */ /* Пример использования функций */ /* для работы с системным журналом */ /* * * * * * * * * * * * * * * * * */ #include <stdio.h> #include <syslog.h> int main (void) { int logmask; /* Прежняя маска журналирования */ /* Будем включать в журналируемые сообщения */ /* идентификатор процесса и выдавать их при */ /* возникновении проблем на системную консоль */ openlog ("Intuit syslog test", LOG_PID | LOG_CONS, LOG_USER); /* Пренебрежем предупреждениями и менее серьезными сообщениями */ logmask = setlogmask (LOG_MASK (LOG_EMERG) | LOG_MASK (LOG_ALERT) | LOG_MASK (LOG_CRIT) | LOG_MASK (LOG_ERR)); printf ("Подразумеваемая маска журналирования: %x\n", logmask); /* Поместим сообщение в журнал */ syslog (LOG_ALERT | LOG_USER, "Как читать системный журнал?"); /* Восстановим прежнюю маску журналирования */ (void) setlogmask (logmask); closelog (); return 0; }Листинг 9.2. Пример применения функций для работы с системным журналом.
Результатом работы этой программы может быть строка, показанная на листинге 9.3.
Подразумеваемая маска журналирования: ffЛистинг 9.3. Возможные результаты применения функций для работы с системным журналом.