Using the framework Twisted, when you use startLogging(), you get logging lines like:
Y-M-D H-m-s [Class - IP] message
How can I format that outp开发者_StackOverflow中文版ut in order to eliminate the date and the IP?
Thanks
I'm working on solving a similar problem right now. The first result on Google for "twisted logs" is the pretty helpful official documentation on logging, which led me to the application page where there was an example of customizing the logging behavior of an application:
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)
I'm guessing I can just do that, and use a custom subclass of FileLogObserver. I went and looked at that code in /usr/lib/python2.6/dist-packages/twisted/python/log.py
here it is
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)
I know this is not a solution, but this is what I have learned so far. If I figure anything else out, I'll post it.
Here is how I override the emit function:
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!")
and the resulting output:
$ 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!
A complete example using @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)
精彩评论