Logging.warning: примеры (PYTHON)

Использование функции logging.warning для записи предупреждений
Раздел: Логирование, Предупреждения
logging.warning(msg: object, *args, **kwargs): None

Основные сведения о функции logging.warning

Функция logging.warning() является частью стандартного модуля logging в Python и предназначена для регистрации событий уровня WARNING. Использование этого уровня сообщений происходит при возникновении ситуаций, которые не останавливают работу программы, но требуют внимания разработчика, так как могут привести к проблемам в будущем.

Функция создает и сразу же обрабатывает запись журнала с уровнем серьезности WARNING. Она применяется, когда необходимо зафиксировать нештатную ситуацию, которая, однако, позволяет приложению продолжать работу.

Аргументы функции

  • msg: обязательный строковый аргумент, содержащий описание события. Может быть строкой форматирования с использованием спецификаторов, аналогичных оператору %.
  • *args: дополнительные аргументы для подстановки в строку форматирования, указанную в параметре msg.
  • **kwargs: дополнительные именованные аргументы. Основные из них:
    • exc_info: если передано значение, отличное от False, в журнал добавляется информация об исключении (трассировка стека). Обычно передается кортеж, возвращаемый sys.exc_info().
    • stack_info: если равно True, в журнал добавляется информация о стеке вызовов с места вызова функции логирования.
    • extra: словарь с пользовательскими атрибутами, которые можно использовать в строке форматирования записи журнала.
    • stacklevel: целое число, указывающее, на сколько кадров стека подняться для получения информации о месте вызова. По умолчанию равен 1.

Функция не возвращает значений.

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

Пример простого вызова с сообщением:

import logging
logging.warning('Обнаружено снижение скорости обработки данных.')
WARNING:root:Обнаружено снижение скорости обработки данных.

Пример с форматированием строки:

import logging
user = 'Алексей'
attempt = 5
logging.warning('Пользователь %s совершил %d неудачных попыток входа.', user, attempt)
WARNING:root:Пользователь Алексей совершил 5 неудачных попыток входа.

Пример с передачей информации об исключении:

import logging
try:
    1 / 0
except ZeroDivisionError:
    logging.warning('Произошло деление на ноль', exc_info=True)
WARNING:root:Произошло деление на ноль
Traceback (most recent call last):
  File "", line 2, in 
ZeroDivisionError: division by zero

Использование параметра extra:

import logging
logging.basicConfig(format='%(levelname)s - %(module)s - %(custom)s')
logging.warning('Тестовое событие', extra={'custom': 'доп. информация'})
WARNING -  - доп. информация

Аналогичные функции в Python

Модуль logging предоставляет набор функций для разных уровней логирования:

  • logging.debug(): используется для отладочных сообщений, которые обычно не включаются в продакшене.
  • logging.info(): фиксирует информационные события, подтверждающие нормальную работу приложения.
  • logging.error(): применяется для записи ошибок, которые влияют на выполнение конкретной операции, но не всей программы.
  • logging.critical(): используется для критических событий, после которых программа не может продолжать работу.
  • logging.log(): универсальная функция, позволяющая явно указать уровень серьезности в первом аргументе.

Выбор функции зависит от серьезности события. WARNING находится между INFO и ERROR, поэтому применяется для предупреждений о потенциальных проблемах, не являющихся критическими ошибками. Функции info и debug могут не записываться при стандартных настройках уровня логирования.

Аналоги в других языках программирования

JavaScript (Node.js, console):

console.warn('Превышен лимит запросов');
Превышен лимит запросов

Java (java.util.logging):

import java.util.logging.Logger;
Logger logger = Logger.getLogger(MyClass.class.getName());
logger.warning("Недостаточно памяти для операции");
мар 12, 2023 10:30:15 AM MyClass main
WARNING: Недостаточно памяти для операции

C# (System.Diagnostics):

using System.Diagnostics;
Trace.TraceWarning("Соединение нестабильно");
Соединение нестабильно

Golang (log):

import "log"
log.Printf("WARNING: Невозможно прочитать конфигурационный файл")
2023/03/12 10:30:15 WARNING: Невозможно прочитать конфигурационный файл

PHP (error_log):

error_log("WARNING: Кэш устарел", 0);

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

Распространенные ошибки

Использование оператора форматирования % вместо передачи аргументов в функцию:

import logging
name = 'test'
# Неправильно
logging.warning('Файл %s не найден' % name)
# Правильно
logging.warning('Файл %s не найден', name)
Оба варианта выводят одинаковое сообщение, но первый вызывает выполнение форматирования ДО вызова функции, что может привести к потерям производительности при отключенном уровне WARNING.

Неправильное использование параметра extra без настройки формата:

import logging
logging.basicConfig(level=logging.WARNING)
logging.warning('Ошибка', extra={'user': 'admin'})
--- Logging error ---
KeyError: 'user'

Ошибка возникает, потому что в строке формата по умолчанию нет спецификатора %(user)s. Для корректной работы необходимо настроить формат с использованием пользовательских ключей.

Изменения в последних версиях

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

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

import logging

def log_warning(msg):
    logging.warning(msg, stacklevel=2)

# При вызове этой функции в журнале будет указана строка 7,
# а не строка 3 внутри функции log_warning
log_warning('Тестовое предупреждение')
WARNING:root:Тестовое предупреждение

Расширенные примеры использования

Использование словаря для форматирования:

Пример python
import logging
data = {'user': 'Иван', 'action': 'удаление'}
logging.warning('Действие пользователя: %(user)s - %(action)s', data)
WARNING:root:Действие пользователя: Иван - удаление

Логирование с захватом стека без информации об исключении:

Пример python
import logging
logging.warning('Неожиданный путь выполнения', stack_info=True)
WARNING:root:Неожиданный путь выполнения
Stack (most recent call last):
  File "", line 1, in 

Кастомизация через создание собственного логгера:

Пример python
import logging

logger = logging.getLogger('my_app')
logger.setLevel(logging.WARNING)
handler = logging.StreamHandler()
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.warning('Специализированное предупреждение для my_app')
my_app - WARNING - Специализированное предупреждение для my_app

Использование в контексте исключения с сохранением исключения в отдельную переменную:

Пример python
import logging

try:
    file = open('missing.txt', 'r')
except FileNotFoundError as e:
    logging.warning('Проблема доступа к файлу: %s', str(e), exc_info=False)
WARNING:root:Проблема доступа к файлу: [Errno 2] No such file or directory: 'missing.txt'

Логирование в разные обработчики в зависимости от условий:

Пример python
import logging
import sys

logger = logging.getLogger()
logger.setLevel(logging.WARNING)

# Хендлер для консоли
console_handler = logging.StreamHandler(sys.stdout)
# Хендлер для файла
file_handler = logging.FileHandler('warnings.log')

logger.addHandler(console_handler)
logger.addHandler(file_handler)

logging.warning('Это сообщение попадет и в консоль, и в файл')
WARNING:root:Это сообщение попадет и в консоль, и в файл

питон logging.warning function comments

En
Logging.warning Log a message with severity WARNING