Четвертую задачу я пропущу, потому как она фактически решена в третьей задаче, и только после того как я еще раз внимательно прочитал условие третьей задачи - понял, что фактически решил четвертую а третью нужно переделать. Всё это можно прочитать в первой части решений задач:
Идём дальше...
Задача 5. Ротация логов
Сделайте так, чтобы логгер utils писал все сообщения уровня INFO и выше в файл utils.log и хранил записи только за последние 10 часов. Убедитесь, что в выводе нет записей от других логгеров.
И как обычно в совете по реализации данной задачи прозвучал риторический вопрос: Какой из них подойдёт лучше для решения данной задачи — BaseRotatingHandler, RotatingFileHandler или TimedRotatingFileHandler? И ссылочка на документацию)))
- Проверьте на маленьких интервалах, например 10 секунд, чтобы убедиться, что ротация работает.
- Чтобы не наплодить много лог-файлов, можно воспользоваться параметром backupCount, отвечающим за количество резервных копий.
Почитал документацию, как-то перевел, составил небольшой конспект:
Так какой же из трех вариантов классов нам может подойти как нельзя лучше?! Наверное тот в котором есть интервал по времени и backupCount, это третий класс - TimedRotatingFileHandler, который собственно и был задействован в пятом уроке - 7.5 Логирование в production:
Который теперь нам нужно модернизировать под наши нужды. В моем варианте это выглядело так:
Я написал отдельный файл конфигурации, который подключил в файле utils.py в котором соответственно вписал дополнительную строчку с уровнем логгирования "INFO":
Сообщения уровнем логгирования ниже чем INFO, в файл utils.log записываться не будут, но если попробовать создать условие для ошибки то оно должно попасть в файл лога:
Как можно видеть, создаются только три файла отдельных от файла utils.log, это выставляется параметром backupCount.
Замечено, если постоянно запускать программу app.py и не давать ей установленного промежутка в 10 секунд, то логи будут писаться в один и тот же файл, дополнительных файлов появляться не будет. Но, если программу запускать по истечении этих 10 секунд, то только тогда появляются новые файлы логов.
Ну осталось исправить настройки ротации как было сказано в условиях к задаче - 10 часов:
Задача 6. Дерево логгеров
Иногда разобраться в хитрой иерархии логгеров бывает затруднительно. Специально для таких целей добрые люди написали библиотеку logging_tree, которая выводит древовидную структуру всех существующих логгеров.
Запустите и посмотрите, как выглядит каждый logger. Результат запишите в файл logging_tree.txt.
Установил пакет:
pip install logging_tree
Очень смутно понятно каков должен быть вывод программы, я открыл документацию и вписал код из нее в файл app.py
И получился вот такой вот вывод в консоль:
logging.printout() выводит дерево всех логов и из этого app.py и из utils.py, хоть я там logging_tree не объявлял.
Ну и соответственно, сохраняет файл с деревом логов...
Задача 7. Только ASCII
Мы не рассмотрели, как реализованы объекты класса Filter в логгировании и как ими пользоваться, по двум причинам:
- Это не такая частая задача.
- Это отличный повод для практики в работе с документацией :)
Итак, задание: прочитайте документацию об объекте Filter.
Реализуйте собственный фильтр, который будет отсеивать сообщения, содержащие не ASCII-символы в тексте. Например, такие: ÎŒØ∏‡°⁄·°€йцукен
- В Python 3.7 была добавлена функция str.isascii(), возвращающая булево значение, которое показывает, все ли символы строки входят в ASCII.
- Ради интереса попробуйте реализовать свою функцию is_ascii, которая принимает на вход строку, а возвращает также булево значение.
Итак, все реализуется довольно таки просто. За основу я взял 4ю работу, с dict-конфигурацией. Выкинул оттуда работу с файлом и вставил обработчик фильтра.
В файл app.py, я добавил две строчки, одна из строчек (которая с кириллицей) должна отсеяться фильтром:
Как можно видеть, символы, отличные от символов ASCII не отображаются в логах:
Задача 8. Сборщик логов
Реализуйте flask-сервер, который будет принимать логи от сервисов, и обработчик, который будет отправлять туда логи.
Нужно сделать чтобы при выполнении приложения app.py, логи выводились не только в консоль но и еще на страничке браузера по адресу 127.0.0.1:5000/logs чтобы результатом работы было нечто подобное на это:
У нас есть минимальный файл запуска сервера, в котором один эндпойнт должен принять эти логи, а другой их выдать по запросу, на страницу, как у меня выше в скриншоте. Всё это дело должно быть сделано через dict_config. И вот что у меня получилось в файле сервера:
Делаем конфигурацию логгера, где логгирование будет выводиться не только в консоль, но и еще посылать логи на эндпойнт http://127.0.0.1:5000/log
Файлы app.py и utils.py у меня оставлены без изменений, я их скопировал из 4й задачи.
Запускаем наш сервер, и только после этого, откуда нибудь из консоли я запускал python app.py:
Что давало реакцию в консоли пайчарма:
А по адресу http://127.0.0.1:5000/logs в браузере выводились эти же логи.
Задача 9. ini-конфигурация
Когда вам придётся работать в проекте не с нуля, высока вероятность того, что логирование в нём будет сконфигурировано не через словарь, а через ini-файл. Так что хорошо бы научиться в нём ориентироваться. Он устроен не очень сложно.
В репозитории приведён пример ini-файла. Ваша задача — переписать его в формат dict-конфигурации.
Не знаю чем я руководствовался когда ini конфиг преобразовывал в dict-config. Скорее всего по наитию. Вот что у меня получилось:
И вот таким способом проверил, будут ли ошибки при использовании моего конфигурационного файла:
И даже создается логфайл со следующим содержимым: