如何配置 YAML 以创建新的日志文件而不是附加它们?

How to configure YAML to create fresh log files instead of appending them?

在下面给出的 python 记录器实现中,每次我 运行 我的程序,日志都会 附加 到现有的日志文件。我如何确保每次 运行 我的应用程序代码都被写入新的日志文件?

发生这种情况是因为我将 RotatingFileHandler 的备份计数设置为 20,每个文件大小为 10MB?我应该将它转换为简单的文件处理程序吗?

我在 python 记录器中使用以下基于 yaml 的日志配置。

  1 version: 1
  2
  3 formatters:
  4   simple:
  5     format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
  6
  7 handlers:
  8   console:
  9     class: logging.StreamHandler
 10     level: DEBUG
 11     formatter: simple
 12     stream: ext://sys.stdout
 13
 14   info_handler:
 15     class: logging.handlers.RotatingFileHandler
 16     level: INFO
 17     formatter: simple
 18     filename: info.log
 19     maxBytes: 10485760 # 10MB
 20     backupCount: 20
 21     encoding: utf8
 22
 23   error_handler:
 24     class: logging.handlers.RotatingFileHandler
 25     level: ERROR
 26     formatter: simple
 27     filename: errors.log
 28     maxBytes: 10485760 # 10MB
 29     backupCount: 20
 30     encoding: utf8
 31
 32 loggers:
 33   my_module:
 34     level: ERROR
 35     handlers: [console]
 36     propagate: no
 37
 38 root:
 39   level: DEBUG
 40   handlers: [info_handler, info_handler]

我正在使用以下 python 记录器初始化程序代码来初始化我的记录器。

  1 import os
  2 import logging.config
  3 import yaml
  4
  5 """Setup logging configuration """
  6 default_path='logging.yaml'
  7 default_level=logging.INFO
  8 env_key='LOG_CFG'
  9
 10 class MyLogger():
 11
 12     def __init__(self):
 13         path = default_path
 14         value = os.getenv(env_key, None)
 15         if value:
 16             path = value
 17         if os.path.exists(path):
 18             with open(path, 'rt') as f:
 19                 config = yaml.safe_load(f.read())
 20             logging.config.dictConfig(config)
 21         else:
 22             logging.basicConfig(filemode='w', level=default_level)

设置filemodew,默认为a(追加)。

或者只需添加以下行来覆盖您的旧日志文件(在读取 yaml 文件之后):

with open(config['handlers']['info_handler']['filename'], 'w') as f:
    pass

我知道这已经有一个可接受的答案,但我不确定它是否非常 cleanly/entirely 回答了这个问题,我添加这个答案以防其他人遇到类似问题。相反,将其包含在配置 YAML 文件中的一个选项:

handlers:
    info_file_handler:
       class: logging.FileHandler
       formatter: complex
       filename: log_info.log
       mode: 'w'

mode 中的 'w' 与 basicConfig() 中使用的 filemode 选项相同,本质上是覆盖日志文件而不是附加(这将是选项 'a')。我还认为模式键可以用于 RotatingFileHandler。

然后我添加到我的主要代码中,以便每个文件名随每个模型 运行 更改(这目前每天都会更改日志文件名 [我有一个日常程序 运行ning])。见下文:

def setup_logging(default_path="logging_config.yml",
                  default_level=logging.INFO,
                  env_key="LOG_CFG"):

    """
    Setup logging configuration

    This reads a .yml file and extracts the relevant logging information
    required by the logging module.

    """

    path = default_path
    value = os.getenv(env_key, None)

    if value:
         path = value

    # Open the logging configuration file
    if os.path.exists(path):
        with open(path, "rb") as f:
            config = yaml.safe_load(f.read())

            # Append the date stamp to the filename for each handler
            # This is so each log file has a unique filename if run
            # on a separate date.
            # This can be changed to suit needs, hourly/minutely etc.
            for i in (config["handlers"].keys()):
                # Check if filename in handler.
                # Console handlers might be present in config file
                if 'filename' in config['handlers'][i]:
                    log_filename = config["handlers"][i]["filename"]
                    base, extension = os.path.splitext(log_filename)
                    today = datetime.datetime.today()
                    log_filename = "{}{}{}".format(base,
                                               today.strftime("_%Y_%m_%d"),
                                               extension)
                config["handlers"][i]["filename"] = log_filename

        logging.config.dictConfig(config)

    else:
        logging.basicConfig(level=default_level)

我希望这对您有所帮助,如果接受的答案确实对您有用,我深表歉意,我只是觉得这是对 OP 提出的问题的更清晰的解决方案。