跨多个模块记录始终更改文件名

Logging across multiple modules with always changing filenames

我有一个带有硬编码日志文件名的日志记录功能 (LOG_FILE):

setup_logger.py

import logging
import sys

FORMATTER = logging.Formatter("%(levelname)s - %(asctime)s - %(name)s - %(message)s")
LOG_FILE = "my_app.log"

def get_console_handler():
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setFormatter(FORMATTER)
    return console_handler

def get_file_handler():
    file_handler = logging.FileHandler(LOG_FILE)
    file_handler.setFormatter(FORMATTER)
    return file_handler

def get_logger(logger_name):
    logger = logging.getLogger(logger_name)

    logger.setLevel(logging.DEBUG) # better to have too much log than not enough

    logger.addHandler(get_console_handler())
    logger.addHandler(get_file_handler())

    # with this pattern, it's rarely necessary to propagate the error up to parent
    logger.propagate = False

    return logger

我以这种方式在各种模块中使用它:

main.py

from _Core import setup_logger as log

def main(incoming_feed_id: int, type: str) -> None:
    logger = log.get_logger(__name__)
    ...rest of my code

database.py

from _Core import setup_logger as log
logger = log.get_logger(__name__)

Class Database:
...rest of my code

etl.py

import _Core.database as db
from _Core import setup_logger as log
logger = log.get_logger(__name__)

Class ETL:
...rest of my code

我想要实现的是始终根据传递给 main.py 中的 main() 函数的参数更改每个 运行 上的日志文件的路径和名称。 简化示例: 如果 main() 接收到以下参数:incoming_feed_id = 1,类型 = simple_load,日志文件的名称应该是 1simple_load.log.

我不确定对此的最佳做法是什么。我想到的可能是最糟糕的做法:在 setup_logger.py 中的 get_logger() 函数中添加一个 log_file 参数,这样我就可以在 main.py。但在这种情况下,我还需要将参数从 main 传递到其他模块,我认为我不应该这样做,例如数据库 class 甚至没有在 main.py 中使用。

我对您的应用程序了解不多,无法确保这对您有用,但您可以通过调用 get_logger('', filename_based_on_cmdline_args)main() 中配置根记录器,然后将内容记录到如果配置的记录器级别允许,其他记录器将传递给根记录器的处理程序进行处理。你现在这样做的方式似乎打开了指向同一个文件的多个处理程序,这似乎 sub-optimal。其他模块可以只使用 logging.getLogger(__name__) 而不是 log.get_logger(__name__).