Spec-Zone.ru › Nim 1

logging

Этот модуль реализует простой логгер.

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

Основные возможности

Для начала создайте логгер:

import logging

var logger = newConsoleLogger()

Созданный выше логгер записывает в консоль, но этот модуль также предоставляет логгеры, записывающие в файлы, такие как FileLogger. Также возможно создание пользовательских логгеров, унаследованных от типа Logger.

После создания логгера вызовите его процедуру записи сообщения, чтобы записать сообщение:

logger.log(lvlInfo, "a log message")
# Output: INFO a log message

Значение INFO в выводе является результатом добавления строки форматирования к сообщению, и оно будет отличаться в зависимости от уровня сообщения. Строки форматирования подробно описаны здесь.

Существует шесть уровней ведения журнала: debug, info, notice, warn, error и fatal. Они более подробно описаны в документации перечисления уровня. Сообщение записывается, если его уровень равен или выше уровня логгера levelThreshold и глобального фильтра логов. Последний можно изменить с помощью процедуры setLogFilter.

Предупреждение:

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

Обработчики

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

import logging

var consoleLog = newConsoleLogger()
var fileLog = newFileLogger("errors.log", levelThreshold=lvlError)
var rollingLog = newRollingFileLogger("rolling.log")

addHandler(consoleLog)
addHandler(fileLog)
addHandler(rollingLog)

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

# This example uses the loggers created above
log(lvlError, "an error occurred")
error("an error occurred")  # Equivalent to the above line
info("something normal happened")  # Will not be written to errors.log

Обратите внимание, что уровень сообщения по-прежнему проверяется для каждого обработчика по отношению к его levelThreshold и глобальному фильтру логов.

Строки форматирования

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

Используемая логгером строка форматирования может быть указана, передав аргумент fmtStr при создании логгера или установив его поле fmtStr позже. Если не указано, используется строка форматирования по умолчанию.

Доступны следующие переменные, которые должны быть префиксрованы символом доллара ($):

Переменная Вывод
$date Текущая дата
$time Текущее время
$datetime $dateT$time
$app os.getAppFilename()
$appname Базовое имя $app
$appdir Имя каталога $app
$levelid Первая буква уровня логирования
$levelname Имя уровня логирования

Обратите внимание, что $app, $appname, и $appdir не поддерживаются при использовании JavaScript-бекенда.

Следующий пример демонстрирует использование строк форматирования:

import logging

var logger = newConsoleLogger(fmtStr="[$time] - $levelname: ")
logger.log(lvlInfo, "this is a message")
# Output: [19:50:13] - INFO: this is a message

Примечания при использовании нескольких потоков

При использовании этого модуля в нескольких потоках следует учитывать несколько моментов:

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

См. также

  • Модуль strutils для общих функций строк
  • Модуль strformat для интерполяции строк и форматирования
  • Модуль strscans для scanf и scanp макросов, которые предлагают более простой способ извлечения подстрок, чем регулярные выражения

Импорты

strutils, times, os

Типы

Level = enum
  lvlAll,                   ## All levels active
  lvlDebug,                 ## Debug level and above are active
  lvlInfo,                  ## Info level and above are active
  lvlNotice,                ## Notice level and above are active
  lvlWarn,                  ## Warn level and above are active
  lvlError,                 ## Error level and above are active
  lvlFatal,                 ## Fatal level and above are active
  lvlNone                    ## No levels active; nothing is logged

Перечисление уровней ведения журнала.

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

Типичное использование каждого уровня ведения журнала, от низкого к высокому, описано ниже:

  • Debug - отладочная информация, полезная только разработчикам
  • Info - все, что связано с нормальной работой и не имеет особого значения
  • Notice - более важная информация, о которой пользователи должны быть проинформированы
  • Warn - предстоящие проблемы, требующие внимания
  • Error - ситуации ошибок, из которых приложение может восстановиться
  • Fatal - фатальные ошибки, которые препятствуют продолжению работы приложения

Приложению полностью предоставлено право на использование каждого уровня.

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

Исходный код Изменить
Logger = ref object of RootObj
  levelThreshold*: Level     ## Only messages that are at or above this
                             ## threshold will be logged
  fmtStr*: string            ## Format string to prepend to each log message;
                             ## defaultFmtStr is the default

Абстрактный базовый тип всех логгеров.

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

См. также:

  • ConsoleLogger
  • FileLogger
  • RollingFileLogger
Исходный код Изменить
ConsoleLogger = ref object of Logger
  useStderr*: bool           ## If true, writes to stderr; otherwise, writes to stdout

Логгер, который записывает сообщения журнала в консоль.

Создайте новый ConsoleLogger с помощью процедуры newConsoleLogger.

См. также:

  • FileLogger
  • RollingFileLogger
Исходный код Изменить
FileLogger = ref object of Logger
  file*: File                ## The wrapped file

Логгер, который записывает сообщения журнала в файл.

Создайте новый FileLogger с помощью процедуры newFileLogger.

Примечание: Этот логгер недоступен для JavaScript-бекенда.

См. также:

  • ConsoleLogger
  • RollingFileLogger
Исходный код Изменить
RollingFileLogger = ref object of FileLogger
  maxLines: int
  curLine: int
  baseName: string
  baseMode: FileMode
  logFiles: int
  bufSize: int

Логгер, который записывает сообщения журнала в файл с ротацией логов.

Создайте новый RollingFileLogger с помощью процедуры newRollingFileLogger.

Примечание: Этот логгер недоступен для JavaScript-бекенда.

См. также:

  • ConsoleLogger
  • FileLogger
Исходный код Изменить

Константы

LevelNames: array[Level, string] = ["DEBUG", "DEBUG", "INFO", "NOTICE", "WARN",
                                    "ERROR", "FATAL", "NONE"]
Массив строк, представляющих каждый уровень логирования. Исходный код Изменить
defaultFmtStr = "$levelname "
Строка форматирования по умолчанию. Исходный код Изменить
verboseFmtStr = "$levelid, [$datetime] -- $appname: "

Более подробная строка форматирования.

Эту строку можно передать как аргумент frmStr в процедуры, создающие новые логгеры, такие как newConsoleLogger.

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

Исходный код Изменить

Процедуры

proc substituteLog(frmt: string; level: Level; args: varargs[string, `$`]): string {...}{.
    raises: [], tags: [ReadIOEffect, TimeEffect].}

Форматирует сообщение журнала на указанном уровне с заданной строкой формата.

Переменные формата, присутствующие в frmt, будут заменены соответствующими значениями перед добавлением к args и возвратом.

Если вы не реализуете собственный логгер, вам вряд ли понадобится вызывать эту функцию напрямую. Используйте метод логгера log или один из шаблонов логирования.

См. также:

  • метод log для ConsoleLogger
  • метод log для FileLogger
  • метод log для RollingFileLogger
  • шаблон логирования

Пример:

doAssert substituteLog(defaultFmtStr, lvlInfo, "a message") == "INFO a message"
doAssert substituteLog("$levelid - ", lvlError, "an error") == "E - an error"
doAssert substituteLog("$levelid", lvlDebug, "error") == "Derror"
Исходный код Редактировать
proc newConsoleLogger(levelThreshold = lvlAll; fmtStr = defaultFmtStr;
                      useStderr = false): ConsoleLogger {...}{.raises: [], tags: [].}

Создаёт новый ConsoleLogger.

По умолчанию, сообщения журнала записываются в stdout. Если useStderr имеет значение true, они записываются в stderr.

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

См. также:

  • функцию newFileLogger для использования дескриптора файла
  • функцию newFileLogger принимающую имя файла
  • функцию newRollingFileLogger

Примеры:

var normalLog = newConsoleLogger()
var formatLog = newConsoleLogger(fmtStr=verboseFmtStr)
var errorLog = newConsoleLogger(levelThreshold=lvlError, useStderr=true)
Исходный код Редактировать
proc defaultFilename(): string {...}{.raises: [], tags: [ReadIOEffect].}

Возвращает имя файла, используемое по умолчанию при именовании файлов логов.

Примечание: Эта функция недоступна для JavaScript-бэкенда.

Исходный код Редактировать
proc newFileLogger(file: File; levelThreshold = lvlAll; fmtStr = defaultFmtStr): FileLogger {...}{.
    raises: [], tags: [].}

Создаёт новый FileLogger, использующий предоставленный дескриптор файла.

Примечание: Эта функция недоступна для JavaScript-бэкенда.

См. также:

  • функцию newConsoleLogger
  • функцию newFileLogger принимающую имя файла
  • функцию newRollingFileLogger

Примеры:

var messages = open("messages.log", fmWrite)
var formatted = open("formatted.log", fmWrite)
var errors = open("errors.log", fmWrite)

var normalLog = newFileLogger(messages)
var formatLog = newFileLogger(formatted, fmtStr=verboseFmtStr)
var errorLog = newFileLogger(errors, levelThreshold=lvlError)
Исходный код Редактировать
proc newFileLogger(filename = defaultFilename(); mode: FileMode = fmAppend;
                   levelThreshold = lvlAll; fmtStr = defaultFmtStr;
                   bufSize: int = -1): FileLogger {...}{.raises: [IOError], tags: [].}

Создаёт новый FileLogger, записывающий в файл с указанным именем.

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

  • -1 - использовать системные значения по умолчанию
  • 0 - без буферизации
  • > 0 - фиксированный размер буфера

Примечание: Эта функция недоступна для JavaScript-бэкенда.

См. также:

  • функцию newConsoleLogger
  • функцию newFileLogger для использования дескриптора файла
  • функцию newRollingFileLogger

Примеры:

var normalLog = newFileLogger("messages.log")
var formatLog = newFileLogger("formatted.log", fmtStr=verboseFmtStr)
var errorLog = newFileLogger("errors.log", levelThreshold=lvlError)
Исходный код Редактировать
proc newRollingFileLogger(filename = defaultFilename();
                          mode: FileMode = fmReadWrite; levelThreshold = lvlAll;
                          fmtStr = defaultFmtStr; maxLines: Positive = 1000;
                          bufSize: int = -1): RollingFileLogger {...}{.
    raises: [IOError, OSError], tags: [ReadDirEffect, ReadIOEffect].}

Создаёт новый RollingFileLogger.

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

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

  • -1 - использовать системные значения по умолчанию
  • 0 - без буферизации
  • > 0 - фиксированный размер буфера

Примечание: Эта функция недоступна для JavaScript-бэкенда.

См. также:

  • функцию newConsoleLogger
  • функцию newFileLogger для использования дескриптора файла
  • функцию newFileLogger принимающую имя файла

Примеры:

var normalLog = newRollingFileLogger("messages.log")
var formatLog = newRollingFileLogger("formatted.log", fmtStr=verboseFmtStr)
var shortLog = newRollingFileLogger("short.log", maxLines=200)
var errorLog = newRollingFileLogger("errors.log", levelThreshold=lvlError)
Исходный код Редактировать
proc addHandler(handler: Logger) {...}{.raises: [], tags: [].}

Добавляет логгер в список зарегистрированных обработчиков.

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

См. также:

  • функцию getHandlers

Пример:

var logger = newConsoleLogger()
addHandler(logger)
doAssert logger in getHandlers()
Исходный код Редактировать
proc getHandlers(): seq[Logger] {...}{.raises: [], tags: [].}

Возвращает список всех зарегистрированных обработчиков.

См. также:

  • функцию addHandler
Исходный код Редактировать
proc setLogFilter(lvl: Level) {...}{.raises: [], tags: [].}

Устанавливает глобальный фильтр логирования.

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

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

См. также:

  • функцию getLogFilter

Пример:

setLogFilter(lvlError)
doAssert getLogFilter() == lvlError
Исходный код Редактировать
proc getLogFilter(): Level {...}{.raises: [], tags: [].}

Получает глобальный фильтр логирования.

См. также:

  • функцию setLogFilter
Исходный код Редактировать

Методы

method log(logger: Logger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [Exception], gcsafe, tags: [RootEffect], base.}

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

См. также:

  • метод log для ConsoleLogger
  • метод log для FileLogger
  • метод log для RollingFileLogger
  • шаблон лога
Исходный код Редактировать
method log(logger: ConsoleLogger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [], tags: [ReadIOEffect, TimeEffect, WriteIOEffect].}

Выводит в консоль сообщение с помощью только данного ConsoleLogger.

Этот метод игнорирует список зарегистрированных обработчиков.

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

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

См. также:

  • метод log для FileLogger
  • метод log для RollingFileLogger
  • шаблон лога

Примеры:

var consoleLog = newConsoleLogger()
consoleLog.log(lvlInfo, "this is a message")
consoleLog.log(lvlError, "error code is: ", 404)
Исходный код Редактировать
method log(logger: FileLogger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [IOError], tags: [WriteIOEffect, ReadIOEffect, TimeEffect].}

Записывает сообщение на указанном уровне, используя только данный FileLogger.

Этот метод игнорирует список зарегистрированных обработчиков.

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

Примечания:

  • Только сообщения об ошибках и критических ошибках вызовут немедленную очистку буфера вывода. Используйте процедуру flushFile для ручного сброса буфера, если необходимо.
  • Этот метод недоступен для JavaScript-бекенда.

См. также:

  • метод log для ConsoleLogger
  • метод log для RollingFileLogger
  • шаблон лога

Примеры:

var fileLog = newFileLogger("messages.log")
fileLog.log(lvlInfo, "this is a message")
fileLog.log(lvlError, "error code is: ", 404)
Исходный код Редактировать
method log(logger: RollingFileLogger; level: Level; args: varargs[string, `$`]) {...}{.
    raises: [OSError, IOError, Exception],
    tags: [ReadIOEffect, WriteIOEffect, TimeEffect].}

Выводит сообщение на указанном уровне, используя только данный RollingFileLogger.

Этот метод игнорирует список зарегистрированных обработчиков.

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

Примечания:

  • Только сообщения об ошибках и критических ошибках вызовут немедленную очистку буфера вывода. Используйте процедуру flushFile для ручного сброса буфера, если необходимо.
  • Этот метод недоступен для JavaScript-бекенда.

См. также:

  • метод log для ConsoleLogger
  • метод log для FileLogger
  • шаблон лога

Примеры:

var rollingLog = newRollingFileLogger("messages.log")
rollingLog.log(lvlInfo, "this is a message")
rollingLog.log(lvlError, "error code is: ", 404)
Исходный код Редактировать

Шаблоны

template log(level: Level; args: varargs[string, `$`])

Выводит сообщение на указанном уровне во все зарегистрированные обработчики.

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

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

log(lvlInfo, "This is an example.")

См. также:

  • шаблон debug
  • шаблон info
  • шаблон notice
  • шаблон warn
  • шаблон error
  • шаблон fatal
Исходный код Редактировать
template debug(args: varargs[string, `$`])

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

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

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

debug("myProc called with arguments: foo, 5")

См. также:

  • шаблон log
  • шаблон info
  • шаблон notice
Исходный код Редактировать
template info(args: varargs[string, `$`])

Выводит информационное сообщение во все зарегистрированные обработчики.

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

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

info("Application started successfully.")

См. также:

  • шаблон log
  • шаблон debug
  • шаблон notice
Исходный код Редактировать
template notice(args: varargs[string, `$`])

Выводит сообщение notice во все зарегистрированные обработчики.

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

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

notice("An important operation has completed.")

См. также:

  • шаблон log
  • шаблон debug
  • шаблон info
Исходный код Редактировать
template warn(args: varargs[string, `$`])

Выводит предупреждающее сообщение во все зарегистрированные обработчики.

Предупреждение — это сообщение, которое не является ошибкой, но может указывать на предстоящие проблемы или снижение производительности.

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

warn("The previous operation took too long to process.")

См. также:

  • шаблон log
  • шаблон error
  • шаблон fatal
Исходный код Редактировать
template error(args: varargs[string, `$`])

Выводит сообщение об ошибке во все зарегистрированные обработчики.

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

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

error("An exception occurred while processing the form.")

См. также:

  • шаблон log
  • шаблон warn
  • шаблон fatal
Исходный код Редактировать
template fatal(args: varargs[string, `$`])

Выводит сообщение о критической ошибке во все зарегистрированные обработчики.

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

Примеры:

var logger = newConsoleLogger()
addHandler(logger)

fatal("Can't open database -- exiting.")

См. также:

  • шаблон log
  • шаблон warn
  • шаблон error
Исходный код Редактировать

© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/logging.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API