在 python 日志记录模块中有两个不同的日志记录处理程序



我正在尝试使用两个不同的处理程序,其中一个处理程序将在控制台上打印日志,另一个不同的处理程序将在控制台上打印日志。Conslole 处理程序由一个内置的 pythonmodbus-tk库提供,我已经编写了自己的文件处理程序。

LOG = utils.create_logger(name="console", record_format="%(message)s") . ---> This is from modbus-tk library
LOG = utils.create_logger("console", level=logging.INFO)
logging.basicConfig(filename="log", level=logging.DEBUG)
log = logging.getLogger("simulator")
handler = RotatingFileHandler("log",maxBytes=5000,backupCount=1)
log.addHandler(handler)

我需要什么:

LOG.info("This will print message on console")
log.info("This will print message in file")

但问题是日志都在控制台上打印,并且都在文件中。我只想在控制台上打印LOGlog打印在文件中。

编辑:

从utils.create_logger添加代码段

def create_logger(name="dummy", level=logging.DEBUG, record_format=None):
"""Create a logger according to the given settings"""
if record_format is None:
record_format = "%(asctime)st%(levelname)st%(module)s.%(funcName)st%(threadName)st%(message)s"
logger = logging.getLogger("modbus_tk")
logger.setLevel(level)
formatter = logging.Formatter(record_format)
if name == "udp":
log_handler = LogitHandler(("127.0.0.1", 1975))
elif name == "console":
log_handler = ConsoleHandler()
elif name == "dummy":
log_handler = DummyHandler()
else:
raise Exception("Unknown handler %s" % name)
log_handler.setFormatter(formatter)
logger.addHandler(log_handler)
return logger

我有一个自己的自定义日志记录模块。我已经修改了一点,我认为现在它可以适合您的问题。它是完全可配置的,它可以处理更多不同的处理程序。

如果要合并控制台和文件日志记录,则只需删除 return 语句(我使用这种方式(。

我已经为代码写了注释以使其更易于理解,您可以在if __name__ == "__main__": ...语句中找到测试部分。

法典:

import logging
import os

# Custom logger class with multiple destinations
class CustomLogger(logging.Logger):
"""
Customized Logger class from the original logging.Logger class.
"""
# Format for console log
FORMAT = (
"[%(name)-30s][%(levelname)-19s] | %(message)-100s "
"| (%(filename)s:%(lineno)d)"
)
# Format for log file
LOG_FILE_FORMAT = "[%(name)s][%(levelname)s] | %(message)s " "| %(filename)s:%(lineno)d)"
def __init__(
self,
name,
log_file_path=None,
console_level=logging.INFO,
log_file_level=logging.DEBUG,
log_file_open_format="w",
):
logging.Logger.__init__(self, name)
consol_color_formatter = logging.Formatter(self.FORMAT)
# If the "log_file_path" parameter is provided,
# the logs will be visible only in the log file.
if log_file_path:
fh_formatter = logging.Formatter(self.LOG_FILE_FORMAT)
file_handler = logging.FileHandler(log_file_path, mode=log_file_open_format)
file_handler.setLevel(log_file_level)
file_handler.setFormatter(fh_formatter)
self.addHandler(file_handler)
return
# If the "log_file_path" parameter is not provided,
# the logs will be visible only in the console.
console = logging.StreamHandler()
console.setLevel(console_level)
console.setFormatter(consol_color_formatter)
self.addHandler(console)

if __name__ == "__main__":  # pragma: no cover
current_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_log.log")
console_logger = CustomLogger(__file__, console_level=logging.INFO)
file_logger = CustomLogger(__file__, log_file_path=current_dir, log_file_level=logging.DEBUG)
console_logger.info("test_to_console")
file_logger.info("test_to_file")

控制台输出:

>>> python3 test.py
[test.py][INFO               ] | test_to_console                                                                                      | (test.py:55)

test_log.log文件内容:

[test.py][INFO] | test_to_file | test.py:56)

如果有什么不清楚的问题/意见,请告诉我,我会尽力提供帮助。

编辑:

如果在实现中将GetLogger更改为Logger,它将起作用。

法典:

import logging

def create_logger(name="dummy", level=logging.DEBUG, record_format=None):
"""Create a logger according to the given settings"""
if record_format is None:
record_format = "%(asctime)st%(levelname)st%(module)s.%(funcName)st%(threadName)st%(message)s"
logger = logging.Logger("modbus_tk")
logger.setLevel(level)
formatter = logging.Formatter(record_format)
if name == "console":
log_handler = logging.StreamHandler()
else:
raise Exception("Wrong type of handler")
log_handler.setFormatter(formatter)
logger.addHandler(log_handler)
return logger

console_logger = create_logger(name="console")
# logging.basicConfig(filename="log", level=logging.DEBUG)
file_logger = logging.Logger("simulator")
handler = logging.FileHandler("log", "w")
file_logger.addHandler(handler)
console_logger.info("info to console")
file_logger.info("info to file")

控制台输出:

>>> python3 test.py
2019-12-16 13:10:45,963 INFO    test.<module>   MainThread      info to console

日志文件内容:

info to file

您的代码中存在一些问题,如果不看到整个配置,很难说出究竟是什么原因造成的,但最有可能发生的事情是日志被传播。

首先,当您调用basicConfig时,您正在配置根记录器并告诉它创建一个文件名为logFileHandler,但之后只需两行,您就会创建一个使用相同文件的RotatingFileHandler。两个记录器现在都在写入同一个文件。

我发现它总是有助于理解 python 中日志记录的工作方式:https://docs.python.org/3/howto/logging.html#logging-flow

如果您不希望将所有日志也发送到根记录器,则应设置LOG.propagate = False。这会阻止此记录器传播其日志。

最新更新