更改扭曲矩阵日志中的时间格式

时间:2013-06-12 16:49:55

标签: python logging twisted

如何更改TwistedMatrix中使用的日志系统的时间格式?

我注意到了 http://twistedmatrix.com/trac/browser/tags/releases/twisted-11.0.0/twisted/python/log.py#L389 应该允许一个人改变timeFormat,但它不起作用 对我来说,这是我执行python myscript.py

的完整测试程序
from twisted.internet import endpoints, reactor

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

#[... here my definition of a ProxyFactory()...]

application = Application("myapp")
logfile = DailyLogFile("my.log", './')
flo = FileLogObserver(logfile)
flo.timeFormat = "%Y-%m-%d %H:%M:%S,%f%z"
application.setComponent(ILogObserver, flo.emit)

log.startLogging(logfile)
log.msg("this is a test")

endpoint = endpoints.serverFromString(reactor, portstr)
d = endpoint.listen(ProxyFactory())
d.addErrback(shutdown, reactor)
reactor.run()

没有得到预期:“%Y-%m-%d%H:%M:%S,%f%z”(毫秒)

2013-06-12 17:08:07+0200 [-] Log opened.
2013-06-12 17:08:12+0200 [-] this is a test

我错过了什么?

也:

  • 当我不需要文件时,我该如何继续更改此时间格式 记录但只有stderr打印?

(其他参考:http://twistedmatrix.com/trac/ticket/3513

编辑:我试着改写我的两个问题。

所以根据JeanPaul发布的答案,我明白我正在将东西和经典的python文件与另一个tac文件混合(在阅读JeanPaul之前我不知道)。顺便说一下,我在下面尝试了这个,但仍然没有得到我需要的毫秒数:

(这次我发布了twistd -noy my.tac

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", "./")
flo = FileLogObserver(logfile)
flo.timeFormat = "%Y-%m-%d %H:%M:%S,%f %z"
application.setComponent(ILogObserver, flo.emit)

并获得:

2013-06-13 17:23:23,%f+0000 [-] Log opened.
2013-06-13 17:23:23,%f+0000 [-] using set_wakeup_fd
2013-06-13 17:23:23,%f+0000 [-] twistd 12.0.0 (/usr/bin/python 2.7.3) starting up.
2013-06-13 17:23:23,%f+0000 [-] reactor class: twisted.internet.pollreactor.PollReactor.
2013-06-13 17:23:30,%f+0000 [-] Received SIGINT, shutting down.
2013-06-13 17:23:30,%f+0000 [-] Main loop terminated.
2013-06-13 17:23:30,%f+0000 [-] Server Shut Down.

你可以看到我是否模仿@ http://twistedmatrix.com/trac/browser/trunk/twisted/python/log.py#L351做了什么,见367行,python和time给我这个毫秒。另请注意,%Z错了它应该是+0200,但我可以忍受这一点,而我需要几毫秒......

Python 2.7.3 (default, Jan  2 2013, 13:56:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.datetime.now().strftime("%H:%M:%S.%f")
'17:28:06.566135'
>>> import time
>>> when = time.time()
>>> import datetime
>>> datetime.datetime.fromtimestamp(when).strftime("%Y-%m-%d %H:%M:%S,%f%z")
'2013-06-13 17:33:20,535350'
>>> import twisted
>>> twisted.version
Version('twisted', 12, 0, 0)

2 个答案:

答案 0 :(得分:3)

你在这里为日志记录系统做了几件不同的事情。您要求twistd使用flo.emit作为日志观察者。这将在twistd加载此 application文件中定义的tac后生效。然后,您手动初始化日志记录系统以使用logfile并立即记录消息。由于这是tac文件的一部分,twistd尚未完成加载application,因此尚未应用您使用ILogObserver指定的日志记录配置。相反,日志事件由您使用startLogging - logfile设置的日志观察者处理,该日志观察者对自定义时间戳格式设置一无所知。

删除startLogging调用,您应该会看到 application文件加载tac后正确记录的事件。

您可以在logging howto中阅读有关如何使用Twisted进行日志记录的详细信息,以及如何在application howto中为twistd配置日志。

另请注意,对custom time formatting using datetime.strftime的支持为first introduced in Twisted 13.0.0。从你问题的输出中,看起来你有Twisted 12.0.0。这意味着使用time.strftime完成格式化,不支持微秒。

在Twisted 13.0.0之前,为了获得时间格式的微秒,您需要覆盖formatTime的{​​{1}}方法并自己致电FileLogObserver

答案 1 :(得分:1)

如果这可以帮助这里的人(文件名为my.tac)

我也让%z正常工作(我现在按照预期使用我自己的时间格式而非+0000获得+0200)

我用twistd -noy my.tac

来称呼它

(灵感来自http://twistedmatrix.com/trac/browser/trunk/twisted/python/log.py#L407

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

from datetime import datetime

class MyFileLogObserver(FileLogObserver):

    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
        L{datetime.datetime.strftime} call.

        BACKPORTED VERSION: and adding support for %z.

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

        @rtype: C{str}
        """
        tzOffset = -self.getTimezoneOffset(when)
        tzHour = abs(int(tzOffset / 60 / 60))
        tzMin = abs(int(tzOffset / 60 % 60))
        if tzOffset < 0:
            tzSign = '-'
        else:
            tzSign = '+'
        tz = "%s%02d%02d" % (tzSign, tzHour, tzMin)
        if self.timeFormat is not None:
            return datetime.fromtimestamp(when).strftime(self.timeFormat.replace("%z", tz))

        when = datetime.utcfromtimestamp(when + tzOffset)    
        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)    

application = Application("myapp")
logfile = DailyLogFile("my.log", "./")
flo = MyFileLogObserver(logfile)
flo.timeFormat = "%Y-%m-%d %H:%M:%S,%f%z"
application.setComponent(ILogObserver, flo.emit)