使用两个处理程序进行日志记录 - 一个用于文件,一个用于 stderr
Logging with two handlers - one to file and one to stderr
我有以下代码来创建两个日志记录处理程序。目标是让 stream_handler
只写入 sterr
,file_handler
只写入文件。
在下面的代码中,stream_handler
也会写入文件,所以每当我记录一条消息时,我都会有重复的日志条目。我如何修改它才能让 stream_handler
而不是 写入文件?
def create_timed_rotating_log(
name='log',
path='logs/',
when='D',
interval=1,
backupCount=30,
form='%(asctime)s | %(name)s | %(levelname)s: %(message)s',
sterr = False,
verbose=False):
logger = logging.getLogger(name)
formatter = logging.Formatter(form)
logger.setLevel(logging.DEBUG)
if sterr:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
file_handler = TimedRotatingFileHandler(filename=path+name,
when=when,
interval=interval,
backupCount=backupCount)
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
logger.addHandler(file_handler)
return logger
您似乎已经考虑过将消息发送到两个处理程序是重复的。如果您希望文件不接收消息并且它们只转到 stderr,当 stderr=True 时,您永远不要将添加文件处理程序的代码放在 else 中,以便仅在 stderr=False[=14= 时才添加它]
具体来说:
if sterr:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
else:
file_handler = TimedRotatingFileHandler(filename=path+name,
when=when,
interval=interval,
backupCount=backupCount)
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
logger.addHandler(file_handler)
我认为这是可能的,但与更常见的多次设置处理程序的问题相比,当您应该如何使用日志记录时,在主模块中将处理程序添加到根记录器,然后只获取通过 logger = logging.getLogger(__name__)
当前模块的记录器。这和 import logging
是唯一应该出现在 if __name__=="__main__":
出现的模块中的唯一日志记录代码,紧接着它应该设置日志记录。
唯一会出现重复的方法是在程序中调用该函数两次。问题不在于这两个处理程序,而是第二次调用此设置函数的其他两个处理程序。
您只需将处理程序添加到根记录器一次,而不是为每个模块中的每个记录器添加一次。
不确定为什么会这样,但首先添加 StreamHandler 会导致它也写入文件。在添加 TimedRotatingFileHandler 之后,我将 StreamHandler 移动到了,这解决了问题。
我有以下代码来创建两个日志记录处理程序。目标是让 stream_handler
只写入 sterr
,file_handler
只写入文件。
在下面的代码中,stream_handler
也会写入文件,所以每当我记录一条消息时,我都会有重复的日志条目。我如何修改它才能让 stream_handler
而不是 写入文件?
def create_timed_rotating_log(
name='log',
path='logs/',
when='D',
interval=1,
backupCount=30,
form='%(asctime)s | %(name)s | %(levelname)s: %(message)s',
sterr = False,
verbose=False):
logger = logging.getLogger(name)
formatter = logging.Formatter(form)
logger.setLevel(logging.DEBUG)
if sterr:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
file_handler = TimedRotatingFileHandler(filename=path+name,
when=when,
interval=interval,
backupCount=backupCount)
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
logger.addHandler(file_handler)
return logger
您似乎已经考虑过将消息发送到两个处理程序是重复的。如果您希望文件不接收消息并且它们只转到 stderr,当 stderr=True 时,您永远不要将添加文件处理程序的代码放在 else 中,以便仅在 stderr=False[=14= 时才添加它]
具体来说:
if sterr:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
else:
file_handler = TimedRotatingFileHandler(filename=path+name,
when=when,
interval=interval,
backupCount=backupCount)
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.DEBUG if verbose else logging.ERROR)
logger.addHandler(file_handler)
我认为这是可能的,但与更常见的多次设置处理程序的问题相比,当您应该如何使用日志记录时,在主模块中将处理程序添加到根记录器,然后只获取通过 logger = logging.getLogger(__name__)
当前模块的记录器。这和 import logging
是唯一应该出现在 if __name__=="__main__":
出现的模块中的唯一日志记录代码,紧接着它应该设置日志记录。
唯一会出现重复的方法是在程序中调用该函数两次。问题不在于这两个处理程序,而是第二次调用此设置函数的其他两个处理程序。
您只需将处理程序添加到根记录器一次,而不是为每个模块中的每个记录器添加一次。
不确定为什么会这样,但首先添加 StreamHandler 会导致它也写入文件。在添加 TimedRotatingFileHandler 之后,我将 StreamHandler 移动到了,这解决了问题。