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 = ref object of Logger useStderr*: bool ## If true, writes to stderr; otherwise, writes to stdout
-
Логгер, который записывает сообщения журнала в консоль.
Создайте новый
ConsoleLoggerс помощью процедуры newConsoleLogger.См. также:
Исходный код Изменить FileLogger = ref object of Logger file*: File ## The wrapped file
-
Логгер, который записывает сообщения журнала в файл.
Создайте новый
FileLoggerс помощью процедуры newFileLogger.Примечание: Этот логгер недоступен для JavaScript-бекенда.
См. также:
Исходный код Изменить RollingFileLogger = ref object of FileLogger maxLines: int curLine: int baseName: string baseMode: FileMode logFiles: int bufSize: int
-
Логгер, который записывает сообщения журнала в файл с ротацией логов.
Создайте новый
RollingFileLoggerс помощью процедуры newRollingFileLogger.Примечание: Этот логгер недоступен для JavaScript-бекенда.
См. также:
Исходный код Изменить
Константы
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: [].}-
Добавляет логгер в список зарегистрированных обработчиков.
Предупреждение: Список обработчиков — это локальная переменная потока. Если данный обработчик будет использоваться в нескольких потоках, эту функцию необходимо вызывать в каждом из этих потоков.
См. также:
Пример:
var logger = newConsoleLogger() addHandler(logger) doAssert logger in getHandlers()
Исходный код Редактировать proc getHandlers(): seq[Logger] {...}{.raises: [], tags: [].}-
Возвращает список всех зарегистрированных обработчиков.
См. также:
Исходный код Редактировать proc setLogFilter(lvl: Level) {...}{.raises: [], tags: [].}-
Устанавливает глобальный фильтр логирования.
Сообщения ниже указанного уровня не будут записываться независимо от
levelThresholdотдельного логгера. По умолчанию, все сообщения записываются.Предупреждение: Глобальный фильтр логирования — это локальная переменная потока. Если выполняется логирование в нескольких потоках, эту функцию необходимо вызывать в каждом потоке, если не предполагается, что разные потоки должны записывать на разных уровнях логирования.
См. также:
Пример:
setLogFilter(lvlError) doAssert getLogFilter() == lvlError
Исходный код Редактировать proc getLogFilter(): Level {...}{.raises: [], tags: [].}-
Получает глобальный фильтр логирования.
См. также:
Исходный код Редактировать
Методы
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.
Этот метод игнорирует список зарегистрированных обработчиков.
Выводится ли сообщение зависит как от поля
levelThresholdConsoleLogger, так и от глобального фильтра логов, заданного с помощью процедуры 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.
Этот метод игнорирует список зарегистрированных обработчиков.
Выводится ли сообщение зависит как от поля
levelThresholdFileLogger, так и от глобального фильтра логов, заданного с помощью процедуры 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.
Этот метод игнорирует список зарегистрированных обработчиков.
Выводится ли сообщение зависит как от поля
levelThresholdRollingFileLogger, так и от глобального фильтра логов, заданного с помощью процедуры 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, `$`])
-
Выводит сообщение на указанном уровне во все зарегистрированные обработчики.
Выводится ли сообщение зависит как от поля
levelThresholdFileLogger, так и от глобального фильтра логов, заданного с помощью процедуры setLogFilter.Примеры:
var logger = newConsoleLogger() addHandler(logger) log(lvlInfo, "This is an example.")
См. также:
Исходный код Редактировать template debug(args: varargs[string, `$`])
-
Выводит сообщение отладки во все зарегистрированные обработчики.
Сообщения отладки обычно полезны только разработчику приложения, и они обычно отключены в сборках релизов, хотя этот шаблон не делает этого различия.
Примеры:
var logger = newConsoleLogger() addHandler(logger) debug("myProc called with arguments: foo, 5")См. также:
Исходный код Редактировать template info(args: varargs[string, `$`])
-
Выводит информационное сообщение во все зарегистрированные обработчики.
Информационные сообщения обычно генерируются во время обычной работы приложения и не имеют особого значения. Могут быть полезны для последующего анализа.
Примеры:
var logger = newConsoleLogger() addHandler(logger) info("Application started successfully.")См. также:
Исходный код Редактировать template notice(args: varargs[string, `$`])
-
Выводит сообщение notice во все зарегистрированные обработчики.
Сообщения notice по смыслу очень похожи на информационные сообщения, но они предназначены для сообщений, о которых пользователь должен быть активно проинформирован, в зависимости от приложения.
Примеры:
var logger = newConsoleLogger() addHandler(logger) notice("An important operation has completed.")См. также:
Исходный код Редактировать template warn(args: varargs[string, `$`])
-
Выводит предупреждающее сообщение во все зарегистрированные обработчики.
Предупреждение — это сообщение, которое не является ошибкой, но может указывать на предстоящие проблемы или снижение производительности.
Примеры:
var logger = newConsoleLogger() addHandler(logger) warn("The previous operation took too long to process.")См. также:
Исходный код Редактировать template error(args: varargs[string, `$`])
-
Выводит сообщение об ошибке во все зарегистрированные обработчики.
Сообщения об ошибках предназначены для условий ошибок на уровне приложения, например, когда какой-то пользовательский ввод сгенерировал исключение. Как правило, приложение будет продолжать работать, но с ухудшенной функциональностью или потерей данных, и эти эффекты могут быть видны пользователям.
Примеры:
var logger = newConsoleLogger() addHandler(logger) error("An exception occurred while processing the form.")См. также:
Исходный код Редактировать template fatal(args: varargs[string, `$`])
-
Выводит сообщение о критической ошибке во все зарегистрированные обработчики.
Сообщения о критических ошибках обычно указывают на то, что приложение не может продолжать работу и завершит свою работу из-за критического состояния. Этот шаблон только выводит сообщение, и ответственность за правильное завершение работы приложения лежит на приложении.
Примеры:
var logger = newConsoleLogger() addHandler(logger) fatal("Can't open database -- exiting.")См. также:
Исходный код Редактировать
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/logging.html