Автор оригинала: Pankaj Kumar.
Модуль Python Logging используется для реализации гибкой системы ведения журнала, управляемой событиями, которая служит удобным способом хранения событий журнала или сообщений для приложения.
Модуль ведения журнала Python – Регистраторы
Объект Logger – это объект этого модуля, которым мы можем манипулировать, чтобы выполнить все необходимые записи.
Чтобы создать экземпляр объекта регистратора, мы всегда должны указывать:
log_object = logging.getLogger(name)
Несколько вызовов getLogger(name)
с одним и тем же именем всегда дают ссылку на один и тот же объект.
Теперь, когда у нас есть объект logger, мы можем использовать для него несколько функций.
Запись сообщений на консоль
Всякий раз, когда необходимо сообщить о событиях, мы выделяем содержимое объектов регистратора, чтобы основная запущенная программа получала уведомления об изменениях состояния.
Для этого у нас есть демаркация уровня серьезности отправляемого сообщения, называемая LEVEL
.
УРОВЕНЬ | Когда он используется |
ОТЛАЖИВАТЬ | Подробная информация для целей отладки |
ИНФОРМАЦИЯ | Подтверждение того, что все работает нормально |
ПРЕДУПРЕЖДЕНИЕ | Признак того, что произошло что-то неожиданное |
ОШИБКА | Более серьезная проблема, когда программное обеспечение не в состоянии выполнять какую-либо функцию |
КРИТИЧЕСКИЙ | Серьезная ошибка, имеющая максимальную серьезность |
Это используется для записи в соответствующий файл журнала или в консоль. По умолчанию используется уровень WARNING
, что означает, что будут отслеживаться только события этого уровня и выше (т. е. по умолчанию будут отслеживаться WARNING
, ERROR
и CRITICAL
)
Это позволяет программисту контролировать способ отображения этих сообщений о состоянии в зависимости от выбранного уровня серьезности.
Формат: logging.info(сообщение)
отобразит сообщение в файле/консоли.
Следующий пример иллюстрирует этот метод
import logging # This message will be printed to the console logging.warning('Warning message') # Will not be printed to the console logging.info('Works as expected')
Выход
WARNING:root:Warning message
Вход в файл
Мы используем logging.basicConfig()
для создания обработчика файла журнала.
Формат: logging.basicConfig(имя файла, уровень)
import logging # Create the logfile logging.basicConfig(filename='sample.log', level=logging.DEBUG) logging.debug('Debug message') logging.info('info message') logging.warning('Warning message')
Выход
root@Ubuntu # cat sample.log DEBUG:root:Debug message INFO:root:info message WARNING:root:Warning message
ПРИМЕЧАНИЕ : Вызов basicConfig()
должен предшествовать любому вызову debug()
, info ()
и т. Д.
Существует еще один параметр file mode
для функции basicConfig ()
, который определяет режим файла журнала.
В приведенном ниже примере sample.log
имеет режим только для записи, что означает, что любые сообщения, записанные в него, будут перезаписывать предыдущее содержимое файла.
logging.basicConfig(filename='sample.log', filemode='w', level=logging.DEBUG)
Ведение журнала из нескольких модулей
Поскольку объект файла журнала и обработчики предоставляют один и тот же контекст в нескольких модулях, мы можем использовать их непосредственно в других модулях.
Пример приведен ниже
# main.py import logging import sample_module def main(): logging.basicConfig(filename='application.log', level=logging.INFO) logging.info('main module started') sample_module.sample_function() logging.info('completed') main()
# sample_module.py import logging def sample_function(): logging.info('Sample module doing work')
Здесь один и тот же объект ведения журнала может совместно использоваться несколькими модулями, что делает его подходящим для модульного кода.
Формат сообщений
По умолчанию выходное сообщение имеет заголовок сообщения, содержащий имя узла и уровень сообщения. Чтобы изменить формат отображаемых сообщений, необходимо указать подходящий формат.
import logging logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG) logging.debug('sample message')
Выход
DEBUG:sample message
Отображение даты и времени в сообщении
Добавьте спецификатор %(asctime)s
format, чтобы указать время в сообщении.
import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.warning('Sample message')
Выход
12/26/2019 12:50:38 PM Sample message
Имена объектов регистратора
Сообщение журнала по умолчанию содержит первую часть, содержащую уровень и имя используемого объекта регистратора. (Например: DEBUG:ROOT:пример сообщения
)
Обычно, если аргумент name
не указан, по умолчанию используется ROOT
, имя корневого узла.
В противном случае рекомендуется использовать переменную __name__
, поскольку это имя модуля в пространстве имен пакета Python.
import logging logger = logging.getLogger(__name__)
Изменение уровня сообщения
Объекты регистратора предоставляют нам способ изменения порогового уровня, на котором отображаются сообщения. Метод set Level(уровень)
используется для установки уровня объекта регистратора.
Формат: logger.setLevel(уровень)
import logging logger = logging.getLogger(__name__) # Set the log level as DEBUG logger.setLevel(logging.DEBUG) # The DEBUG level message is displayed logger.debug('Debug message')
Выход
No handlers could be found for logger "__main__"
Это не то, чего мы ожидали. Почему сообщение не отображается и что такое обработчик?
Обработчик ведения журнала
Обработчик ведения журнала-это компонент, который выполняет работу по записи в журнал/консоль. Объект logger вызывает обработчик ведения журнала для отображения содержимого сообщения.
Обработчик никогда не создается напрямую, как в случае с регистраторами. Существуют различные типы обработчиков, каждый из которых имеет свой собственный метод создания экземпляра.
Типы обработчиков
В модуле ведения журнала есть различные обработчики, но мы в первую очередь рассматриваем 3 наиболее часто используемых обработчика, а именно:
- Ручник
- Обработчик файлов
- NullHandler
Ручник
StreamHandler используется для отправки выходных данных журнала в такие потоки, как stdout
, stderr
или любой файлоподобный объект, который поддерживает методы write()
и flush ()
, такие как pipes, FIFOs и другие.
Мы можем использовать StreamHandler()
для инициализации объекта StreamHandler, который может отображать сообщения на консоли из нашего объекта регистратора.
Предыдущий фрагмент кода теперь можно завершить вызовами StreamHandler()
и handler.setLevel()
.
import logging # Instantiate the logger object logger = logging.getLogger(name='hi') # Set the level of the logger logger.setLevel(logging.DEBUG) # Initialise the handler object for writing handler = logging.StreamHandler() # The handler also needs to have a level handler.setLevel(logging.DEBUG) # Add the handler to the logger object logger.addHandler(handler) # Now, the message is ready to be printed by the handler logger.debug('sample message')
Выход
sample message
Обработчик файлов
Для входа в файл мы можем использовать объект FileHandler. Он также похож на объект StreamHandler, но здесь упоминается файловый дескриптор, так что ведение журнала происходит с файлом.
Приведенный выше фрагмент кода может быть изменен при создании экземпляра обработчика журнала. Изменив тип на файловый обработчик, сообщение можно записать в файл.
handler_name = logging.FileHandler(filename='sample.log', mode='a')
NullHandler
Этот обработчик, по сути, ни во что не записывает (эквивалентно передаче вывода в /dev/null
) и, следовательно, рассматривается как обработчик без операций, полезный для разработчиков библиотек.
Вывод
Мы узнали, как использовать API модуля ведения журнала для записи сообщений на консоль и в файл в зависимости от уровня их серьезности. Мы также узнали, как использовать спецификаторы формата для указания способа отображения сообщений, а также использование обработчиков ведения журнала для управления и изменения уровня зарегистрированных сообщений.
Рекомендации
Официальная документация Python для модуля ведения журнала: https://docs.python.org/3/howto/logging.html#logging-basic-tutorial