跨多个模块记录始终更改文件名
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__)
.
我有一个带有硬编码日志文件名的日志记录功能 (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__)
.