有两个不同的处理程序用于登录python日志记录模块

时间:2019-12-16 10:45:24

标签: python logging

我正在尝试使用两种不同的处理程序,其中一个处理程序将在控制台上打印日志,而另一个处理程序将在控制台上打印日志。 Conslole处理程序由一个内置的python modbus-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")

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

编辑:

从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)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

2 个答案:

答案 0 :(得分:1)

我有一个自定义的日志记录模块。我做了一些修改,我认为现在可以解决您的问题。它是完全可配置的,并且可以处理更多不同的处理程序。

如果要将控制台日志记录和文件日志记录结合起来,则只需要删除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)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")

控制台输出:

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

日志文件的内容:

info to file

答案 1 :(得分:1)

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

首先,当您调用basicConfig时,您正在配置root记录器,并告诉它创建一个文件名为FileHandler的{​​{1}},但是之后仅需两行即可创建一个使用相同文件的log。这两个记录器现在正在写入同一文件。

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

如果您也不想将所有日志都发送到根记录器,则应设置RotatingFileHandler。这阻止了该记录器传播其日志。