代码之家  ›  专栏  ›  技术社区  ›  Juanjo Conti

如何格式化扭曲的日志?

  •  3
  • Juanjo Conti  · 技术社区  · 15 年前

    使用twisted框架,当您使用startogging()时,您会得到如下日志记录行:

    Y-M-D H-M-S[等级-IP]消息

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

    谢谢

    3 回复  |  直到 9 年前
        1
  •  5
  •   Nathan    15 年前

    我正在努力解决一个类似的问题。 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)
    

    我知道这不是一个解决办法,但这是我迄今为止学到的。如果我还有什么发现的话,我会贴出来的。

        2
  •  3
  •   AXE Labs    14 年前

    以下是我如何重写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!
    
        3
  •  0
  •   jpillora    9 年前

    使用@nathan's direction的完整示例:

    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)