logLib

[ lua  qlua  квик  quik  ]

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

Библиотека логирования (за основу была взята небольшая библиотека)

Чтобы ее использовать необходимо подключить ее к своему коду через типовой вызов:

    local log = require("log")

Чтобы скрипт нашел библиотеку необходимо включить путь к каталогу, где расположена библиотека в переменную package.path:

    package.path = path.."/?.lua;..package.path..';'

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

Для определения файла лога используется метод openfile:

    log.openfile(path)

где path - это полный путь к файлу лога.

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

    log.use_err_file    = true
    log.err_filename    = err_path

где err_path - это полный путь к файлу лога ошибок.

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

Для задания уровня выводимых сообщений в лог используется свойство level:

    log.level           = 'error'

Полный список уровней задан в таблице modes:

    local modes = {
        { name = "trace"},
        { name = "debug"},
        { name = "info"},
        { name = "warn"},
        { name = "error"},
        { name = "fail"},
    }

Уровни лога называются так, потому что они расположены в порядке повышения номера по порядку. trace - это уровень 1, debug - 2 и т.д.

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

Для примера:

    log.info('info text') - запись по уровню info, т.е. простая информационная запись
    log.debug('debug text')  - запись по уровню debug, т.е. отладочная информация
    log.warn('warn text') - важная информация
    log.error('error text') - ошибка. Если настроен файл лога ошибок, то также будет продублирована в лог ошибок.

Т.к. уровни лога определяют важность информации, то задав уровень лога через log.level, можно определять, что будет выводиться в файл лога. Допустим, мы определили уровень лог файла info. В тексте скрипта у нас есть вывод как простой информации через log.info, так и отладочной через log.debug. Т.к. уровень info выше, чем уровень debug, то в файл не будет записываться debug информация. Т.е. мы можем оставить в тексте нашего скрипта вывод отладочной информации, но при этом она не будет выводиться.

Если же понизить уровень логирования до debug, то будет выводиться и она. Такая общепринятая организация логирования позволяет удобно формировать лог работы скрипта.

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

Для примера вывод отладочной информации:

[DEBUG 2021-06-04 17:28:18] multiAlgoRunner\robotBaseState.lua:485: Некий текст

Уровни, для которых выводится информация о исполняемой строке, определяются через свойство line_info_levels:

    log.line_info_levels  = "debug|error|fatal"

В библиотеке переопределён глобальный метод tostring так, чтобы корректно форматировались числовые значения, а также организована примитивная сериализация таблиц (без метатаблицы). Т.о. можно при выводе в лог передать tostring(table), что приведет к строковому представлению таблицы. Это удобно для анализа данных при отладке.

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

    log.info('info text '..tostring(a)..', value '..tostring(val)) - это вывод информации с созданием строки
    log.info('info text', a, 'value', val) - это вывод через передачу параметров.

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

При окончании работы скрипта необходимо вызвать методы, закрывающие файлы:

    log.close_err_file() - если определен файл для ошибок
    log.closefile()