如何格式化扭曲的日志?

时间:2010-09-13 13:41:46

标签: python logging twisted

使用框架Twisted,当你使用startLogging()时,你得到的记录行如下:

Y-M​​-D H-m-s [Class-IP]消息

如何格式化该输出以消除日期和IP?

由于

3 个答案:

答案 0 :(得分:5)

我正在努力解决类似的问题。 The first result on Google for "twisted logs" is pretty helpful 该页面引导我进入Application page,其中有一个自定义应用程序日志记录行为的示例:

from twisted.application.service import Application
from twisted.python.log import ILogObserver, FileLogObserver
from twisted.python.logfile import DailyLogFile

application = Application("myapp")
logfile = DailyLogFile("my.log", "/tmp")
application.setComponent(ILogObserver, FileLogObserver(logfile).emit)

我猜我可以这样做,并使用FileLogObserver的自定义子类。我去查看/usr/lib/python2.6/dist-packages/twisted/python/log.py中的代码

这里是

class FileLogObserver:
    """
    Log observer that writes to a file-like object.

    @type timeFormat: C{str} or C{NoneType}
    @ivar timeFormat: If not C{None}, the format string passed to strftime().
    """
    timeFormat = None

    def __init__(self, f):
        self.write = f.write
        self.flush = f.flush

    def getTimezoneOffset(self, when):
        """
        Return the current local timezone offset from UTC.

        @type when: C{int}
        @param when: POSIX (ie, UTC) timestamp for which to find the offset.

        @rtype: C{int}
        @return: The number of seconds offset from UTC.  West is positive,
        east is negative.
        """
        offset = datetime.utcfromtimestamp(when) - datetime.fromtimestamp(when)
        return offset.days * (60 * 60 * 24) + offset.seconds

    def formatTime(self, when):
        """
        Format the given UTC value as a string representing that time in the
        local timezone.

        By default it's formatted as a ISO8601-like string (ISO8601 date and
        ISO8601 time separated by a space). It can be customized using the
        C{timeFormat} attribute, which will be used as input for the underlying
        C{time.strftime} call.

        @type when: C{int}
        @param when: POSIX (ie, UTC) timestamp for which to find the offset.

        @rtype: C{str}
        """
        if self.timeFormat is not None:
            return time.strftime(self.timeFormat, time.localtime(when))

        tzOffset = -self.getTimezoneOffset(when)
        when = datetime.utcfromtimestamp(when + tzOffset)
        tzHour = abs(int(tzOffset / 60 / 60))
        tzMin = abs(int(tzOffset / 60 % 60))
        if tzOffset < 0:
            tzSign = '-'
        else:
            tzSign = '+'
        return '%d-%02d-%02d %02d:%02d:%02d%s%02d%02d' % (
            when.year, when.month, when.day,
            when.hour, when.minute, when.second,
            tzSign, tzHour, tzMin)

    def emit(self, eventDict):
        text = textFromEventDict(eventDict)
        if text is None:
            return

        timeStr = self.formatTime(eventDict['time'])
        fmtDict = {'system': eventDict['system'], 'text': text.replace("\n", "\n\t")}
        msgStr = _safeFormat("[%(system)s] %(text)s\n", fmtDict)

        util.untilConcludes(self.write, timeStr + " " + msgStr)
        util.untilConcludes(self.flush)  # Hoorj!

    def start(self):
        """
        Start observing log events.
        """
        addObserver(self.emit)

    def stop(self):
        """
        Stop observing log events.
        """
        removeObserver(self.emit)

我知道这不是解决方案,但这是我迄今所学到的。如果我想出其他的东西,我会发布它。

答案 1 :(得分:4)

以下是我重写emit函数的方法:

from twisted.python import log, util
from twisted.internet import reactor
from twisted.application.service import Application

def myFLOemit(self,eventDict):
  """Custom emit for FileLogObserver"""
  text = log.textFromEventDict(eventDict)
  if text is None:
    return
  self.timeFormat='[%Y-%m-%d %H:%M:%S]'
  timeStr = self.formatTime(eventDict['time'])
  fmtDict = {'text': text.replace("\n", "\n\t")}
  msgStr = log._safeFormat("%(text)s\n", fmtDict)
  util.untilConcludes(self.write, timeStr + " " + msgStr)
  util.untilConcludes(self.flush)

# Overwrite twistd's FileLogObserver formatting
log.FileLogObserver.emit=myFLOemit
# Start the app
application=Application("fileget")
reactor.callWhenRunning(log.msg,"No system here!")

以及结果输出:

$ twistd -noy myapp.tac 
[2012-02-06 12:32:22] Log opened.
[2012-02-06 12:32:22] twistd 11.1.0 (/usr/bin/python2 2.7.2) starting up.
[2012-02-06 12:32:22] reactor class: twisted.internet.pollreactor.PollReactor.
[2012-02-06 12:32:22] No system here!

答案 2 :(得分:0)

使用@ Nathan方向的完整示例:

from os import sys

from twisted.python import log, util
from twisted.python.log import FileLogObserver, textFromEventDict, _safeFormat


def start(prefix):
    o = LogObserver(sys.stdout, prefix)
    log.startLoggingWithObserver(o.emit)


class LogObserver(FileLogObserver):

    def __init__(self, f, prefix):
        if len(prefix) > 0:
            prefix += ''
        self.prefix = prefix
        FileLogObserver.__init__(self, f)

    def emit(self, eventDict):
        text = textFromEventDict(eventDict)
        if text is None:
            return
        timeStr = self.formatTime(eventDict["time"])
        msgStr = _safeFormat("[%(prefix)s] %(text)s\n", {
            "prefix": self.prefix,
            "text": text.replace("\n", "\n\t")
        })
        util.untilConcludes(self.write, timeStr + " " + msgStr)
        util.untilConcludes(self.flush)