簡體   English   中英

在python中帶有時間戳的自定義記錄器

[英]Custom logger with time stamp in python

我在一個帶有打印語句的項目中有很多代碼,想要快速創建這些打印語句的骯臟記錄器,並決定采用自定義路線。 我設法將一個記錄器打印到終端和文件上(在此站點的幫助下),但是現在我想為每個語句添加一個簡單的時間戳,並且遇到了一個奇怪的問題。

這是我的測井課程。

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方法。

運行以下兩行時,我得到意外的輸出:

sys.stdout = Logger(sys.stdout)
print("Hello World!")

輸出:

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

這也是輸出在日志文件中顯示的內容,但是,我看不出我要添加的字符串附加到末尾的原因。 有人可以幫我嗎?

更新請參見下面的答案。 但是,為了便於參考,該問題通常使用“ print()”。 分配變量后,將其替換為sys.stdout.write。

對於長期/較大的項目,也請立即使用“日志記錄”。

它調用.write()你流的方法兩次,因為在CPython的print調用流.write()方法的兩倍。 第一次與對象在一起,第二次它與對象寫入換行符。 例如,查看cpython v3.5.2中pprint模塊中的第138行

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

您可以測試一下:

>>> from my_logger import Logger  # my_logger.py has your Logger class
>>> import sys
>>> sys.stdout = Logger(stream=sys.stdout)
>>> sys.stdout.write('hi\n')
[14:05:32] hi

您可以使用sed在代碼中的任何地方替換print(<blah>)

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

查看Python的Logging內置模塊 它具有非常全面的日志記錄,包括以所有消息格式包含時間戳。

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: messagestdout 還有一些處理程序可以將輸出發送到文件。 有一個基本的教程 ,一個高級的教程和一個常用的日志記錄食譜

食譜中有一個同時使用文件和控制台記錄器的示例。

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

您可能需要使用換行符。

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

無論如何,使用內置的日志記錄模塊會更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM