繁体   English   中英

Python中如何正确登录不同的文件?

[英]How to log into different files properly in Python?

我在下面有一个记录器配置 class,my_logger.py:

def my_logger(module_name, log_file):
    logger = logging.getLogger(module_name)
    logger.setLevel(logging.DEBUG)

    # Create handlers
    c_handler = logging.StreamHandler()
    f_handler = logging.handlers.RotatingFileHandler(filename=log_file)
    c_handler.setLevel(logging.DEBUG)
    f_handler.setLevel(logging.DEBUG)

    # Create formatters and add it to handlers
    c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    c_handler.setFormatter(c_format)
    f_handler.setFormatter(f_format)

    # Add handlers to the logger
    logger.addHandler(c_handler)
    logger.addHandler(f_handler)

    return logger

这个 my_logger.py 在 package 根目录下:

my_package:
    my_logger.py
    test.py
    api/api.py
    logs/

然后在我的 test.py 中:

abspath = os.path.abspath(os.path.dirname(__file__))

logger_info = logger.my_logger("test_info", os.path.join(abspath,"../logs/info.log"))
logger_debug = logger.my_logger("test_debug", os.path.join(abspath,"../logs/debug.log"))
logger_error = logger.my_logger("test_error", os.path.join(abspath,"../logs/error.log"))

logger_info.info('Info test ...')
logger_debug.debug('Debug test ...')
logger_error.error('Error test ...')

我想调试到 debug.log,到 info.log 和错误到 error.log。

对于我要记录的每个文件,我需要在每个文件中添加以下 3 行:

logger_info = logger.my_logger(module_info, os.path.join(abspath,"../logs/info.log"))
logger_debug = logger.my_logger(module_debug, os.path.join(abspath,"../logs/debug.log"))
logger_error = logger.my_logger(module_error, os.path.join(abspath,"../logs/error.log"))

这是正常的做法吗? 我希望从所有模块到 go 的所有日志消息都放入 logs/ 下的相同 3 个文件中。

简短的回答

要完全实现您所描述的,您需要 3 个处理程序(在您的示例中有),并将它们的默认级别设置为顶部的相应级别。 无需单独设置处理程序的级别。

import logging
from logging import handlers

def my_logger(module_name, log_file, level):
    logger = logging.getLogger(module_name)
    logger.setLevel(level)

    # Create handlers
    c_handler = logging.StreamHandler()
    f_handler = handlers.RotatingFileHandler(filename=log_file)

    # Create formatters and add it to handlers
    c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    c_handler.setFormatter(c_format)
    f_handler.setFormatter(f_format)

    # Add handlers to the logger
    logger.addHandler(c_handler)
    logger.addHandler(f_handler)

    return logger

if __name__ == "__main__":
    logger_info = my_logger("test_info", "info.log", logging.INFO)
    logger_debug = my_logger("test_debug", "debug.log", logging.DEBUG)
    logger_error = my_logger("test_error", "error.log", logging.ERROR)

    logger_info.info('Info test ...')
    logger_debug.debug('Debug test ...')
    logger_error.error('Error test ...')

Output:

python test_logger2.py 
2020-12-04 16:57:00,771 - test_info - INFO - 29 - Info test ...
2020-12-04 16:57:00,771 - test_debug - DEBUG - 30 - Debug test ...
2020-12-04 16:57:00,771 - test_error - ERROR - 31 - Error test ...

cat info.log 
2020-12-04 16:57:00,771 - test_info - INFO - 29 - Info test ...

cat debug.log 
2020-12-04 16:57:00,771 - test_debug - DEBUG - 30 - Debug test ...

cat error.log 
2020-12-04 16:57:00,771 - test_error - ERROR - 31 - Error test ...

长答案:

  1. 为什么要3份?
    您正在调用my_logger function 3 次,每次调用它时都会调用一个新的文件处理程序以及添加到记录器的新 stream 处理程序。 这就是为什么您会在控制台上看到 3 个副本(3 个 stream 处理程序)。 另外,您的所有处理程序都设置为DEBUG级别。 这就是为什么所有三个记录器都会打印出您提供的任何日志的原因。 您不希望ERROR处理程序在DEBUG / INFO级别处理/打印日志,因此您应该将其级别设置为ERROR

  2. 我不认为这是记录日志的标准方法。 相反,您应该使用带有 4 个处理程序(stream、file_debug、file_info、file_error)的单个记录器。 此外,调试日志文件应包含所有日志,信息日志文件应包含信息日志和错误日志。 详情如下。

import logging
from logging import handlers

def main():

    logger = logging.getLogger()
    c_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')

    # You need to set the default level to the lowest (DEBUG)
    logger.setLevel(logging.DEBUG)

    c_handler = logging.StreamHandler()
    c_handler.setLevel(logging.DEBUG)
    c_handler.setFormatter(c_format)

    f1_handler = handlers.RotatingFileHandler("debug.log")
    f1_handler.setLevel(logging.DEBUG)
    f1_handler.setFormatter(c_format)

    f2_handler = logging.handlers.RotatingFileHandler("info.log")
    f2_handler.setLevel(logging.INFO)
    f2_handler.setFormatter(c_format)

    f3_handler = logging.handlers.RotatingFileHandler("error.log")
    f3_handler.setLevel(logging.ERROR)
    f3_handler.setFormatter(c_format)

    logger.addHandler(c_handler)
    logger.addHandler(f1_handler)
    logger.addHandler(f2_handler)
    logger.addHandler(f3_handler)

    logger.debug("A debug line")
    logger.info("An info line")
    logger.error("An error line")

if __name__ == "__main__":
    main()

output 是:

python test_logger.py 
2020-12-04 16:48:56,247 - root - DEBUG - 32 - A debug line
2020-12-04 16:48:56,248 - root - INFO - 33 - An info line
2020-12-04 16:48:56,248 - root - ERROR - 34 - An error line

cat debug.log 
2020-12-04 16:49:06,673 - root - DEBUG - 32 - A debug line
2020-12-04 16:49:06,673 - root - INFO - 33 - An info line
2020-12-04 16:49:06,673 - root - ERROR - 34 - An error line

cat info.log 
2020-12-04 16:49:06,673 - root - INFO - 33 - An info line
2020-12-04 16:49:06,673 - root - ERROR - 34 - An error line

cat error.log 
2020-12-04 16:49:06,673 - root - ERROR - 34 - An error line

在这里您可以看到debug.log文件还包含其他级别的日志,并且您的info.log文件也包含错误日志。 因为这就是日志级别背后的全部原理。 较低级别还应该跟踪较高级别的日志( DEBUG < INFO < WARNING < ERROR )。 这就是为什么您想要的不是标准的方法,而是可以完美地实现,如简短答案中所述。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM