首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python日志模块中有两个不同的日志处理程序

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

Stack Overflow用户
提问于 2019-12-16 10:45:24
回答 2查看 541关注 0票数 1

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

代码语言:javascript
复制
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)

我需要的是:

代码语言:javascript
复制
LOG.info("This will print message on console")

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

但是问题是,两个日志都被打印在控制台上,并且都在文件中。我只希望在控制台上打印LOG,在文件中打印log

编辑:

从utils.create_logger添加代码段

代码语言:javascript
复制
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)s\t%(levelname)s\t%(module)s.%(funcName)s\t%(threadName)s\t%(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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-16 11:16:21

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

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

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

代码:

代码语言:javascript
复制
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")

控制台输出:

代码语言:javascript
复制
>>> python3 test.py
[test.py][INFO               ] | test_to_console                                                                                      | (test.py:55)

test_log.log文件内容:

代码语言:javascript
复制
[test.py][INFO] | test_to_file | test.py:56)

如果你有什么不清楚的地方,请告诉我,我会尽力帮忙的。

编辑:

如果在您的实现中将GetLogger更改为Logger,它将工作。

代码:

代码语言:javascript
复制
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)s\t%(levelname)s\t%(module)s.%(funcName)s\t%(threadName)s\t%(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")

控制台输出:

代码语言:javascript
复制
>>> python3 test.py
2019-12-16 13:10:45,963 INFO    test.<module>   MainThread      info to console

日志文件的内容:

代码语言:javascript
复制
info to file
票数 1
EN

Stack Overflow用户

发布于 2019-12-16 12:27:48

您的代码中有一些问题,如果没有看到整个配置,就很难知道到底是什么原因造成的,但最有可能的情况是日志被传播了。

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

我发现理解python:https://docs.python.org/3/howto/logging.html#logging-flow中日志记录的流程总是有帮助的。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59355018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档