Это старая версия документа!
Классы логгера наследуются, в блоке «root» можно определить базовые параметры для всех создаваемых потом подклассов
Собсна структура конфига ниже, перечисляются форматтеры, логгеры, хендлеры, можно создавать несколько разных комбинаций, каждая со своими параметрами и для каждой применяются указанные правила логирования (место, формат, устр-во и т.д.)
Лучше хранить в отдельном «xml» файле
{ "version": 1, "disable_existing_loggers": False, "formatters": { }, "handlers": { }, "loggers": { }, "root": { }, }
Использование
import loggers logger = loggers.get_logger('main') logger.info("This is test text, level == info") logger.error("This is test text, level == error")
Объект логгера. Думаю тут можно переработать/оптимизировать, сырой пример
#!/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='default'): 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) def get_default_logger(): create_log_folder() with open(LOGGING_CONFIG_FILE, "r") as f: logging.config.dictConfig(json.load(f)) return logging.getLogger("default")
Конфиг
{ "version": 1, "disable_existing_loggers": false, "formatters": { "default": { "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 ] %(levelname)s %(message)s", "datefmt": "%d/%m/%y ( %H:%M:%S )", "rename_fields": { "asctime": "time", "levelname": "level" }, "json_indent": 4 } }, "handlers": { "logfile": { "formatter": "default", "level": "ERROR", "class": "logging.handlers.RotatingFileHandler", "filename": "log/main.log", "backupCount": 2 }, "json": { "formatter": "json", "class": "logging.handlers.RotatingFileHandler", "filename": "log/main.xml" }, "console": { "formatter": "default", "level": "ERROR", "class": "logging.StreamHandler", "stream": "ext://sys.stdout" } }, "loggers": { "default": { "level": "INFO", "handlers": ["logfile", "json", "console"] } } }
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')
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)
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}")