Python 日志记录并打印到终端和文件 > 未获取调用者类和行号

问题描述 投票:0回答:1

我有一个用于日志记录功能的 python 类包装器,当我调用 Print 时,它会同时记录在控制台上(如果我从控制台调用)和文件(始终)。这涵盖了我从 cron 作业实现自动化时的情况。

记录器的示例可以在这里或我实际关注的这里找到。

这些解决方案的问题是日志记录选项“

%(asctime)s:[%(filename)s->%(funcName)s():%(lineno)s] %(levelname)s>> %(message)s
”不会引用“print”方法的原始调用者。

我正在谈论的一个例子,如果我有“Foo”类:

class Foo:
    def bar():
        try:
            print("example")
        except Exception as e:
            print(f"ERROR:\n{e}")
            return

我称之为:

wrapped_logger = Logger()
a = Foo()
a.bar()

输出将是:

2024-11-05 12:02:15,994:[logger.py->write():39] INFO>> example

虽然这在技术上是正确的,但我想知道发生打印的类和函数

Foo.bar

这是

logger.py
上的记录器类:

import logging
import sys
from datetime import datetime

class Logger(object):
    """
    Fake file-like stream object that redirects writes to a logger instance.
    """

    def __init__(self, log_level=logging.INFO):

        month = datetime.today().strftime('%Y-%m')
        self.logFile = f'./logs/{month}.log'

        self.terminal = sys.stdout
        self.log = open(self.logFile, "a")
        
        logger = logging.getLogger(__name__)
        logger.handlers = []
        fh = logging.FileHandler(filename=self.logFile, mode = 'a')
        formatter = logging.Formatter('%(asctime)s:[%(filename)s->%(funcName)s():%(lineno)s] %(levelname)s>> %(message)s')
        fh.setFormatter(formatter)
        logger.addHandler(fh)
        logger.setLevel("DEBUG")

        self.logger = logger
        self.log_level = log_level
        self.linebuf = ''

        sys.stdout = self

    def write(self, buf):

        self.terminal.write(buf)
        temp_linebuf = self.linebuf + buf
        self.linebuf = ''
        for line in temp_linebuf.splitlines(True):

            if line[-1] == '\n':
                self.logger.log(self.log_level, line.rstrip())
            else:
                self.linebuf += line
                

    def flush(self):
        if self.linebuf != '':
            self.logger.log(self.log_level, self.linebuf.rstrip())
        self.linebuf = ''

我怎样才能做到输出为“

2024-11-05 12:02:15,994:[foo.py->Foo.bar():4] INFO>> example

如何获得正确的函数和类名称以及行号?

(是的,类似于 log4net 对 c# 的作用或 log4j 对 java 的作用,有 log4py 吗?xD)是否有更简单的方法来实现这一切?人们如何进行日志记录?

python python-3.x logging stdout
1个回答
0
投票

您可以像这样使用

stacklevel
参数。 (详情请参阅参考。)

...
class Logger(object):
    ...
    def write(self, buf):
        ...
                self.logger.log(self.log_level, line.rstrip(), stacklevel=2)
        ...
    ...
© www.soinside.com 2019 - 2024. All rights reserved.