python - 使用一个记录器和多个几乎相同的文件处理程序
问题描述
我有一个负责 2 个流的服务:A 和 B。这些流是连接的,但我想将每个流记录在不同的日志文件中。
我想使用以下配置文件:
[loggers]
keys=root,A,B
[handlers]
keys=file_handler
[formatters]
keys=full
[logger_A]
level=INFO
handlers=fileHandler
[logger_B]
level=INFO
handlers=fileHandler
[logger_root]
level=INFO
handlers=fileHandler
[handler_fileHandler]
class=FileHandler
level=INFO
formatter=full
args=('%(logfilename)s','%(permissions)s','%(encoding)s',)
[formatter_full]
format=[%(asctime)s] [%(levelname)s] --- [%(funcName)s] [P%(process)d][%(threadName)s - %(thread)d]- %(message)s
datefmt='%Y-%m-%d %H:%M:%S'
据我了解,没有任何方法可以在运行时动态地将这些参数发送到 fileHandler,对吧?处理程序对所有记录器具有相同的属性,区别在于记录器写入的目标文件。
我考虑过配置一个函数,该函数将获取记录器名称和目标文件作为输入并将记录器返回给我 - 这是在记录到具有不同设置的两个文件中建议的内容:
import logging
def getLoggerToFile(loggerName,filePath,fileMode,fileHandler=None,level=logging.INFO):
logger = logging.getLogger(loggerName)
if len(logger.handlers) > 0:
return logger
if(fileHandler is None):
formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] --- [%(funcName)s] '
'[P%(process)d][%(threadName)s - %(thread)d]- %(message)s')
fileHandler = logging.FileHandler(filePath, mode=fileMode)
fileHandler.setFormatter(formatter)
logger.setLevel(level)
logger.addHandler(fileHandler)
return logger
想听听任何其他建议并提出问题:
如果我将使用该函数,并且我将使用相同的记录器名称但具有不同的文件路径两次调用该函数,那么记录器将无法同时写入 2 个不同的文件,对吗?因此,它与创建一个包含 2 个记录器和每个记录器的处理程序/格式化程序的配置文件相同。
解决方案
可以使用一个过滤器和两个处理程序来做到这一点。创建一个记录器和两个 FileHandler。向每个处理程序添加一个过滤器,该过滤器只允许消息进入属于该流的文件。您可以使用 LogRecord 中存在的任何信息来决定消息的去向。下面的代码使用了extra
日志记录方法的 kwarg,但是如果日志中已经存在某些内容来决定不需要的流程。以下是文档相关部分的一些链接:
FilterObjects
LogRecord attributes
import logging
class Filter:
def __init__(self, flow):
self.flow = flow
def filter(self, record):
if record.flow == self.flow:
return True
handlerA = logging.FileHandler('A.log')
handlerB = logging.FileHandler('B.log')
handlerA.addFilter(Filter('a'))
handlerB.addFilter(Filter('b'))
logger = logging.getLogger()
logger.addHandler(handlerA)
logger.addHandler(handlerB)
logger.warning('message A', extra={'flow':'a'}) # writes only to A.log
logger.warning('message B', extra={'flow':'b'}) # writes only to B.log
推荐阅读
- awk - 识别分层文件bash脚本中的行
- homebrew - 自制:没有瓶子的夹子
- python - 为什么错误处理在 repl 中不起作用,但在 VSCode 中起作用?不和谐.py
- python - Python Selenium 查找表的 Xpath
- r - 中位数和 IQR “NA”
- android - 如何为 Flutter 应用程序创建 Firebase 火库
- bash - 观看并粘贴命令
- python - 如何正确调用函数并返回更新的数据框?
- visual-studio-code - vscode中option-n的奇怪行为
- apache-spark - databricks spark - 集群本身是性能低下的原因吗?