3

如何更改 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 和时间给了我这个毫秒。还要注意 %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)
4

2 回答 2

3

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

挂断电话,您应该会看到从文件加载记录的startLogging事件被正确格式化。applicationtac

您可以在日志记录操作指南中阅读有关 Twisted 中日志记录twistd如何工作的所有信息,以及如何在应用程序操作指南中对其进行配置。

另请注意,在 Twisted 13.0.0中首次引入了对自定义时间格式datetime.strftime的支持。从您问题的输出来看,您似乎拥有 Twisted 12.0.0。这意味着格式化是使用不支持微秒的。time.strftime

在 Twisted 13.0.0 之前,要获取时间格式的微秒,您需要重写并调用自己的formatTime方法。FileLogObserverdatetime.strftime

于 2013-06-12T20:35:31.490 回答
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)
于 2013-06-13T21:09:50.200 回答