Добавить в корзинуПозвонить
Найти в Дзене

Logging в Python. Основы и углублённое изучение

Logging - важная часть разработки и поддержки программного обеспечения. В Python встроенный модуль logging предоставляет гибкий и мощный инструментарий для ведения журналов. Давайте углубимся в детали этого модуля и рассмотрим его основные компоненты и продвинутые функции. Прежде всего, для использования logging необходимо импортировать соответствующий модуль: import logging Базовое использование logging очень просто: logging.debug('Это сообщение уровня DEBUG') logging.info('Это информационное сообщение') logging.warning('Это предупреждение') logging.error('Это сообщение об ошибке') logging.critical('Это критическое сообщение') По умолчанию, только сообщения уровня WARNING и выше будут выводиться на консоль. Для более тонкой настройки logging можно использовать функцию basicConfig(): logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', filename='app.log', filemode='w') Эта конфигурация устанавливает уровень логирования DEBUG,
Оглавление

Logging - важная часть разработки и поддержки программного обеспечения. В Python встроенный модуль logging предоставляет гибкий и мощный инструментарий для ведения журналов. Давайте углубимся в детали этого модуля и рассмотрим его основные компоненты и продвинутые функции.

1. Основы logging

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

import logging

Базовое использование logging очень просто:

logging.debug('Это сообщение уровня DEBUG')
logging.info('Это информационное сообщение')
logging.warning('Это предупреждение')
logging.error('Это сообщение об ошибке')
logging.critical('Это критическое сообщение')

По умолчанию, только сообщения уровня WARNING и выше будут выводиться на консоль.

2. Конфигурация logging

Для более тонкой настройки logging можно использовать функцию basicConfig():

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', filename='app.log', filemode='w')

Эта конфигурация устанавливает уровень логирования DEBUG, задает формат сообщений, указывает файл для записи логов и режим записи (перезапись).

3. Форматирование сообщений

Форматирование сообщений - важный аспект logging. Вы можете использовать различные атрибуты в строке формата:

- %(asctime)s: Время создания записи

- %(name)s: Имя логгера

- %(levelname)s: Текстовое представление уровня логирования

- %(message)s: Сообщение лога

- %(filename)s: Имя файла, из которого была вызвана функция логирования

- %(funcName)s: Имя функции, в которой произошло логирование

- %(lineno)d: Номер строки, где произошло логирование

Пример более сложного форматирования:

format_str = '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
logging.basicConfig(format=format_str)

4. Использование getLogger()

Функция getLogger() позволяет создавать именованные логгеры, что особенно полезно в больших приложениях:

logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)
# Создание обработчика
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# Создание форматтера
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# Добавление обработчика к логгеру
logger.addHandler(handler)
logger.debug('Это отладочное сообщение')

5. Обработчики (Handlers)

Обработчики определяют, куда будут отправляться сообщения лога. Python предоставляет несколько типов обработчиков:

- StreamHandler: Отправляет сообщения в потоки (например, sys.stdout, sys.stderr)

- FileHandler: Отправляет сообщения в файл

- RotatingFileHandler: Отправляет сообщения в файл с возможностью ротации по размеру

- TimedRotatingFileHandler: Отправляет сообщения в файл с возможностью ротации по времени

Пример использования

RotatingFileHandler:

from logging.handlers import RotatingFileHandler
logger = logging.getLogger('my_app')
handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=3)
logger.addHandler(handler)

6. Фильтры (Filters)

Фильтры позволяют более точно контролировать, какие сообщения логируются:

class MyFilter(logging.Filter):
def filter(self, record):
return 'important' in record.getMessage()
logger = logging.getLogger('my_app')
logger.addFilter(MyFilter())

7. Логирование исключений

Для логирования исключений можно использовать метод exception():

try:
1 / 0
except ZeroDivisionError:
logging.exception("Произошло деление на ноль")

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

8. Конфигурация из файла

Для больших приложений удобно хранить конфигурацию logging в отдельном файле:

import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('my_app')

Использование dictConfig Альтернативой fileConfig является dictConfig, которая позволяет настраивать logging с помощью словаря Python:

import logging.config
logging_config = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default': {
'level': 'INFO',
'formatter': 'standard',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
},
},
'loggers': {
'': {
'handlers': ['default'],
'level': 'INFO',
'propagate': True
}
}
}
logging.config.dictConfig(logging_config)
logger = logging.getLogger(__name__)

10. Логирование в многопоточных приложениях

Модуль logging потокобезопасен, но при работе с несколькими потоками следует быть осторожным:

import logging
import threading
def worker(arg):
logger = logging.getLogger('myapp.worker')
logger.info('Worker running with argument %s', arg)
logging.basicConfig(level=logging.INFO, format='%(threadName)s: %(message)s')
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()

11. Создание пользовательских уровней логирования

Вы можете создавать собственные уровни логирования:

VERBOSE = 15
logging.addLevelName(VERBOSE, "VERBOSE")
def verbose(self, message, *args, **kwargs):
if self.isEnabledFor(VERBOSE):
self._log(VERBOSE, message, args, **kwargs)
logging.Logger.verbose = verbose
logger = logging.getLogger(__name__)
logger.setLevel(VERBOSE)
logger.verbose("Это сообщение уровня VERBOSE")

12. Контекстные менеджеры для временного изменения уровня логирования

Иногда требуется временно изменить уровень логирования:

import contextlib
@contextlib.contextmanager
def temporary_log_level(logger, level):
old_level = logger.level
logger.setLevel(level)
try:
yield
finally:
logger.setLevel(old_level)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
with temporary_log_level(logger, logging.DEBUG):
logger.debug("Это сообщение будет залогировано")
logger.debug("А это сообщение не будет залогировано")

Заключение

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

Спасибо за прочтение статьи! Надеюсь она окажется вам полезной! Оставляйте комментарии и подписывайтесь! Всем печенек)