Логирование и обработка ошибок
Скрипт, работающий без присмотра, обязан рассказывать о себе. Модуль logging ведёт журнал событий, а try/except не даёт одной ошибке уронить весь пайплайн.
Суть:loggingвместо print — с уровнями, временем и записью в файл.try/exceptловит ошибку, чтобы скрипт продолжил работу и записал, что пошло не так.
Когда скрипт запускается ночью по cron, рядом никого нет. Если он молча упадёт, вы узнаете об этом утром по отсутствию отчёта — и не поймёте, что случилось. Поэтому надёжная автоматизация всегда логирует свои действия и обрабатывает ошибки. Модуль logging из stdlib ведёт журнал с временными метками и уровнями важности; всё это работает в браузере.
Уровни логов — это градация важности: DEBUG (детали для отладки), INFO (нормальный ход), WARNING (подозрительно), ERROR (сбой). Настроив порог, вы фильтруете шум. Разберём logging и обработку ошибок прямо в браузере.
Попробуй сам ▶
import logging
logging.basicConfig(level=logging.INFO,
format='%(levelname)s: %(message)s')
def process(file, ok):
# try/except: одна плохая запись не валит весь цикл
try:
if not ok:
raise ValueError('битые данные')
logging.info(f'{file}: обработан')
return True
except ValueError as e:
logging.error(f'{file}: пропущен — {e}')
return False
files = [('jan.csv', True), ('feb.csv', False), ('mar.csv', True)]
done = sum(process(f, ok) for f, ok in files)
logging.warning(f'Готово: {done} из {len(files)} файлов')
# feb.csv упал, но mar.csv всё равно обработалсяКлючевая мысль: feb.csv сломался, но цикл не остановился — ошибка поймана, записана в лог, и обработка пошла дальше. Без try/except первый же сбой уронил бы весь скрипт, и валидные файлы остались бы необработанными.
УСТОЙЧИВЫЙ ПАЙПЛАЙН
для каждого элемента:
try:
обработать --ok--> log INFO -> дальше
except:
log ERROR --------------------> дальше
итог: log WARNING 'N из M успешно'
один сбой НЕ останавливает остальныеВ реальном скрипте логи пишут в файл, чтобы наутро посмотреть историю. Настройка записи в файл показана как врезка — она трогает диск.
import logging
logging.basicConfig(
filename='automation.log',
level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
try:
run_pipeline()
logging.info('Пайплайн завершён успешно')
except Exception as e:
# exc_info=True добавит полный стек ошибки в лог
logging.error('Пайплайн упал', exc_info=True)
raiseЛогирование раскрывает свою силу в связке с уведомлениями: критическую ошибку мало записать в файл — о ней нужно узнать сразу. Поэтому в продакшене к logging часто подключают обработчик, который при уровне ERROR не только пишет в журнал, но и шлёт сообщение в почту или мессенджер. Так ночное падение бэкапа не останется незамеченным до утра. Полезно различать и стратегии реакции на сбой: иногда правильно пропустить плохой элемент и продолжить (обработка пачки файлов), а иногда — немедленно остановиться и поднять тревогу (ошибка в финансовом расчёте). Осознанный выбор между «продолжить» и «упасть громко» — признак зрелой автоматизации.
Как работает под капотом
Когда возникает ошибка, Python создаёт объект исключения и начинает «всплывать» вверх по стеку вызовов, пока кто-нибудь его не поймает блоком except. Если никто не ловит — программа падает с трассировкой. try/except ставит «сетку»: код в try выполняется, а если в нём вылетело подходящее исключение, управление переходит в except, и скрипт продолжает жить.
Модуль logging устроен как конвейер: ваше сообщение проходит через фильтр уровня, форматтер (который добавляет время и уровень) и обработчик (который решает, куда писать — в консоль или файл). Параметр exc_info=True просит logging приложить полную трассировку ошибки — бесценно при ночных падениях.
Частые ошибки
- Голый
except:. Перехват всех исключений подряд прячет даже опечатки в коде. Ловите конкретные типы. - print вместо logging. print не даёт уровней, времени и записи в файл; для автоматизации он слеп.
- Глотать ошибку молча.
except: passскрывает проблему — вы не узнаете, что половина данных потерялась.
Best practices
- Логируйте начало, конец и каждый сбой; пишите логи в файл с временными метками.
- Ловите конкретные исключения, а не всё подряд; используйте
exc_info=Trueдля трассировки. - Решите осознанно: пропустить плохой элемент и продолжить или остановить весь пайплайн.
Итоги. logging и try/except превращают хрупкий скрипт в надёжную службу: журнал событий, перехват ошибок, понятные сообщения. Теперь соберём все навыки курса в один полноценный проект автоматизации.