Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование под Linux [22-12-2002]


Информационный Канал Subscribe.Ru


Здравствуйте дорогие подписчики рассылки "Программирование под Linux" !!!
 ....----==== http://www.firststeps.ru/linux/ ====----....

Вывод сообщений об ошибках программы

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

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

Все это конечно хорошо, если Вы разрабытаваете пользовательское консольное приложение, но как быть, если Ваша программа является сетевым приложением, например POP3 или каким-нибудь другим сервером. В этом случае работа с stderr не возможна, и отладка мягко выражаясь может сильно усложниться. Но не все так печально. Для этих случаев существует демон сообщений syslogd, который все сообщения от ядра и программ записывает в файлы хранящиеся в папке /var/log.

Для того, чтобы начать работу с этим демоном надо подключить файл syslog.h и вам станут доступными три процедуры:

#include <syslog.h>

void openlog( char *ident, int option, int  facility)

void syslog( int priority, char *format, ...)

void closelog( void )

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

Для начала вывода сообщений Вам придется передать в функцию openlog() несколько необходимых параметров:

  • ident - текстовый идентификатор программы, обычно ее название. Он добавляется к началу каждого сообщения для того, чтобы было видно от какой программы поступают сообщения.
  • option - установки открываемого соединения, которые посредством операции OR могут складываться из следующих:
    • LOG_CONS - вывод напрямую в системную консоль, если вдруг происходит ошибка во время отправления сообщения
    • LOG_NDELAY - открывать соединение сразу, обычно соединение открывается после появления первого сообщения
    • LOG_PERROR - выводить сообщения в stderr
    • LOG_PID - добавлять PID программы в каждое сообщение. Полезно когда может работать одновременно несколько одинаковых программ, в этом случае их можно различить по идентификатору процесса.
  • facility - позволяет задать тип программы, которая выводит сообщение. Это полезно для того, чтобы разделять сообщения от различных программ и записывать их в разные файлы. Все это настраивается для syslogd файлом конфигурации /etc/syslog.conf. А значения этого параметра могут быть следующими:
    • LOG_AUTH - сообщения безопасности/авторизации (рекомендуется использовать LOG_AUTHPRIV)
    • LOG_AUTHPRIV - приватные сообщения безопасности/авторизации
    • LOG_CRON - сообщения от демонов времени (например, cron или at)
    • LOG_DAEMON - сообщения от других демонов системы
    • LOG_KERN - сообщения ядра системы
    • LOG_LOCAL0...LOG_LOCAL7 - зарезервированы для локального использования
    • LOG_LPR - подсистема принтера
    • LOG_MAIL - почтовая подсистема
    • LOG_NEWS - подсистема новостей USENET
    • LOG_SYSLOG - внутренние сообщения сгенерированные syslogd
    • LOG_USER (по умолчанию) - сообщения пользовательского уровня
    • LOG_UUCP - сообщения системы UUCP

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

Ну, и чтобы выводить сами сообщения надо использовать функцию syslog(), работа с которой похожа на работу с функцией printf, за исключением того, что сообщению можно задать приоритет(или тип), т.е. его важность. Задается приоритет параметром priority, который может иметь следующие значения:

  • LOG_EMERG - система не работает, грубо говоря в обмороке и требует госпитализации :)
  • LOG_ALERT - необходимо немедленно принять меры
  • LOG_CRIT - критическое состояние
  • LOG_ERR - ошибочное состояние
  • LOG_WARNING - состояние предупреждения
  • LOG_NOTICE - нормальное, но значимое, состояние
  • LOG_INFO - информационное сообщение
  • LOG_DEBUG - сообщение отладки, то что как раз нужно при разработке

А теперь попробуем написать программу test.c, использующую syslog:

#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>

#define DEBUG

int main(){

    int i=0;
    openlog("test",LOG_PID,LOG_USER);

#ifdef DEBUG
    syslog(LOG_DEBUG,"try to sending 10 messages");
#endif

    for (i=0;i<10;i++){
        syslog(LOG_INFO,"info message [i = %d] ",i);
    };

#ifdef DEBUG
    syslog(LOG_DEBUG,"try log to stderr");
#endif
    closelog();

    openlog("test_stderr",LOG_PERROR | LOG_PID,LOG_USER);
    syslog(LOG_INFO,"this is attempt to use stderr for syslog");
    closelog();

    return 0;
};

Компилируем программу и попробуем запустить:

dron~# ./test
test_stderr[6222]: this is attempt to use stderr for syslog

Теперь можем зайти в файл /var/log/messages и посмотреть, что там получилось. А получилось вот что:

Dec 20 11:25:04 dron-linux test[6222]: info message [i = 0]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 1]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 2]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 3]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 4]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 5]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 6]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 7]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 8]
Dec 20 11:25:04 dron-linux test[6222]: info message [i = 9]
Dec 20 11:25:04 dron-linux test_stderr[6222]: this is attempt to use stderr for syslog

Помоему классно, но почему-то не хватает некоторых сообщений. Посмотрим /var/log/debug и увидим, что все на месте :)

Dec 20 11:25:04 dron-linux test[6222]: try to sending 10 messages
Dec 20 11:25:04 dron-linux test[6222]: try log to stderr

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

# /etc/syslog.conf
# For info about the format of this file, see "man syslog.conf"
*.=info;*.=notice /var/log/messages
*.=debug  /var/log/debug
*.err   /var/log/syslog

Обратите также внимание, что сообщения, которые должны были выводиться в stderr дублируются в файл. Т.е. по большому счету, даже если поток stderr будет не доступен, то сообщения программы все равно дойдут до вас и это очень хорошо.


Количество подписчиков: 1075

Выпуск подготовил: Кузин Андрей (dron@mjk.msk.ru)

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное