Инструменты пользователя

Инструменты сайта


develop:pyton:logger

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
develop:pyton:logger [2022/12/03 05:32]
admin
develop:pyton:logger [2023/02/01 09:50] (текущий)
admin
Строка 4: Строка 4:
 ===== Общее ===== ===== Общее =====
 [[https://habr.com/ru/company/otus/blog/590067/|Статья]]\\ [[https://habr.com/ru/company/otus/blog/590067/|Статья]]\\
 +
 +<details>
 +<summary>:!: Вырезки </summary>
  
 {{:develop:pyton:2022-12-03_11-21.png?direct&600|}} {{:develop:pyton:2022-12-03_11-21.png?direct&600|}}
  
 {{:develop:pyton:2022-12-03_11-31.png?direct&600|}} {{:develop:pyton:2022-12-03_11-31.png?direct&600|}}
 +
 +</details>
 +
 +
 +===== Применение =====
 +[[https://docs.python.org/3/library/logging.html#logger-objects|Дока]]\\
 +[[https://docs.python.org/3/library/logging.config.html|Дока]]\\
 +
 +Классы логгера наследуются, в блоке "root" можно определить базовые параметры для всех создаваемых потом подклассов\\
 +
 +Собсна структура конфига ниже, перечисляются форматтеры, логгеры, хендлеры, можно создавать несколько разных комбинаций, каждая со своими параметрами и для каждой применяются указанные правила логирования (место, формат, устр-во и т.д.)\\
 +
 +Конфиг можно хранить в отдельном файле, но тогда нет возможности использовать переменные, можно обернуть в python объект, тогда чики-пики. [[https://habr.com/ru/company/otus/blog/590067/|тут есть пример]]\\
 +
 +Настройка целевого уровня задается и в loggers и в handlers, сначала фильтруется в первом, затем во втором\\
 +
 +<code json>
 +{
 +    "version": 1,
 +    "disable_existing_loggers": False,
 +    "formatters": { },
 +    "handlers": { },
 +    "loggers": { },
 +    "root": { },
 +}
 +</code>
 +
 +
 +
 +Для использования JSON нужен модуль [[https://pypi.org/project/python-json-logger/|"python-json-logger"]]\\
 +
 +
 +<details>
 +<summary>:!: Боевой пример. Три типа логов </summary>
 +Три типа логов:
 +  * Общий
 +  * Только ошибки
 +  * Логирование спец событий, в данном случае д-я пользователей
 +
 +
 +Использование
 +<code python>
 +#!/usr/bin/python3.8
 +
 +import loggers
 +
 +logger = loggers.get_logger('main')
 +usr_logger = loggers.get_logger('usrlog', template = "usr_actions")
 +
 +logger.info("Simple logger, level == info")
 +logger.error("Simple logger, level == error")
 +
 +usr_logger.info("User log, level == info", extra={"username": "myname"})
 +</code>
 +
 +
 +Создание объекта логгера
 +<code python>
 +#!/usr/bin/python3.8
 +
 +import os
 +import json
 +import logging
 +import logging.config
 +
 +FOLDER_LOG = "log"
 +LOGGING_CONFIG_FILE = 'logger_config.json'
 +
 +
 +def create_log_folder(folder=FOLDER_LOG):
 + if not os.path.exists(folder):
 + os.mkdir(folder)
 +
 +
 +def get_logger(name, template='simple'):
 + create_log_folder()
 + with open(LOGGING_CONFIG_FILE, "r") as f:
 + dict_config = json.load(f)
 + dict_config["loggers"][name] = dict_config["loggers"][template]
 + logging.config.dictConfig(dict_config)
 + return logging.getLogger(name)
 +</code>
 +
 +
 +Конфиг
 +<code xml>
 +{
 +    "version": 1,
 +    "disable_existing_loggers": false,
 +    "formatters": {
 +        "strings": {
 +            "format": "%(asctime)s - %(processName)-10s - %(name)-10s - %(levelname)-8s - %(message)s",
 +            "datefmt": "%Y-%m-%d %H:%M:%S"
 +        },
 +        "json": {
 +            "()": "pythonjsonlogger.jsonlogger.JsonFormatter",
 +            "format": "[ %(asctime)s ] %(username)s %(message)s",
 +            "datefmt": "%Y-%m-%d %H:%M:%S",
 +            "json_indent": 4
 +        }
 +    },
 +    "handlers": {
 +        "mainlog": {
 +            "formatter": "strings",
 +            "level": "INFO",
 +            "class": "logging.handlers.RotatingFileHandler",
 +            "filename": "log/main.log",
 +            "backupCount": 2
 +        },
 +        "errorlog": {
 +            "formatter": "strings",
 +            "level": "ERROR",
 +            "class": "logging.handlers.RotatingFileHandler",
 +            "filename": "log/error.log",
 +            "backupCount": 2
 +        },
 +        "json": {
 +            "formatter": "json",
 +            "level": "INFO",
 +            "class": "logging.handlers.RotatingFileHandler",
 +            "filename": "log/usrlog.xml"
 +        }
 +    },
 +    "loggers": {
 +        "simple": {
 +            "level": "DEBUG",
 +            "handlers": ["mainlog", "errorlog"]
 +        },
 +        "usr_actions": {
 +            "level": "DEBUG",
 +            "handlers": ["json"]
 +        }
 +    }
 +}
 +</code>
 +</details>
 +
 +
 +
 +===== Примеры =====
 +<details>
 +<summary>:!: Минимальный пример для логирования</summary>
 +<code python>
 +import logging
 +from datetime import datetime
 +
 +start_date = datetime.strftime(datetime.now(), "%Y%m%d_%H%M%S")
 +log_path = f"{start_date}.log"
 +
 +#Настройка логирования.
 +log = logging.getLogger()
 +log.setLevel(logging.INFO)
 +fh = logging.FileHandler(filename=log_path)
 +fh.setLevel(logging.INFO)
 +formatter = logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s')
 +fh.setFormatter(formatter)
 +log.addHandler(fh)
 +
 +log.info("test test ")
 +</code>
 +</details>
 +
 +
 +<details>
 +<summary>:!: Еще примеры </summary>
 +<code python>
 +import logging
 +
 +logging.basicConfig(
 +    level=logging.DEBUG,
 +    filename = "mylog.log",
 +    format = "%(asctime)s - %(module)s - %(levelname)s - %(funcName)s: %(lineno)d - %(message)s",
 +    datefmt='%H:%M:%S',
 +    )
 +
 +logging.info('Hello')
 +</code>
 +
 +
 +<code python>
 +import logging
 +
 +logging.basicConfig(level=logging.INFO, filename="py_log.log",filemode="w",
 +                    format="%(asctime)s %(levelname)s %(message)s")
 +                    
 +x_vals = [2,3,6,4,10]
 +y_vals = [5,7,12,0,1]
 +
 +for x_val,y_val in zip(x_vals,y_vals):
 +    x,y = x_val,y_val
 +    logging.info(f"The values of x and y are {x} and {y}.")
 +    try:
 +        x/y
 +        logging.info(f"x/y successful with result: {x/y}.")
 +    except ZeroDivisionError as err:
 +        #logging.exception("ZeroDivisionError")
 +        logging.error("ZeroDivisionError",exc_info=True)
 +</code>
 +
 +
 +<code python>
 +import logging
 +from test_div import test_division 
 +
 +# получение пользовательского логгера и установка уровня логирования
 +py_logger = logging.getLogger(__name__)
 +py_logger.setLevel(logging.INFO)
 +
 +# настройка обработчика и форматировщика в соответствии с нашими нуждами
 +py_handler = logging.FileHandler(f"{__name__}.log", mode='w')
 +py_formatter = logging.Formatter("%(name)s %(asctime)s %(levelname)s %(message)s")
 +
 +# добавление форматировщика к обработчику 
 +py_handler.setFormatter(py_formatter)
 +# добавление обработчика к логгеру
 +py_logger.addHandler(py_handler)
 +
 +py_logger.info(f"Testing the custom logger for module {__name__}...")
 +
 +x_vals = [2,3,6,4,10]
 +y_vals = [5,7,12,0,1]
 +
 +for x_val,y_val in zip(x_vals,y_vals):
 +    x,y = x_val, y_val
 +    # вызов test_division
 +    test_division(x,y)
 +    py_logger.info(f"Call test_division with args {x} and {y}")
 +</code>
 +
 +</details>
 +
 +
develop/pyton/logger.1670045563.txt.gz · Последнее изменение: 2022/12/03 05:32 — admin