首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python日志记录-每次循环迭代都有新的日志文件

Python日志记录-每次循环迭代都有新的日志文件
EN

Stack Overflow用户
提问于 2019-02-08 19:22:40
回答 4查看 6.5K关注 0票数 4

我想使用日志模块在Python中每次循环迭代时生成一个新的日志文件。我正在分析for循环中的数据,其中循环的每次迭代都包含一个新对象的信息。我想为每个对象生成一个日志文件。

我查看了日志模块的文档,可以按时间间隔或在日志文件填满时更改日志文件,但我看不到如何使用新名称迭代生成新的日志文件。我提前知道循环中有多少对象。

我想象的伪代码是:

代码语言:javascript
复制
import logging

for target in targets:
    logfile_name = f"{target}.log"
    logging.basicConfig(format='%(asctime)s - %(levelname)s : %(message)s',
                        datefmt='%Y-%m/%dT%H:%M:%S',
                        filename=logfile_name,
                        level=logging.DEBUG)


    # analyse target infomation
    logging.info('log target info...')

但是,日志记录信息始终附加到目标1的第一个日志文件中。

有没有办法强制在每个循环开始时创建一个新的日志文件?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-02-08 20:02:11

您需要使用记录器对象,而不是直接使用logging。浏览文档here

创建一个新的记录器对象作为循环中的第一条语句。下面是一个可行的解决方案。

代码语言:javascript
复制
import logging
import sys


def my_custom_logger(logger_name, level=logging.DEBUG):
    """
    Method to return a custom logger with the given name and level
    """
    logger = logging.getLogger(logger_name)
    logger.setLevel(level)
    format_string = ("%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:"
                    "%(lineno)d — %(message)s")
    log_format = logging.Formatter(format_string)
    # Creating and adding the console handler
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setFormatter(log_format)
    logger.addHandler(console_handler)
    # Creating and adding the file handler
    file_handler = logging.FileHandler(logger_name, mode='a')
    file_handler.setFormatter(log_format)
    logger.addHandler(file_handler)
    return logger


if __name__ == "__main__":
    for item in range(10):
        logger = my_custom_logger(f"Logger{item}")
        logger.debug(item)

这将为每次迭代写入不同的日志文件。

票数 8
EN

Stack Overflow用户

发布于 2019-02-08 19:46:11

这可能不是最好的解决方案,但它将为每次迭代创建新的日志文件。这样做是为了在每次迭代中添加一个新的文件处理程序。

代码语言:javascript
复制
import logging
targets = ["a", "b", "c"]
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

for target in targets:
    log_file = "{}.log".format(target)
    log_format = "|%(levelname)s| : [%(filename)s]--[%(funcName)s] : %(message)s"
    formatter = logging.Formatter(log_format)

    # create file handler and set the formatter
    file_handler = logging.FileHandler(log_file)
    file_handler.setFormatter(formatter)

    # add handler to the logger
    logger.addHandler(file_handler)

    # sample message
    logger.info("Log file: {}".format(target))
票数 3
EN

Stack Overflow用户

发布于 2019-06-02 03:06:34

这不一定是最好的答案,但对我的情况有效,只是想把它放在这里供将来参考。我创建了一个函数,如下所示:

代码语言:javascript
复制
def logger(filename, level=None, format=None):
    """A wrapper to the logging python module

    This module is useful for cases where we need to log in a for loop
    different files. It also will allow more flexibility later on how the
    logging format could evolve.

    Parameters
    ----------
    filename : str
        Name of logfile. 
    level : str, optional
        Level of logging messages, by default 'info'. Supported are: 'info'
        and 'debug'.
    format : str, optional
        Format of logging messages, by default '%(message)s'.

    Returns
    -------
    logger
        A logger object.
    """

    levels = {"info": logging.INFO, "debug": logging.DEBUG}

    if level is None:
        level = levels["info"]
    else:
        level = levels[level.lower()]

    if format is None:
        format = "%(message)s"

    # https://stackoverflow.com/a/12158233/1995261
    for handler in logging.root.handlers[:]:
        logging.root.removeHandler(handler)

    logger = logging.basicConfig(filename=filename, level=level, format=format)

    return logger

正如您所看到的(您可能需要向下滚动上面的代码才能看到return logger行),我使用的是logging.basicConfig()。我的包中所有记录内容的模块,在文件的开头都有以下内容:

代码语言:javascript
复制
import logging
import other stuff

logger = logging.getLogger()


class SomeClass(object):
    def some_method(self):
        logger.info("Whatever")
        .... stuff

在执行循环时,我是这样调用的:

代码语言:javascript
复制
if __name__ == "__main__":
    for i in range(1, 11, 1):
        directory = "_{}".format(i)

        if not os.path.exists(directory):
            os.makedirs(directory)
        filename = directory + "/training.log"
        logger(filename=filename)

我希望这对你有帮助。

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

https://stackoverflow.com/questions/54591352

复制
相关文章

相似问题

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