Содержание


Чтение записей в журнале ошибок

Comments

Серия контента:

Этот контент является частью # из серии # статей:

Следите за выходом новых статей этой серии.

Этот контент является частью серии:

Следите за выходом новых статей этой серии.

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

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

Журналирование

Пользователи могут вносить в журнал записи об ошибках с помощью двух механизмов:

  • Использование функции. В пользовательских приложениях используется функция errlog, а в расширениях ядра – функция errsave.

    Синтаксис:

    int errlog ( ErrorStructure,  Length)
    void *ErrorStructure;
    unsigned int Length;
  • Использование команды. Используется команда errorlogger.

    Синтаксис:

    errlogger Message

Чтение записей журнала

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

Основы чтения записей в журнале ошибок

Запись в журнале ошибок состоит из различных пар атрибут-значение. К атрибутам относятся идентификатор ошибки, метка, вероятная причина, подробные данные и т.д. Атрибут подробных данных предназначен для предоставления пользователям необходимых данных для обслуживания неисправных компонентов. Тем не менее если пользователь делает дамп структур, содержащих некую жизненно важную информацию, инструмент errpt не может его понять, и на владельца записей в журнале ошибок ложится ответственность за преобразование необработанных данных в простой и понятный формат путем отображения на соответствующие структуры. Для этого инфраструктура журналирования ошибок предоставляет набор конструкций и интерфейсов прикладного программирования (API).

Инфраструктура журналирования ошибок делает записи, сортируя их по времени. Записи создаются в двоичном формате. Для их чтения и анализа необходимы определенные структуры и конструкции. Для поиска и чтения записей в файле журнала ошибок можно использовать приведенный ниже подход, а затем отобразить подробные данные на определенные пользователем структуры и извлечь из этих записей больше значимой информации.

Определение местонахождения файла журнала ошибок

Для определения местонахождения файла журнала ошибок используется следующая команда:

# /usr/lib/errdemon -l
Error Log Attributes
--------------------------------------------
Log File                /var/adm/ras/errlog
Log Size                1048576 bytes
Memory Buffer Size      32768 bytes
Duplicate Removal       true
Duplicate Interval      10000 milliseconds
Duplicate Error Maximum 1000

Напротив тега Log File указывается полный путь к файлу журнала ошибок.

Функции для чтения записей в журнале ошибок

  • errlog_open: с помощью этого API можно открыть файл журнала для чтения имеющихся в нем записей. Ниже приводится его синтаксис.

    Синтаксис:

    int errlog_open(path, mode, magic, handle)

    Таблица 1. Описание параметров функции errlog_open

    АргументТипПримечания
    pathchar *Содержит полный путь к файлу журнала ошибок.
    modeintАналогичен режимам, которые используются в открытой системной подпрограмме.
    magicunsigned intОпределяет версию структуры errlog_entry_t. Значение этого параметра должно быть установлено в LE_MAGIC. Файл sys/errlog.h содержит определение LE_MAGIC, которое используется для текущей версии IBM® AIX®.
    handleerrlog_handle_t *Действует как возвращаемое значение и содержит дескриптор успешно открытого файла журнала ошибок.

    Таблица 2. Описание возвращаемых значений функции errlog_open

    Возвращаемое значениеОписание
    0Успешно.
    LE_ERR_INVARGПередан недопустимый параметр.
    LE_ERR_NOFILEФайл журнала ошибок не существует.
    LE_ERR_NOMEMНе удалось выделить необходимую память.
    LE_ERR_IOПроизошла ошибка ввода/вывода.
    LE_ERR_INVFILEНедопустимый файл журнала ошибок.
  • errlog_close: эта функция используется для закрытия файл журнала ошибок, дескриптор развертывания которого передается в качестве аргумента. Этот дескриптор должен быть тем же, который был возвращен интерфейсом errlog_open.
    int errlog_close(handle)
    errlog_handle_t handle;

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

  • errlog_find_first: эта подпрограмма находит первую запись, которая соответствует заданным критериям фильтрации.
    int errlog_find_first(handle, filter, result)

    Таблица 3. Описание параметров функции errlog_find_first

    АргументТипПримечания
    handleerrlog_handle_tЭто дескриптор, возвращаемый подпрограммой errlog_open.
    filtererrlog_match_t *Определяет фильтр, который будет использоваться для поиска записей.
    resulterrlog_entry_t *Этот параметр указывает область памяти, в которую помещается запись журнала ошибок, соответствующая критериям фильтра.

    Таблица 4. Описание возвращаемого значения функции errlog_find_first

    Возвращаемое значениеОписание
    0Успешно.
    LE_ERR_INVARGПередан недопустимый параметр.
    LE_ERR_DONEВо время поиска достигнут конец файла журнала ошибок. Иными словами, совпадений после предыдущего вызова этого API не найдено. Если это был первый вызов, значит, нет ни одной записи, соответствующей критериям.
    LE_ERR_NOMEMНе удалось выделить необходимую память.
    LE_ERR_IOПроизошла ошибка ввода/вывода.
  • errlog_find_next: описание параметров аналогично интерфейсу errlog_find_first.
    int errlog_find_next(handle, result)

    Описание возвращаемого значения аналогично интерфейсу errlog_find_first.

  • errlog_find_sequence:
    int errlog_find_sequence(handle, sequence, result)

    Таблица 5. Описание параметров функции errlog_find_sequence

    АргументТипПримечания
    handleerrlog_handle_tЭто дескриптор, возвращаемый подпрограммой errlog_open.
    sequenceintЭтот параметр определяет порядковый номер записи в журнале ошибок.
    resulterrlog_entry_t *Этот параметр указывает область памяти, в которую помещается запись журнала ошибок, соответствующая критериям фильтра.

    Описание возвращаемого значения аналогично интерфейсу errlog_find_first.

  • errlog_set_direction:
    int errlog_set_direction(handle, direction)

    Таблица 6. Описание параметров функции errlog_set_direction

    АргументТипПримечания
    handleerrlog_handle_tЭто дескриптор, возвращаемый подпрограммой errlog_open.
    directionint

    Этот параметр определяет направление поиска записей. Возможные значения:

    LE_FORWARD: поиск вперед
    LE_REVERSE: поиск назад

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

Используемые структуры

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

  • Структура errlog_entry для файла /usr/include/sys/errlog.h

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

    typedef struct errlog_entry {
        unsigned int        el_magic;
        unsigned int        el_sequence;
        char                el_label[LE_LABEL_MAX];
        unsigned int        el_timestamp;
    /* некоторые пропущены */
        char                el_machineid[LE_MACHINE_ID_MAX];
        char                el_nodeid[LE_NODE_ID_MAX];
        char                el_class[LE_CLASS_MAX];
        char                el_type[LE_TYPE_MAX];
        char                el_resource[LE_RESOURCE_MAX];
        char                el_rclass[LE_RCLASS_MAX];
        char                el_rtype[LE_RTYPE_MAX];
    /* некоторые пропущены */
        unsigned short      el_detail_length;
        char                el_detail_data[LE_DETAIL_MAX];  /* это важно */
    /* некоторые пропущены */
    } errlog_entry_t;

    Большинство полей el_detail_data используется для поиска записи в журнале ошибок. В el_detail_data хранятся данные, передаваемые посредством структуры struct err_rec0 в интерфейсы errlog и errsave. Отображая структуру, используемую при записи, мы получаем необходимые данные.

  • Структура для указания критериев поиска

    typedef struct errlog_match {
        unsigned int                em_op;
        union {
            struct errlog_match     *emu_left;
            unsigned int            emu_field;
        } emu1;
        union {
            struct errlog_match     *emu_right;
            unsigned int            emu_intvalue;
            unsigned char           *emu_strvalue;
        } emu2;
    } errlog_match_t;

    Приведенная выше структура используется для определения критериев фильтрации/поиска в интерфейсе errlog_find_first.

    В теге emu2 union поля emu_intvalue и emu_strvalue используются для целочисленных и строковых значений.

    Поля emu_field выбирают значения из записи в журнале ошибок и применяют оператор, указанный в emu_intvalue или emu_strvalue в зависимости выбранного типа.

    Файл sys/errlog.h содержит несколько предопределенных значений, упрощающих доступ к этим внутренним полям; более подробную информацию можно найти в самом файле.

Создание критериев поиска

Критерии поиска можно представить в виде изображенного ниже двоичного дерева.

L2:			 Operator [ em_op]
			 /		\
		[ emu_left]		[emu_right]
L1:	       operator1		     operator2
	     [ em_op]				[ em_op ]
	     /	    \				/	\
Leaf:	emu_field   emu_intvalue	emu_field	emu_strvalue

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

Таблица 7. Описание различных уровней узлов
Уровень узлаПримечания
Концевые узлы (листья)Эти узлы содержат только поля и значения журнала ошибок, которые являются операндами для операторов узла L1.
Узлы уровня L1Эти узлы содержат операторы сравнения, такие как greater than (больше), equal to (равно), less than (меньше) и т.д.
Узел уровня L2Этот уровень содержит логические операторы, такие как AND (и), OR (или) и т.д.

Таким образом, к записям и значениям журнала ошибок можно применять только операторы сравнения. Результаты выполнения операторов сравнения можно объединять для формирования сложных критериев поиска с использованием логических операторов. Рассмотрим использование различных операторов.

  • Операторы сравнения:

    В приведенной ниже таблице описываются операторы сравнения, которые можно использовать для создания критериев поиска/фильтрации. Они указываются в поле em_op структуры errlg_match_t. Эти операторы работают только с концевыми узлами.

    Таблица 8. Описание операторов сравнения

    ОператорОписание
    LE_OP_EQUALПроверяет, что левый концевой узел (значение поля записи журнала ошибок) равен правому концевому узлу.
    LE_OP_NEПроверяет, что левый концевой узел (значение поля записи журнала ошибок) не равен правому узлу.
    LE_OP_SUBSTRПроверяет, что левый концевой узел (значение поля записи журнала ошибок) содержит подстроку, указанную в правом узле.
    LE_OP_LTПроверяет, что левый концевой узел (значение поля записи журнала ошибок) меньше правого узла.
    LE_OP_LEПроверяет, что левый концевой узел (значение поля записи журнала ошибок) не больше правого узла.
    LE_OP_GTПроверяет, что левый концевой узел (значение поля записи журнала ошибок) больше правого узла.
    LE_OP_GEПроверяет, что левый концевой узел (значение поля записи журнала ошибок) не меньше правого узла.
  • Логические операторы:

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

    Таблица 9. Описание логических операторов

    ОператорОписание
    LE_OP_ANDПрименяет логический оператор AND к левому и правому узлам.
    LE_OP_ORПрименяет логический оператор OR к левому и правому узлам.
    LE_OP_XORПрименяет логический оператор XOR к левому и правому узлам.
    LE_OP_NOTПрименяет логический оператор NOTтолько к левому узлу.

Для указания поля записи журнала ошибок, которое используется в качестве левого операнда в операторах сравнения, применяются следующие теги:

Таблица 10. Теги, представляющие соответствующие поля записи журнала ошибок
Значения em_fieldОписание
LE_MATCH_SEQUENCEДля использования в качестве операнда поля Sequence записи журнала ошибок.
LE_MATCH_LABELДля использования в качестве операнда поля Label записи журнала ошибок.
LE_MATCH_TIMESTAMPДля использования в качестве операнда поля Timestamp записи журнала ошибок.
LE_MATCH_MACHINEIDДля использования в качестве операнда поля MachineID записи журнала ошибок.
LE_MATCH_NODEIDДля использования в качестве операнда поля NodeID записи журнала ошибок.
LE_MATCH_CLASSДля использования в качестве операнда поля Class записи журнала ошибок.
LE_MATCH_TYPEДля использования в качестве операнда поля Type записи журнала ошибок.
LE_MATCH_RESOURCEДля использования в качестве операнда поля Resource записи журнала ошибок.
LE_MATCH_RCLASSДля использования в качестве операнда поля Rclass (resource class) записи журнала ошибок.
LE_MATCH_RTYPEДля использования в качестве операнда поля Rtype (resource type) записи журнала ошибок.

Пример

Рассмотрим общий подход к чтению записей журнала ошибок.

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

Запись из журнала ошибок:

errlogger "I am from IBM"

Программа на С для чтения записи "I am from IBM":

#include <fcntl.h>
#include <stdio.h>
#include <sys/errlog.h>
main()
{
        /* дескриптор файла журнала ошибок */
        errlog_handle_t my_errlog_hndl;
        /* режим открытия файла ошибок */
        int mode = O_RDONLY;
        int magic = LE_MAGIC;
        /* путь к файлу журнала ошибок */
        char path[]="/var/adm/ras/errlog";
        int rc=0;
        /* критерии соответствия/определения записи журнала ошибок */
        errlog_match_t match_resource_name;
        /* информация соответствующей записи журнала ошибок */
        errlog_entry_t matched_errlog_entry;

        /* Пример поиска записей с типом ресурса OPERATOR */
        char resource_name[]="OPERATOR";

        /* открытие файла журнала ошибок */
        rc=errlog_open(path,mode,magic,&my_errlog_hndl);
        if ( rc )
        {
                printf(" Failed to open error log file error : %d\n",rc);
                exit(1);
        }
        /*
          создание критерия соответствия
          критерий:
          если поле el_resource в структуре errlog_entry_t равно значению OPERATOR
         */
        match_resource_name.em_op=LE_OP_EQUAL;
        match_resource_name.emu1.emu_field=LE_MATCH_RESOURCE;
        match_resource_name.emu2.emu_strvalue=resource_name;

        /* искать первую запись */
        rc=errlog_find_first(my_errlog_hndl,&match_resource_name,&matched_errlog_entry);
        if ( rc == LE_ERR_DONE )
        {
                printf(" Did not find any entry matching the criteria.\n");
        }
        else if ( rc )
        {
                printf(" Failed to find error log entry : %d\n",rc);
        }
        else
        {
                /* продолжать поиск по всем записям; прекратить в случае нахождения
				   нужной записи или возникновения ошибки*/
                while( !rc )
                {
                        /* вывести подробные данные */
                        /* Также можно вывести другую информацию записи журнала ошибок */
                        /* Указатель detail_data можно привести к типу актуальной 
                           и структуры и вывести значения как поля структуры
                         */
                        printf("error log entries detail data is : %s\n",
						matched_errlog_entry.el_detail_data);

                        /* искать следующие записи после первой найденной */
                        rc=errlog_find_next(my_errlog_hndl,&matched_errlog_entry);
                }
                if ( rc == LE_ERR_DONE )
                {
                        printf(" No more entries found.\n");
                }
                else
                {
                        printf(" Failed to find error log entry : %d\n",rc);
                }
        }
        /* закрыть файл журнала ошибок */
        rc=errlog_close(my_errlog_hndl);
        if ( rc )
                printf(" Failed to close error log file error : %d\n",rc);
}

Эту программу можно скомпилировать с помощью следующей команды:

cc read_errlog_entries.c -lerrlog

Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=984948
ArticleTitle=Чтение записей в журнале ошибок
publish-date=10012014