Logging.error: примеры (PYTHON)
logging.error(msg: object, *args, **kwargs): NoneОсновы функции logging.error
Функция logging.error() в Python относится к стандартному модулю logging и применяется для регистрации событий уровня ERROR. Уровень ERROR обозначает серьезные проблемы, которые препятствуют нормальному выполнению программы, но не приводят к ее полной остановке.
Функция вызывается, когда возникает ошибка, требующая внимания разработчика, но позволяющая приложению продолжать работу, возможно, в ограниченном режиме.
Аргументы функции:
- msg (обязательный): Строка сообщения, которая может содержать спецификаторы форматирования (%s, %d и т.д.).
- args (опциональный): Кортеж или словарь аргументов для подстановки в строку сообщения
msg. - exc_info (опциональный, по умолчанию False): Если имеет значение True, в запись лога добавляется информация об исключении из текущего стека вызовов.
- stack_info (опциональный, по умолчанию False): Если True, в лог добавляется информация о стеке вызовов с места, где был вызван логгер, независимо от наличия исключения.
- stacklevel (опциональный, по умолчанию 1): Определяет, сколько уровней стека нужно пропустить при поиске информации о строке и функции. Используется для более точного указания места вызова.
- extra (опциональный): Словарь с дополнительными пользовательскими атрибутами для передачи в форматтер.
Функция ничего не возвращает (None). Ее основная задача - передать запись обработчикам логгера для последующего вывода.
Простые примеры использования
Базовый пример с простым сообщением:
import logging
logging.basicConfig(level=logging.ERROR)
logging.error('Произошла ошибка при чтении файла')ERROR:root:Произошла ошибка при чтении файла
Пример с подстановкой аргументов:
import logging
logging.basicConfig(level=logging.ERROR, format='%(levelname)s: %(message)s')
filename = 'data.txt'
error_code = 404
logging.error('Не удалось открыть файл %s. Код ошибки: %d', filename, error_code)ERROR: Не удалось открыть файл data.txt. Код ошибки: 404
Пример с выводом информации об исключении:
import logging
logging.basicConfig(level=logging.ERROR)
try:
1 / 0
except ZeroDivisionError:
logging.error('Деление на ноль', exc_info=True)ERROR:root:Деление на ноль Traceback (most recent call last): File "", line 2, in ZeroDivisionError: division by zero
Альтернативные функции в Python
Модуль logging предоставляет несколько функций для разных уровней серьезности событий:
- logging.debug(): Для отладочной информации, полезной в процессе разработки. Уровень DEBUG.
- logging.info(): Для регистрации обычных событий работы программы. Уровень INFO.
- logging.warning(): Для предупреждений о нештатных, но некритичных ситуациях. Уровень WARNING.
- logging.critical(): Для критических ошибок, после которых программа не может продолжать работу. Уровень CRITICAL.
- logging.exception(): Специальная функция для логирования на уровне ERROR с автоматическим добавлением информации об исключении. Эквивалентна вызову
logging.error(..., exc_info=True)внутри блока except.
Выбор функции зависит от важности события. logging.error() применяют для ошибок, требующих вмешательства, но не останавливающих приложение полностью. logging.critical() используют для фатальных сбоев. logging.exception() удобна внутри блоков обработки исключений.
Аналоги в других языках программирования
JavaScript (Node.js, console.error):
console.error('Ошибка соединения с базой данных: %s', error.message);Ошибка соединения с базой данных: Connection refused
Java (java.util.logging.Logger.severe или log4j):
import java.util.logging.Logger;
Logger logger = Logger.getLogger(MyClass.class.getName());
logger.severe("Ошибка загрузки конфигурации: " + e.getMessage());Go (log.Println, log.Printf с флагом log.LstdFlags):
import "log"
log.Printf("[ERROR] Ошибка валидации данных: %v", err)2024/01/15 10:30:15 [ERROR] Ошибка валидации данных: invalid type
PHP (error_log с типом 0 или monolog/monolog):
error_log("Ошибка SQL запроса: " . $e->getMessage(), 0);
// Или с Monolog
$logger->error('Ошибка SQL запроса', ['exception' => $e]);C# (ILogger.LogError или NLog/Serilog):
_logger.LogError("Ошибка при сохранении файла {FileName}", fileName);Отличия от Python: в Java и C# часто используют отдельные библиотеки логирования (Log4j, NLog), предоставляющие более сложную конфигурацию. В Go и JavaScript подход более минималистичный, без уровней по умолчанию в стандартной библиотеке.
Распространенные ошибки
Использование форматирования через f-строки или str.format() вместе с аргументами args:
import logging
name = 'файл.txt'
# Неправильно: дублирование форматирования
logging.error(f'Ошибка с {name}', exc_info=True) # Аргумент 'name' уже подставлен, args не нуженERROR:root:Ошибка с файл.txt
Отсутствие базовой конфигурации, приводящее к молчаливому игнорированию сообщений:
import logging
# Без basicConfig сообщения уровня ERROR все равно выводятся, но для других уровней могут игнорироваться
logging.warning('Это предупреждение не появится')
logging.error('А это сообщение об ошибке появится')ERROR:root:А это сообщение об ошибке появится
Неправильный порядок аргументов:
import logging
# Ошибка: передача словаря в качестве msg, а не в extra
logging.error({'user': 'admin'}, extra={'ip': '192.168.1.1'}) # Выведет repr словаря как сообщениеERROR:root:{'user': 'admin'}Изменения в новых версиях Python
В Python 3.8 был добавлен параметр stacklevel. Он позволяет указать, на сколько уровней вверх по стеку нужно подняться для определения имени функции, номера строки и других атрибутов. Это полезно при создании оберток вокруг логирования.
import logging
logging.basicConfig(format='%(funcName)s: %(message)s', level=logging.ERROR)
def helper():
logging.error('Ошибка', stacklevel=2) # Указывает, что вызов был на уровень выше
def main():
helper() # В логе будет указана функция main, а не helper
main()main: Ошибка
В Python 3.11 улучшена производительность модуля logging, особенно при частых вызовах.
Расширенные примеры
Использование словаря для аргументов форматирования:
import logging
logging.basicConfig(level=logging.ERROR, format='%(message)s')
params = {'resource': 'база данных', 'status': 'недоступна'}
logging.error('Сервис %(resource)s %(status)s', params)Сервис база данных недоступна
Передача дополнительных полей через extra:
import logging
logging.basicConfig(level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(user_id)s - %(message)s')
logging.error('Сбой авторизации', extra={'user_id': 12345})2024-01-15 10:30:15,123 - ERROR - 12345 - Сбой авторизации
Логирование с фильтрацией по имени логгера:
import logging
# Создаем именованный логгер
app_logger = logging.getLogger('my_app')
app_logger.setLevel(logging.ERROR)
handler = logging.StreamHandler()
app_logger.addHandler(handler)
app_logger.error('Ошибка в модуле my_app')
logging.error('Это сообщение от корневого логгера') # Не появится, т.к. у корневого логгера нет обработчикаОшибка в модуле my_app
Использование logging.error в сочетании с исключениями и finally:
import logging, sys
logging.basicConfig(level=logging.ERROR, stream=sys.stderr)
def process_data(data):
try:
result = int(data)
except ValueError as e:
logging.error('Некорректные данные: %s. Оригинальная ошибка: %s', data, str(e))
result = None
finally:
logging.error('Блок finally выполнен для данных: %s', data)
return result
print(process_data('abc'))
print(process_data('42'))ERROR:root:Некорректные данные: abc. Оригинальная ошибка: invalid literal for int() with base 10: 'abc' ERROR:root:Блок finally выполнен для данных: abc None ERROR:root:Блок finally выполнен для данных: 42 42