python中带有时间戳的自定义记录器

2024-04-26 20:40:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个带有print语句的项目上有很多代码,我想对这些print语句进行一个快速的脏日志记录,并决定采用定制的方式。我设法建立了一个记录器,可以打印到终端和文件(在这个站点的帮助下),但是现在我想给每个语句添加一个简单的时间戳,我遇到了一个奇怪的问题。在

这是我的日志课。在

class Logger(object):
    def __init__(self, stream):
        self.terminal = stream
        self.log = open("test.log", 'a')

    def write(self, message):
        self.terminal.flush()
        self.terminal.write(self.stamp() + message)
        self.log.write(self.stamp() + message)

    def stamp(self):
        d = datetime.today()
        string = d.strftime("[%H:%M:%S] ")
        return string

请注意我随后尝试在write方法中使用的stamp方法。在

运行以下两行时,我得到一个意外的输出:

^{pr2}$

输出:

[11:10:47] Hello World![11:10:47]

这个输出也在日志文件中显示,但是,我看不出为什么我要添加的字符串追加到末尾。有人能帮我吗?在

更新 见下面的答案。但是,为了更快地参考,该问题通常使用“print()”;将其替换为系统标准输出写入分配变量后。在

对于长期/较大的项目,也要立即使用“日志记录”。在


Tags: 文件项目方法selflogmessagestreamstring
2条回答

您可能需要使用换行符。在

class Logger(object):
    def __init__(self, stream):
        self.terminal = stream
        self.log = open("test.log", 'a')

    def write(self, message):
        self.terminal.flush()
        self.terminal.write(self.stamp() + message + "\n")
        self.log.write(self.stamp() + message + "\n")

    def stamp(self):
        d = datetime.today()
        string = d.strftime("[%H:%M:%S] ")
        return string

无论如何,使用内置的日志模块会更好。在

它调用流的.write()方法两次,因为在cpython中,print调用流.write()方法两次。第一次是对象,第二次是写换行符。例如看line 138 in the ^{} module in cpython v3.5.2

def pprint(self, object):
    self._format(object, self._stream, 0, 0, {}, 0)
    self._stream.write("\n")  # <- write() called again!

你可以测试一下:

^{pr2}$

您可以使用^{}替换代码中任何地方的print(<blah>)。在

$ for mymodule in *.py; do
> sed -i -E "s/print\((.+)\)/LOGGER.debug(\1)/" $mymodule
> done

退房Python's Logging builtin module。它有相当全面的日志记录,包括在所有消息格式中包含时间戳。在

import logging
FORMAT = '%(asctime)-15s %(message)s'
DATEFMT = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(format=FORMAT, datefmt=DATEFMT)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

logger.debug('message: %s', 'message')

它将2016-07-29 11:44:20 message: message输出到stdout。还有一些处理程序将输出发送到文件。有一个basic tutorial,一个advanced tutorial和一个cookbook of common logging recipes。在

在食谱中有一个使用simultaneous file and console loggers的例子。在

import logging

LOGGER = logging.getLogger(__name__)  # get logger named for this module
LOGGER.setLevel(logging.DEBUG)  # set logger level to debug

# create formatter
LOG_DATEFMT = '%Y-%m-%d %H:%M:%S'
LOG_FORMAT = ('\n[%(levelname)s/%(name)s:%(lineno)d] %(asctime)s ' +
              '(%(processName)s/%(threadName)s)\n> %(message)s')
FORMATTER = logging.Formatter(LOG_FORMAT, datefmt=LOG_DATEFMT)

CH = logging.StreamHandler()  # create console handler
CH.setLevel(logging.DEBUG)  # set handler level to debug
CH.setFormatter(FORMATTER)  # add formatter to ch
LOGGER.addHandler(CH)  # add console handler to logger

FH = logging.FileHandler('myapp.log')  # create file handler
FH.setLevel(logging.DEBUG)  # set handler level to debug
FH.setFormatter(FORMATTER)  # add formatter to fh
LOGGER.addHandler(FH)  # add file handler to logger

LOGGER.debug('test: %s', 'hi')

该输出:

[DEBUG/__main__:22] 2016-07-29 12:20:45 (MainProcess/MainThread)
> test: hi

同时指向控制台和文件myapp.log。在

相关问题 更多 >