Журналирование ошибок и предупреждений
Можно использовать два интерфейса в 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, потому что они - просто часть текста сообщения.
Некоторые предложенные хэш-теги:
Хэш-тег | Значение |
---|---|
| Сообщение в контексте системного процесса. |
| Сообщение в контексте пользовательского процесса. |
| Сообщение в контексте разработки программного обеспечения. Например, осуждаемый APIs и сообщения отладки. |
| Сообщение, которое должно быть исследовано системным администратором, потому что это может быть знак большей проблемы. Например, ошибки от контроллера жесткого диска, обычно происходящие, когда диск собирается перестать работать. |
| Сообщение в контексте критического события или критического отказа. |
| Сообщение, которое является некритической ошибкой. |
| Сообщение, которое является комментарием. |
| Сообщение, отмечающее изменение для деления сообщений вокруг этого в тех прежде и тех после изменения. |
| Сообщение, содержащее дополнительные пары ключ/значение с дополнительной информацией, чтобы помочь восстановить контекст. |
| Сообщение имело отношение к проблемам безопасности. |
| Сообщение, описывающее файловую систему, связало событие. |
| Сообщение, описывающее связанное с сетью событие. |
| Сообщение, описывающее связанное с аппаратными средствами событие. |
Следующие сообщения журнала иллюстрируют использование хэш-тегов.
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, но обеспечивает дополнительную функциональность:
Использует текстовую строку для идентификатора средства для более точной фильтрации сообщений журнала. Необходимо использовать имя стиля обратного DNS для средства, такой как
com.example.myproduct
.Обеспечивает функции для запросов файлов журнала.
Безопасно для использования в многопоточной среде, потому что оно обеспечивает функции для получения отдельного коммуникационного дескриптора для каждого потока.
Позволяет файлу быть присоединенным к сообщению журнала. Это - эффективный способ получить обширное состояние или информацию о следе, не загрязняя журналы.
Следующий пример кода показывает, как зарегистрировать простое сообщение об ошибке:
#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
функция следующим образом:
LOG_CONS: Распечатывает сообщение к консоли если
syslogd
демон не работает.LOG_PERROR: В дополнение к нормальному журналированию, также распечатывает сообщение к стандартной погрешности.
Обратите внимание на то, что что-либо распечатанное к стандартной погрешности от a
launchd
задание регистрируется, таким образом с помощью этой опции от alaunchd
задание приводит к сообщениям, зарегистрированным дважды.LOG_PID: Добавляет процесс ID после имени процесса в начале сообщения журнала.
Эти и другие флаги описаны более подробно в 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 фильтрует сообщения журнала в трех точках:
Глобальный фильтр (также названный основным фильтром) применяется ко всем сообщениям журнала от всех средств. По умолчанию это отключено. Для установки его использовать
asl_set_filter(3) Mac OS X Developer Tools Manual Page
(API ASL),setlogmask(3) Mac OS X Developer Tools Manual Page
(системный журнал API), илиsyslog
инструмент командной строки.Фильтр на клиент. По умолчанию это не отфильтровывает сообщений.
Фильтр базы данных управляет тем, какие сообщения сохраняются к базе данных журнала. По умолчанию это отбрасывает отладку - и сообщения журнала информационного уровня. Однако любое сообщение, в частности позволенное глобальным или фильтром на клиент, обходит этот фильтр.
Функции в Системном журнале 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 вместо того, чтобы создать Вашу собственную систему журналирования рекомендуемая наиболее успешная практика и обеспечивает несколько преимуществ:
Ваши сообщения журнала проще найти — пользователи только должны посмотреть в одном месте.
Система не становится нарушенной многочисленными файлами журнала из различных программ.
Журналирование APIs управляет вращением журнала и фильтрующий для Вас.
Журналирование APIs позволяет Вам искать сообщения журнала, а также журналы.
При журналировании отладочной информации необходимо или отключить эти сообщения по умолчанию или зарегистрировать их на Уровне отладки. Это гарантирует, чтобы Ваши сообщения отладки не загромождали Ваш (и Ваши пользователи) журналы.