Журналирование ошибок и предупреждений

Можно использовать два интерфейса в OS X для журналирования сообщений: ASL и Системный журнал. Можно также использовать много высокоуровневых подходов такой как NSLog. Однако, потому что большинство демонов не соединяется против Основы или Набора Приложения, низкоуровневый APIs является часто более надлежащим.

Для программного обеспечения, определенного для OS X, необходимо использовать интерфейс ASL, потому что это обеспечивает больше функциональности. API Системного журнала является обычно используемым журналированием API на UNIX и системах Linux, таким образом, необходимо рассмотреть использование его при записи межплатформенного программного обеспечения.

Структура обменивается сообщениями с ключами и хэш-тегами

Исторически, сообщения журнала состояли из текстового сообщения, сопровождаемого информацией такой как, куда сообщение прибыло из, насколько важный это было, и когда это было зарегистрировано. API ASL структурирует все сообщение как ключи и значения. Существует много стандартных ключей, перечисленных в /usr/include/asl.h, но можно также создать собственные ключи. Для предотвращения ключевых коллизий необходимо назвать ключи с помощью обратного стиля DNS. Например, com.example.myCustomKey.

Вы также призваны включать хэш-теги в свои сообщения журнала, независимо от того, что API Вы используете. Хэш-тег составлен из хеша (#) символ, сопровождаемый по крайней мере четырьмя непробельными символами, завершенными пробелом или концом сообщения. Хэш-теги могут не начаться с числа. Кроме того, любой пользовательский ключ ASL, начинающийся с хеша, обрабатывается как хэш-тег. Консольное приложение и журналирование APIs понимают хэш-теги на OS X v10.6 и позже. Они не вмешиваются в нормальное вхождение в систему предыдущих версий OS X, потому что они - просто часть текста сообщения.

Некоторые предложенные хэш-теги:

Хэш-тег

Значение

#System

Сообщение в контексте системного процесса.

#User

Сообщение в контексте пользовательского процесса.

#Developer

Сообщение в контексте разработки программного обеспечения. Например, осуждаемый APIs и сообщения отладки.

#Attention

Сообщение, которое должно быть исследовано системным администратором, потому что это может быть знак большей проблемы. Например, ошибки от контроллера жесткого диска, обычно происходящие, когда диск собирается перестать работать.

#Critical

Сообщение в контексте критического события или критического отказа.

#Error

Сообщение, которое является некритической ошибкой.

#Comment

Сообщение, которое является комментарием.

#Marker

Сообщение, отмечающее изменение для деления сообщений вокруг этого в тех прежде и тех после изменения.

#Clue

Сообщение, содержащее дополнительные пары ключ/значение с дополнительной информацией, чтобы помочь восстановить контекст.

#Security

Сообщение имело отношение к проблемам безопасности.

#Filesystem

Сообщение, описывающее файловую систему, связало событие.

#Network

Сообщение, описывающее связанное с сетью событие.

#Hardware

Сообщение, описывающее связанное с аппаратными средствами событие.

Следующие сообщения журнала иллюстрируют использование хэш-тегов.

 
The volume "Macintosh HD" is almost full. #System #Critical #Filesystem
 
Reloading configuration files. #Marker
 
Too many failed logins from user "Mouse". Possible brute force attack? #Attention #Security #Network
 
Startup items are deprecated. Use a launchd job instead. #Developer
 
While organizing orchestra, expected cowbell but found drums. #Comment #Developer

Установите уровень журнала

Системное журналирование поддержек регистратора на многих приоритетных уровнях, как является традиционным в Основанных на Unix и подобных Unix системах. Приоритетные уровни и предложенное использование для этих уровней:

Уровень журнала

Предложенное использование

Чрезвычайная ситуация (уровень 0)

Самый высокий приоритет, обычно резервируемый для катастрофических отказов и уведомлений перезагрузки.

Предупреждение (уровень 1)

Серьезный отказ в ключевой системе.

Критически важный (уровень 2)

Отказ в ключевой системе.

Ошибка (уровень 3)

Что-то перестало работать.

Предупреждение (уровня 4)

Что-то неправильно и могло бы перестать работать если не исправленный.

Заметьте (уровень 5)

Вещи умеренного интереса для пользователя или администратора.

Информация (уровень 6)

Самый низкий приоритет, который Вы обычно регистрировали бы, и чисто информационный в природе.

Отладка (уровень 7)

Самый низкий приоритет, и обычно не зарегистрированный за исключением сообщений от ядра.

Системный регистратор в OS X определяет, где зарегистрировать сообщения на любом уровне, которому дают приоритет, на основе файла /etc/syslog.conf.

Важно выбрать надлежащий уровень для сообщений журнала. Системный регистратор отбрасывает большинство низкоприоритетных сообщений, в зависимости от указанного средства. Чтобы узнать, как системный регистратор решает который средства и приоритетные уровни для входа в систему данного файла журнала смотрите на файлы /etc/asl.conf и /etc/syslog.conf. По умолчанию сообщения, зарегистрированные в Информации и Отладке, отбрасываются.

Сообщения журнала Используя API ASL

ASL (Системный Регистратор Apple) API очень подобен историческому Системному журналу API, но обеспечивает дополнительную функциональность:

Следующий пример кода показывает, как зарегистрировать простое сообщение об ошибке:

#include <fcntl.h>
#include <asl.h>
#include <unistd.h>
 
main()
{
        aslclient log_client;
        int cause_an_error = open("/fictitious_file", O_RDONLY, 0);
 
        log_client = asl_open("LogIt", "The LogIt Facility", ASL_OPT_STDERR);
        asl_log(log_client, NULL, ASL_LEVEL_EMERG, "This is a silly test: Error %m: %d", 42);
        asl_close(log_client);
}

Полное объяснение функций API ASL выходит за рамки этого документа. Для получения дополнительной информации посмотрите asl страница руководства.

Сообщения журнала Используя системный журнал API

Для использования Системного журнала API сначала вызовите openlog функция. Эта функция связывается с определенным средством. Можно найти список средств в странице руководства для syslog.

Если необходимо записать, что обертка функционирует для syslog функция, используйте функцию vsyslog вместо этого. Эта функция идентична syslog за исключением того, что это берет параметр списка аргумента переменной вместо серии отдельных параметров.

Прежде чем Ваши выходы программы, или когда необходимо указать различное средство, вызывают closelog. Эта функция сбрасывает средство и опции журналирования к настройкам по умолчанию, как будто Вы никогда не вызывали openlog.

Следующий пример кода показывает, как зарегистрировать простое сообщение об ошибке:

#include <fcntl.h>
#include <syslog.h>
 
main()
{
        int cause_an_error = open("/fictitious_file", O_RDONLY, 0); // sets errno to ENOENT
        openlog("LogIt", (LOG_CONS|LOG_PERROR|LOG_PID), LOG_DAEMON);
        syslog(LOG_EMERG, "This is a silly test: Error %m: %d", 42);
        closelog();
}

Флаги передали openlog влияйте на поведение syslog функция следующим образом:

Эти и другие флаги описаны более подробно в syslog страница руководства.

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

Таким образом пример кода выше распечатывает следующее сообщение к стандартному выводу:

LogIt[165]: This is a silly test: Error No such file or directory: 42

Затем пример кода говорит системному регистратору регистрировать то сообщение. В результате принятие Вас не изменилось /etc/syslog.conf, системный регистратор широковещательно передает это сообщение всем пользователям:

Broadcast Message from user@My-Machine-Name.mycompany.com
        (no tty) at 13:28 PDT...
 
Jul 24 13:28:46 My-Machine-Name LogIt[601]: This is a silly test: Error No such file or directory: 42

В этом примере процесс ID был 601, и имя процесса было LogIt.

Для дополнительного управления тем, что регистрируется, можно использовать функцию setlogmask быстро включить или отключить журналирование на различных уровнях. Например, следующий код отключает журналирование любых сообщений ниже LOG_EMERG уровень (который является один выше, чем LOG_ALERT уровень):

setlogmask(LOG_UPTO(LOG_ALERT));

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

Сообщения Отфильтрованы

Журналирование APIs фильтрует сообщения журнала в трех точках:

Функции в Системном журнале API консультируются с фильтром процесса для решения который сообщения передать syslogd и который обменивается сообщениями для отбрасывания. Фильтр по умолчанию передает все сообщения. Используйте setlogmask(3) Mac OS X Developer Tools Manual Page функционируйте для устанавливания фильтра.

Функции в API ASL консультируются, фильтр клиента ASL передал им. У каждого клиента может быть различное значение, что означает, что возможно иметь многократные фильтры в том же процессе, несмотря на то, что редкий. Фильтр по умолчанию отбрасывает отладку - и сообщения информационного уровня. Используйте asl_set_filter(3) Mac OS X Developer Tools Manual Page функционируйте для устанавливания фильтра.

Существует два уровня, на которых можно переопределить фильтры — глобальную переменную и на клиент — использование syslog команда. Оба механизма переопределения прочь по умолчанию. Переопределение глобального фильтра заменяет фильтр для всей системы с той, которую Вы обеспечиваете. Переопределение замен на клиент фильтр для определенного клиента регистратора. Если оба переопределения имеют силу, фильтры на клиент заменяют глобальный фильтр для своих клиентов.

syslogd сервер получает форму сообщений различные источники через многие различные каналы передачи. Это обрабатывает каждое сообщение и может принять много мер, включая сохранение сообщений в одном или более файлах или базах данных, передача сообщений к другим серверам по сети, отправка уведомлений, и т.д.

Существует два основных модуля обработки. Модуль BSD читает /etc/syslog.conf файл и соблюдает правила, которые он находит там. Правила в том файле имеют две части: селектор и действие. Селектор составлен из имен средства сообщения и уровней журнала. Когда уровень средства и/или журнала сообщения соответствует спецификацию селектора, модуль выполняет связанное действие. Как правило, действие должно отформатировать сообщение и записать его в файл журнала.

Второй выходной модуль, модуль ASL, выполняет очень подобную сортировку и фильтрацию функции. Правила для этого модуля найдены в/etc/asl.conf. Этот конфигурационный файл более общего назначения, чем syslog.conf файл. Это позволяет администратору устанавливать различные параметры для управления функциями syslogd сервер. Это также обычно содержит соответствие правил и действий. Когда сообщение соответствует одно из этих правил, модуль выполняет связанное действие. Многие из этих действий указывают, что сообщение должно быть сохранено в базе данных ASL.

Следующий листинг кода показывает некоторые ASL-правила-стиля в качестве примера с комментариями, объясняющими их:

# Store everything from emergency to notice.
# This means messages with debug and info log
# level are not saved in the database.
? [<= Level notice] store
 
# All messages from the kernel (PID 0) and launchd
# (PID 1) are stored, no matter what log level.
? [<= PID 1] store
 
# Likewise, all messages from the mail, ftp, local0,
# and local1 facilities are stored.
? [= Facility mail] store
? [= Facility ftp] store
? [= Facility local0] store
? [= Facility local1] store
 
# All non-debug messages from the lpr facility
# are stored.
? [<= Level info] [= Facility lpr] store
 
# All messages from the internal facility are
# ignored, regardless of their log level.
? [= Facility internal] ignore

Просмотрите и ищите сообщения журнала

Используйте Консольное приложение (найденный в /Applications/Utilities) просмотреть сообщения журнала от GUI, или syslog команда, чтобы просмотреть и искать сообщения журнала из командной строки.

Используйте asl API для поиска сообщений журнала программно. Для получения дополнительной информации посмотрите asl_search страница руководства.

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

Обработайте свои сообщения журнала как потенциально бывшую обращенным к клиенту часть Вашего приложения, не как просто внутреннее средство отладки. Следуйте за хорошими методами журналирования для создания журналов максимально полезными:

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

Журналирование чрезмерно делает файлы журнала намного тяжелее для использования и уменьшает значение журналов пользователю (кто не может легко найти, что важные сообщения журнала), Вам (кто не может легко использовать сообщения журнала для помощи в отладке), и другим разработчикам (чьи сообщения журнала приложений прокладываются под землей под Вашим).

Необходимо избежать писать собственные файлы журнала. Используя APIs вместо того, чтобы создать Вашу собственную систему журналирования рекомендуемая наиболее успешная практика и обеспечивает несколько преимуществ:

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