Вы когда-нибудь запускали программу и она вылетала с ошибкой? Никаких сообщений об ошибках, никаких подсказок, только тишина. Как понять, что пошло не так? В этом случае на помощь приходит ведение журнала.
Журналы отслеживают, что происходит внутри вашего кода, чтобы вам не приходилось гадать, когда что-то идёт не так. Они похожи на print
или console.log
, но более мощные.
В этой статье мы используем Python, чтобы создать и продемонстрировать вам несколько примеров кода для ведения журнала.
Прежде чем мы поговорим о журналах, давайте разберёмся в различных типах ошибок, с которыми вы можете столкнуться.
Типы ошибок
При создании приложения для производственной среды необходимо отображать ошибки в зависимости от их серьёзности. Существует несколько типов ошибок, и наиболее важные из них:
- DEBUG: Подробная информация, обычно полезная для диагностики проблем.
- INFO: Общая информация о ходе реализации программы.
- WARNING: Произошло нечто неожиданное, но это не критично.
- ERROR: Произошла ошибка, но программа все еще может запускаться.
- CRITICAL: очень серьёзная ошибка, которая может привести к остановке работы программы.
Что такое ведение журнала?
Теперь давайте перейдём к сути и разберёмся, что такое лесозаготовка.
Проще говоря, логирование — это процесс записи информации обо всём, что делает ваша программа. Записываемая информация может быть любой: от базовых сведений, таких как вызов функций, до более подробных, таких как отслеживание ошибок или проблем с производительностью.
Зачем нам нужно ведение журнала?
Вы можете подумать: «Если логи выводят ошибки, информацию и так далее, я могу просто использовать операторы вывода. Зачем мне нужны логи?» Что ж, print
работает, но логи дают вам больше возможностей:
- Он может сохранять сообщения в файле.
- У него есть разные уровни (информация, предупреждение, ошибка и так далее).
- Вы можете фильтровать сообщения по важности.
- Он помогает в отладке, не перегружая код.
Это то, что print
не может сделать эффективно.
Как добавить журналы в Python
В Python модуль logging
создан специально для ведения журнала.
Давайте настроим несколько журналов, чтобы посмотреть, как они работают.
Шаг 1: Импортируйте модуль ведения журнала
Чтобы начать использовать ведение журнала, нам нужно импортировать модуль:
import logging
Шаг 2: Регистрируйте сообщения
Теперь вы можете начать регистрировать сообщения в своей программе. Вы можете использовать разные уровни регистрации в зависимости от важности сообщения. Напомним, что эти уровни (от наименее до наиболее важных):
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
Давайте запишем простое сообщение на каждом уровне:
logging.debug("This is a debug message") logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") logging.critical("This is a critical message")
При запуске вы увидите сообщение, выводимое на консоль, похожее на это:
Вы можете задаться вопросом, почему вы не видите сообщения DEBUG и INFO. Этому препятствует уровень ведения журнала по умолчанию.
По умолчанию уровень ведения журнала установлен на WARNING
. Это означает, что будут отображаться только сообщения с уровнем важности WARNING
или выше (то есть WARNING
, ERROR
, и CRITICAL
).
Шаг 3: Настройте базовую конфигурацию
Чтобы увидеть сообщения debug
и info
, нам нужно установить уровень ведения журнала DEBUG
перед запуском кода.
Это означает, что нам нужно настроить логи. Для этого воспользуйтесь описанным ниже методом basicConfig
:
logging.basicConfig(level=logging.DEBUG)
Эта базовая конфигурация позволяет регистрировать сообщения на уровне DEBUG или выше. Вы можете изменить уровень в зависимости от типа необходимых вам журналов.
Теперь все журналы печатаются:
Шаг 4: Войдите в файл
Теперь давайте сохраним эти журналы в файл, чтобы отслеживать ошибки и время их возникновения. Для этого обновите конфигурацию:
logging.basicConfig(filename='data_log.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
Здесь:
asctime
– Время, когда произошло событие.levelname
— Тип журнала (например, DEBUG, INFO).message
– Сообщение, которое мы выводим на экран.
Теперь, когда вы запустите программу, файл журнала будет создавать и сохранять ваши логи с указанием точного времени, типа ошибки и сообщения. Вот так:
Как использовать регистраторы для большего контроля
Если вы работаете над крупным проектом, вам может понадобиться служебный логгер, который можно использовать в любом месте кода. Давайте создадим такой пользовательский логгер.
Сначала мы обновим basicConfig
так, чтобы он добавлял имя файла, номер строки и записывал всё, даже специальные символы:
logging.basicConfig( filename=log_file, level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s', filemode='w', encoding='utf-8' )
Объяснение:
encoding='utf-8'
— Обеспечивает регистрацию специальных символов.%(filename)s:%(lineno)d
— Регистрирует имя файла и номер строки, в которой был сгенерирован журнал.
Теперь давайте настроим пользовательский консольный регистратор:
console_handler = logging.StreamHandler() console_handler.setLevel(logging.DEBUG) console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s') # Added line number console_handler.setFormatter(console_formatter) logging.getLogger().addHandler(console_handler)
Эта настройка выполняет следующее:
console_handler
: Отправляет сообщения журнала на консоль (стандартный вывод).console_formatter
: Форматирует сообщение журнала с указанием времени, уровня, имени файла, номера строки и самого сообщения.logging.getLogger().addHandler(console_handler)
: Добавляет пользовательский обработчик в корневой журнал, чтобы сообщения журнала выводились на консоль.
Полный пример кода
import logging import os from datetime import datetime def setup_daily_logger(): base_dir = os.path.dirname(os.path.abspath(__file__)) log_dir = os.path.join(base_dir, 'logs') os.makedirs(log_dir, exist_ok=True) current_time = datetime.now().strftime("%m_%d_%y_%I_%M_%p") log_file = os.path.join(log_dir, f"{current_time}.log") logging.basicConfig( filename=log_file, level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s', filemode='w', encoding='utf-8' ) console_handler = logging.StreamHandler() console_handler.setLevel(logging.DEBUG) console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s') # Added line number console_handler.setFormatter(console_formatter) logging.getLogger().addHandler(console_handler) return logging.getLogger(__name__)
Что же теперь будет?
Теперь при каждом запуске программы в папке logs
будет создаваться новый файл журнала. При каждом запуске программы будет создаваться новый файл журнала с уникальной отметкой времени.
Вот так:
Эти журналы дадут вам чёткое представление о поведении вашей программы и помогут в отладке.
Надеюсь, эта статья помогла вам лучше понять логи и их важность в программировании.
Практические примеры из реального мира
Теперь, когда вы понимаете, что такое логи и как их настроить в Python, давайте рассмотрим примеры из реальной жизни.
1. Бот: Скрапинг крупнейшего сайта недвижимости Кореи
Вот пример бота, созданного для сбора данных с крупнейшего в Корее сайта о недвижимости.
- В журналах отображается каждый шаг, который выполняет бот, что упрощает отслеживание прогресса.
- Если на каком-либо этапе возникает ошибка, она записывается в файл журнала.
- Даже если бот выйдет из строя, я могу проверить логи, чтобы понять, где что-то пошло не так.
Один из методов в классе этого бота использует логирование, чтобы отслеживать, правильно ли бот выбирает провинцию.
Здесь:
- Если возникает ошибка или предупреждение, они сохраняются в файле журнала.
- Позже вы сможете просмотреть журналы и точно узнать, что произошло
2. Бот: Очистка групп Facebook
Теперь давайте посмотрим, как ведение журнала помогает в парсинге групп Facebook.
Отслеживание ошибок
- В какой-то момент бот вышел из строя из-за ошибки.
- Поскольку у нас была включена функция ведения журнала, ошибка была сохранена в файле журнала.
- Это позволяет вам быстро выяснить, что пошло не так.
Здесь вы видите точное имя файла и номер строки, в которой возникает ошибка.
Как только мы выявили и устранили проблему, бот снова начал работать.
Он фиксирует каждую деталь в журнале, экономя часы отладки за счёт определения места возникновения ошибок.
Упрощенная отладка
- В логах были зафиксированы все детали работы бота.
- Это может сэкономить вам несколько часов на отладке, потому что вы будете точно знать, где произошла ошибка.
Заключение
Ведение журналов — это одна из тех вещей, о которых никто не задумывается, пока что-нибудь не сломается. Но когда это происходит, журналы становятся вашим лучшим другом.
Запомните:
- Ведение журнала нужно не только для отслеживания ошибок — оно помогает контролировать работу программы.
- Вместо того чтобы гадать, что пошло не так, проверьте логи. Обычно ответ находится там.
Не забудьте добавить ведение журнала в свой код. Вы потом будете себя благодарить!