Страница 147 из 399
Более новые реализации отключают возможность создания сокета UDP, если она не задана администратором, поскольку если позволить кому угодно отправлять дейтаграммы UDP на этот порт (возможно, заполняя приемный буфер его сокета), это может привести к тому, что законные сообщения не будут получены (атака типа отказ в обслуживании) или переполнится файловая система из-за неограниченного роста журналов.
Между реализациями демона syslogd существуют различия. Например, доменные сокеты Unix используются Беркли-реализациями, а реализации System V используют потоковый драйвер (streams log driver). Различные реализации, происходящие от Беркли, используют для доменных сокетов Unix различные полные имена. Мы можем игнорировать все эти тонкости, если используем функцию syslog.
Мы можем отправлять сообщения о событиях для записи в журнал (log messages) демону syslogd из наших демонов, создав дейтаграммный доменный сокет Unix и указывая при отправке полное имя, с которым связан демон, но более простым интерфейсом является функция syslog, которую мы описываем в следующем разделе. В качестве альтернативы мы можем создать сокет UDP и отправлять наши сообщения на адрес закольцовки и порт 514.
13.3. Функция syslog
Поскольку у демона нет управляющего терминала, он не может просто вызвать функцию fprintf для вывода в стандартный поток сообщений об ошибках (stderr). Обычная техника записи в журнал сообщений для демона — это вызов функции syslog.
#include <syslog.h>
void syslog(int <i>priority</i>, const char *<i>message</i>, ...);
Хотя эта функция изначально разрабатывалась для BSD, в настоящее время она предоставляется большинством производителей систем Unix. Описание syslog в POSIX соответствует тому, что мы пишем здесь. RFC 3164 содержит документацию, касающуюся протокола syslog BSD.
Аргумент priority — это комбинация аргументов level и facility, которые мы показываем в табл. 13.1 и 13.2. Дополнительные сведения об этом аргументе можно найти в RFC 3164. Аргумент message аналогичен строке формата функции printf с добавлением спецификации %m, которая заменяется сообщением об ошибке, соответствующим текущему значению переменной errno. Символ перевода строки может появиться в конце строки message, но он не является обязательным.
Сообщения для журнала имеют значение level (уровень) от 0 до 7, что мы показываем в табл. 13.1. Это упорядоченные значения. Если отправитель не задает значение level, используется значение по умолчанию LOG_NOTICE.
Таблица 13.1. Аргумент level журнальных сообщений