Как сделать лог

Обновлено: 02.07.2024

В стандартной библиотеке Python есть замечательный пакет для логирования — logging. В сети бытует мнение, что он сложный и настраивать его сплошная боль. В этой статье я попробую убедить вас в обратном. Мы разберём что из себя представляет этот пакет, изучим основные компоненты и закрепим материал практическим примером.

Зачем нужны логи?

logging и Python

Точкой входа в работу с логированием в Python является библиотека logging. На первый взгляд может показаться, что библиотека сложная и запутанная, но потратив некоторое время на её изучение, можно убедиться в обратном. Для меня logging это классический пример дизайна ООП, где композиция преобладает над наследованием, поэтому в исходном коде библиотеки можно встретить множество функциональных классов. Цель этого туториала разобрать по косточкам каждый класс и воссоединить их в единый механизм логирования в Python. Начнём-с.

Logger

Чтобы начать работу с logging необходимо в импортировать библиотеку logging и вызвать функцию getLogger, передав ей имя будущего логера. Функция вернёт инстанс объекта Logger. Логер это рычаг за который мы дёргаем каждый раз, когда нам нужно записать информацию в лог.

Заметьте, что функция getLogger принимает на вход параметр — имя логера. Можно назначать любое имя или __name__ . Вызов getLogger с одинаковым названием вернёт один и тот же инстанс логера.

Я рекомендую использовать в качестве аргумента __name__ , в этом случае не нужно беспокоиться, что разные модули могут ссылаться на один и тот же логер.

Также есть ещё один метод — exception . Его желательно вызывать в блоке except при обработке исключения. В это случае он сможет уловить контекст исключения и записать его в лог:

Handler

Это далеко не полный список. Чтобы посмотреть все, перейдите по ссылке выше. Для указания Handler, необходимо у инстанса Logger вызвать метод addHandler и передать туда инстанс класса Handler. У одного Logger инстанса может быть множество обработчиков.

Пример записи лога в stdout:

Наверняка вы обратили внимание, что лог содержит всего лишь переданную строку. Как сделать так, чтобы в логе была информация об уровне лога, времени записи?

Formatter

Обратите внимание на строку, которую я передал при инициализации инстанса Formatter :

Filter

Наглядно и понятно, разве logging может быть сложным? 😎

LoggerAdapter

Адаптер нужен для передачи дополнительной контекстной информации при каждой записи лога через Logger. Например, вы написали веб-приложение и вам необходимо в логи дополнительно передавать username пользователя:

extra и не только

Строки в логах это хорошо, а что если я хочу помимо строки дополнительно передавать ответ от веб-сервера? Для этого можно использовать аргумент extra при вызове методов debug , info и т.д. Давайте напишем пример вывода

Теперь вывод значения ключа response можно указать через Formatter (при условии, что response передаётся всегда):

Аргумент extra удобен при написании своих кастомных обработчиков логов (например, отсылка логов в телеграм). Далее я покажу пример кастомного Handler класса для отправки логов в Telegram через бота.

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

Официальная документация рекомендует конфигурировать logging через python-словарь. Для этого необходимо вызвать функцию logging.config.dictConfig и передать ей специальный словарь. Схема словаря описана здесь. Я лишь вкратце пробегусь по основным ключам:

  • version — ключ указывает версию конфига, рекомендуется наличие этого ключа со значением 1, нужно для обратной совместимости в случае, если в будущем появятся новые версии конфигов.
  • disable_existing_loggers — запрещает или разрешает настройки для существующих логеров (на момент запуска), по умолчанию равен True
  • formatters — настройки форматов логов
  • handlers — настройки для обработчиков логов
  • loggers — настройки существующих логеров

Ранее все настройки я задавал кодом через вызов методов. Это может быть удобно, если у вас 1 модуль, но когда таких модулей становится множество, то в каждом из них задавать общие настройки кажется излишним занятием. Давайте попробуем все настройки задать в одном месте:

Неправда ли удобно? В реальных приложениях настройки выносят в отдельный модуль, который обязательно импортируется на старте, например, модуль в settings.py как в Django. Именно в нём задаются глобальные настройки для всех логеров приложения.

Наследование в logging

Ещё одним удобным механизмом в logging является "наследование" настроек корневого логера его потомками. Наследование задаётся через символ . в названии логера. То есть логер с названием my_package.logger1 унаследует все настройки, заданные для my_package . Давайте обновим пример выше, добавив в LOGGING_CONFIG настройку для my_package

Если у вас есть настройка для конкретного логера и вы не хотите, чтобы он был дополнительно обработан родительскими Handler классами, то ключу propagate нужно присвоить значение False . В этом случае передача управления "вверх" до родителя будет запрещена.

Отправляем логи в Telegram

Чтобы создать свой обработчик, необходимо наследоваться от класса Handler и перезаписать метод emit :

При инициализации инстанса класса TelegramBotHandler ему необходимо будет передать токен бота и chat_id . Замечу, что эти настройки можно задать через конфигурирование:

Чтобы обработчик начал свою работу, достаточно в настройках вашего логера прописать новый обработчик:

Заключение

В этой статье я постарался вкратце рассказать и показать основные сущности библиотеки logging, а также продемонстрировать гибкий механизм логирования в python. Надеюсь мне это удалось, и статья оказалась для вас полезной.

Как сделать лог с помощью утилиты ComboFix ?

Скачайте ComboFix здесь и сохраните на рабочий стол.

Anti-Malware Telegram

Как удалить программу Combofix?

Деинсталлируйте ComboFix: нажмите Пуск => Выполнить в окне наберите команду Combofix /Uninstall (см. картинку) , нажмите кнопку "ОК"


Скачайте OTCleanIt, запустите, нажмите Clean up

Антивирусная помощь

Как восстановить ошибочно удалённые Combofix файлы и реестровые записи?

Combofix является мощным инструментом в борьбе с вредоносным ПО.
К сожалению в отличие от других подобных приложений в программе не предусмотрена возможность вмешательства пользователя в её работу.
Это ведёт иногда к потере важных данных, ошибочно отнесённых программой к вредоносному ПО.

Внимание: Перед операциями восстановления обязательно посоветуйтесь с Вашим хелпером.

Если у Вас после работы Combofix наблюдаются проблемы с ОС или с тем или иным приложением, поступаем следующим образом:

- Открываем созданную Combofix папку [корневой каталог]:\Qoobox, в стандартном случае C:\Qoobox. В этой папке находятся подкаталоги:
--Quarantine
--BackEnv
и файлы
--Add-Remove Programs.txt - тут содержится список установленных программ, соответствует панели установки/удаления приложений.
--ComboFix-quarantined-files.txt - тут содержится список удалённых и закарантиненных в процессе работы Combofix файлов.
[email protected][дата сканирования]_[рандомный номер].dat - список файлов системной папки %windir% (в стандартном случае C:\WINDOWS) и подкаталогов.

-Открываем папку ..\Qoobox\Quarantine. В этой папке находятся подкаталоги:
--Папка с именем корневого каталога (в стандартном случае . C)
--Папка с сохранёнными ключами реестра Registry_backups
и файл
--catchme.log

Если Вы НЕ уверены, что этот файл не является вредоносным, пришлите его нам по правилам раздела Помогите (Приложение 2 и 3).


Логи можно сравнить с уликами на месте преступления, а разработчиков — с криминалистами. Роль логов трудно переоценить, ведь когда необходимо найти баг или причину сбоя, сразу обращаются к ним. Подобно тому, как отсутствие улик приводит к нераскрытым делам, отсутствие содержательных логов осложняет диагностику и устранение ошибок, превращая их в затянувшийся или вовсе невыполнимый процесс. Мне приходилось наблюдать, как люди мучились с такими инструментами, как Strace и tcpdump, или развертывали новый код в продакшене во время сбоя лишь затем, чтобы получить больше лог-файлов для выявления проблемы.

Как говорится: “ Хорошо подготовиться — половину дела сделать”, так что каждому профессиональному разработчику следует научиться эффективно вести логи и быть готовым к работе с ними. В данной статье мы не только рассмотрим список полезных практик логирования в приложении, но и разберем теоретические основы данного процесса: что записываем, когда и кто этим должен заниматься.

Прежде чем начать разговор о логах, необходимо ответить на два вопроса:

  1. Что такое программа?
  2. Как осуществляется отладка, в которой логи играют важную роль?

Программа как переходы состояний

Программа — это серия переходов между состояниями.

Состояния — это вся информация, которую программа хранит в своей памяти в определенный момент времени, а код программы определяет то, как она переходит от одного состояния к другому. Разработчики, использующие императивные языки программирования, такие как Java, зачастую акцентируют больше внимания на самом процессе (коде), чем состояниях. Однако понимание того, что программа является серией состояний, очень важно, поскольку они существенно ближе к тому, что должна делать программа, а не как.

Допустим, есть робот, задача которого — заполнить бензобак машины. Если мы рассмотрим выполняемые им действия как переходы состояний, то ему необходимо перейти от состояния (бак пустой, в наличии 50 $) к состоянию (бак полный, в наличии 15 $). Если же мы описываем его как процесс, то он должен найти заправку, доставить туда машину и заплатить. Конечно же, процесс имеет большое значение, но состояния дают более точную оценку правильности программы.

Отладка

Отладка — это мысленная реконструкция переходов состояний. Разработчики проигрывают в уме сценарий программы: как она принимает вводные данные, проходит через ряд изменений состояний и осуществляет вывод, а затем определяют, что пошло не так. Во время разработки этот мыслительный процесс подкрепляется использованием отладчика. Однако в продакшене делать это уже гораздо сложнее, поэтому на данном этапе чаще прибегают к помощи логов.

Понимая суть процесса отладки, мы с легкостью ответим на этот вопрос:

Логи должны содержать информацию, необходимую для реконструкции переходов состояний.

Невозможно, да и не нужно, фиксировать все состояния во все отрезки времени. Например, полиции достаточно лишь нескольких точных набросков, а не видеоклона, для поимки преступника. Тоже самое относится и к логам: разработчикам нужно только внести в них информацию о том, когда происходит переход в критическое состояние. Кроме того, логи должны содержать ключевые характеристики текущего состояния и причину перехода.

Переход в критическое состояние

Не все переходы состояний стоит записывать в лог. Важно рассмотреть программу как серию изменяемых состояний, разделить их на фазы и затем сосредоточиться на времени, когда выполнение переходит от одной фазы к другой.

Предположим, что существуют 3 фазы запуска приложения:

  • загрузка настроек программы;
  • подключение к зависимостям;
  • запуск сервера.


Было бы очень разумно вести логи в начале и конце каждой фазы. Если бы произошла ошибка на этапе подключения к зависимостям и приложение бы зависло, то логи отчетливо показали бы, что после загрузки настроек оно вошло во вторую фазу процесса, не завершив его. Располагая этой информацией, разработчики смогли бы быстро определить проблему.

Ключевые характеристики

Логирование состояний напоминает создание эскизов программы только с учетом ключевых характеристик основ бизнес-логики. Если есть информация закрытого характера, например персональные данные, то ее также нужно записать в лог, но в завуалированном виде.

Причина перехода состояния

Логирование причины перехода состояния чрезвычайно полезно для отладки. Логи должны кратко охватывать содержание предыдущих и следующих состояний, а также объяснять их причины. Они помогают разработчикам получить общую картину и ориентироваться в процессе реконструкции (отладки) выполнения программы.

Пример

Рассмотрим простой пример для обобщения всего сказанного. Предположим, что сервер получает некорректный номер социального страхования, и разработчик намерен внести в лог информацию об этом событии.

Вот несколько анти-шаблонов логов, в которых отсутствуют ключевые характеристики состояния и причины:

  • [2020–04–20T03:36:57+00:00] server.go: Error processing request (Запрос на обработку ошибок)
  • [2020–04–20T03:36:57+00:00] server.go: SSN rejected (Номер социального страхования отклонен)
  • [2020–04–20T03:36:57+00:00] server.go: SSN rejected for user UUID “123e4567-e89b-12d3-a456–426655440000” (Номер социального страхования отклонен для пользователя UUID “123e4567-e89b-12d3-a456–426655440000”)

[2020–04–20T03:36:57+00:00] server.go: Received a SSN request(track id: “e4a49a27–1063–4ab3–9075-cf5faec22a16”) from user uuid “123e4567-e89b-12d3-a456–426655440000”(previous state), rejecting it(next state) because the server is expecting SSN format AAA-GG-SSSS but got **-***(why)

([2020–04–20T03:36:57+00:00] server.go: Получен запрос номера социального страхования (трек id: “e4a49a27–1063–4ab3–9075-cf5faec22a16”) от пользователя user uuid “123e4567-e89b-12d3-a456–426655440000” (предыдущее состояние), запрос отклонен (следующее состояние), так как сервер требует номер социального страхования в формате AAA-GG-SSSS, а получил **-*** (причина)

Типичная ошибка, которую многие допускают, связана с тем, “кто” должен фиксировать информацию. Ведение логов не теми функциями оборачивается дублированием или дефицитом информации.

Программа как уровни абстракции

Большинство грамотно созданных программ подобны пирамиде с уровнями абстракции. Классы/функции верхних уровней разбивают сложную задачу на подзадачи, тогда как классы/функции нижних уровней абстрагируют реализацию подзадач, таких как черные ящики, и предоставляют интерфейсы для вызова верхним уровнем. Эта парадигма облегчает программирование, поскольку каждый уровень сосредоточен на своей логике, не беспокоясь о всевозможных деталях.


Ведите логи только на правильных уровнях

Вернемся к нашему примеру проверки корректности номера социального страхования. Допустим, что логика его проверки обернута в класс Validator следующим образом:

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

Существует два местоположения (A и B) для записи логов об ошибке проверки номера социального страхования, но только B владеет достаточной для этого информацией . В A программа не знает, ни какой запрос она обрабатывает, ни от какого пользователя он поступает. Логирование просто добавляет деталей. Будет лучше, если validateUserUpdateRequest выбросит ошибку из вызывающего компонента (validateRequest), содержащего больше контекста для лога.

Однако это вовсе не означает, что логирование на нижних уровнях программы совершенно необязательно, особенно когда они не раскрывают ошибки верхним уровням. Например, сетевой уровень может иметь встроенную логику повторных попыток, из чего следует, что верхние уровни не замечают проблем с прерывающимися соединениями. В общем, нижние уровни могут вести логи больше на уровне DEBUG, чем на INFO, в целях сокращения многословности. При необходимости разработчики могут настроить уровень лога для получения большего количества деталей.

Существует очевидное соотношение между объемом логов и их полезностью. Чем более содержательные логи, тем легче реконструировать переходы состояний. Вы можете воспользоваться двумя способами контроля количества логов:

Установите соотношение между логами и рабочей нагрузкой

Для контроля объема логов сначала важно его правильно измерить. Большинство программ имеют 2 типа рабочей нагрузки:

  • получение рабочих элементов (запросов) и последующая реакция на них;
  • запрос рабочих элементов откуда-либо и последующее выполнение действий.

где X можно определить, изучив код. Разработчики должны иметь хорошее представление об X-факторах для своих программ и приводить их в соответствие с возможностями логирования и бюджетом. Вот еще несколько типичных случаев X:

Используйте уровни логов

Что, если X все еще слишком большой даже после оптимизации? На помощь приходят уровни логов. Если X намного больше, чем 1, то можно поместить логи на уровень DEBUG, тем самым снизив X уровня INFO. В процессе устранения неполадок программа может временно выполняться на этом уровне для предоставления дополнительной информации.

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

1.Когда писать логи? В момент перехода в критическое состояние.

2.Что записывать в лог? Ключевые характеристики текущего состояния и причину перехода состояния.

3.Кто должен записывать логи? Логирование должно происходить на правильном уровне, содержащем достаточно информации.

logs

Что такое лог? Лог (журнал, log file) - специальный файл с хронологической информацией, который хранится на компьютере или сервере пользователя и содержит данные о действиях программ или отдельных пользователей. Логи - текстовые файлы, которые содержат данные о возникших ошибках работы системы. Серверное ПО создает логи, по которым можно узнать необходимую информацию. Название лога состоит из 2 частиц, например, error_log или access_log.

Зачем нужны лог файлы?

В некоторых ситуациях каждому пользователю ПК или сервера требуется проверить логи. Рассмотрим зачем именно нужны лог файлы.

1. Логи могут понадобится, если нужно узнать статистику по сайту. Например, логи сайтов отображают следующую информацию:

а) статистику посещаемости

б) точки входа и выхода с сайта

в) поисковые запросы, по которым приходят посетители, и наиболее популярные страницы сайта

г) поисковики, страны и браузеры посетителей

д) уровень конверсии и страницы сайта, которые никто не посещает

е) сайты, которые ссылаются на этот ресурс.

2. В случае вирусов или Дддос атаки на сайт, логи помогут быстрее выяснить причину и соответственно помочь устранить ее.

3. Для восстановления доступов испольузются логи авторизации, которые собирают данные о попытках входа.

4. В случае ошибок в работе определенного ПО, устройства или ОС, когда необходимо определить источник проблемы.

Логи (server logs) помогают контролировать работу серверной машины и в случае возникновения ошибок быстро их находить и устранять. Логи используются практически везде, где ведется запись и прослеживание истории программного процесса. В первую очередь это необходимо в целях безопасности. Для того, чтобы найти и проанализировать логи, используют специально предназначенное для этого ПО. Некоторые логи могут обладать очень большим размером, поэтому время от времени их нужно очищать. Лог файл показывает события и его непосредственный источник. Причиной события может быть:

  • действия пользователя системы;
  • программная ошибка;
  • действия со стороны ОС;
  • со стороны используемого оборудования и другие.

Какие есть виды логов?

На практике видов логов может быть несколько. Рассмотрим каждый из них.

  • Логи системы - это логи, связанные с системными событиями.
  • Логи сервера - логи, отвечающие за обращения к серверу и за возникшие ошибки.
  • Логи баз данных - специальные логи, которые имеют отношение к запросам баз данным и возникших ошибках.
  • Логи почты отвечают за отправленные и принятые письма, ошибки и причины по которым письма не были доставлены.
  • Логи cron (планировщика задач).
  • Логи панели управления хостингом, где размещен сайт.
  • Лог основного файла, например, фаервола, днс сервера и др.

Как найти логи?

Место, где находятся логи зависит от используемого ПО, заданных настроек и пути, который заведомо установил администратор сервера.

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

Путь /var/log/ - наиболее частый путь для хранения логов, но могут использоваться и другие папки. Например, для популярных Debian или Ubuntu логи Apache расположены в /var/log/apache2

Названия файлов: журнал ошибок – error.log; журнал доступов – log; основной журнал – syslog; журнал загрузки системы – dmesg.

В ОС Windows свой способ структуризации логов, в котором выделяют уровни событий: подробности; сведения; предупреждение; ошибка; критический. Пользователь может сортировать и фильтровать записи, в зависимости от того, что именно ему нужно.

Что делать с логами?

Лог файлы могут понадобится во многих ситуациях при работе с сайтов, ПК или сервером. Но обратите внимания, что логи не хранятся вечно, поэтому если появилась необходимость проверить их, то следует это делать своевременно. Например, часто хостинг-провайдеры хранят логи до 14 дней, а далее они удаляются и записываются новые. Поэтому если ваш сайт взломали более нескольких недель назад, то установить причину по логам не получится, если логи уже удалены.

Включение и выключение записей логов на сервере происходит в панели управления. В большинстве случаев эта функция доступна в разделе панели Журнал или Логи. Более детально об этом вы можете уточнить непосредственно у вашего хостера.

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

Читайте также: