Added channel logfile rotation.

This commit is contained in:
Jeremy Fincher 2004-03-27 20:18:47 +00:00
parent 07d10bb223
commit f5365a6202
2 changed files with 44 additions and 24 deletions

View File

@ -61,6 +61,23 @@ conf.registerChannelValue(conf.supybot.plugins.ChannelLogger, 'noLogPrefix',
registry.String('[nolog]', """Determines what string a message should be registry.String('[nolog]', """Determines what string a message should be
prefixed with in order not to be logged. If you don't want any such prefixed with in order not to be logged. If you don't want any such
prefix, just set it to the empty string.""")) prefix, just set it to the empty string."""))
conf.registerChannelValue(conf.supybot.plugins.ChannelLogger, 'rotateLogs',
registry.Boolean(False, """Determines whether the bot will automatically
rotate the logs for this channel."""))
conf.registerChannelValue(conf.supybot.plugins.ChannelLogger,
'filenameTimestamp', registry.String('%d-%a-%Y', """Determines how to
represent the timestamp used for the filename in rotated logs. When this
timestamp changes, the old logfiles will be closed and a new one started.
The format characters for the timestamp are in the time.strftime docs at
python.org."""))
class FakeLog(object):
def flush(self):
return
def close(self):
return
def write(self, s):
return
class ChannelLogger(callbacks.Privmsg): class ChannelLogger(callbacks.Privmsg):
def __init__(self): def __init__(self):
@ -73,8 +90,8 @@ class ChannelLogger(callbacks.Privmsg):
def die(self): def die(self):
for log in self.logs.itervalues(): for log in self.logs.itervalues():
log.close() log.close()
if self.flush in world.flushers: world.flushers = [x for x in world.flushers
world.flushers.remove(self.flush) if hasattr(x, 'im_class') and x.im_class == self]
def __call__(self, irc, msg): def __call__(self, irc, msg):
try: try:
@ -90,9 +107,10 @@ class ChannelLogger(callbacks.Privmsg):
def reset(self): def reset(self):
for log in self.logs.itervalues(): for log in self.logs.itervalues():
log.close() log.close()
self.logs = ircutils.IrcDict() self.logs.clear()
def flush(self): def flush(self):
self.checkLogNames()
try: try:
for log in self.logs.itervalues(): for log in self.logs.itervalues():
log.flush() log.flush()
@ -100,18 +118,38 @@ class ChannelLogger(callbacks.Privmsg):
if e.args[0] != 'I/O operation on a closed file': if e.args[0] != 'I/O operation on a closed file':
self.log.exception('Odd exception:') self.log.exception('Odd exception:')
def logNameTimestamp(self, channel):
format = self.registryValue('filenameTimestamp', channel)
return time.strftime(format)
def getLogName(self, channel):
if self.registryValue('rotateLogs', channel):
return '%s.%s.log' % (channel, self.logNameTimestamp(channel))
else:
return '%s.log' % channel
def checkLogNames(self):
for (channel, log) in self.logs.items():
if self.registryValue('rotateLogs', channel):
name = self.getLogName(channel)
if name != log.name:
log.close()
del self.logs[channel]
def getLog(self, channel): def getLog(self, channel):
self.checkLogNames()
if channel in self.logs: if channel in self.logs:
return self.logs[channel] return self.logs[channel]
else: else:
try: try:
logDir = conf.supybot.directories.log() logDir = conf.supybot.directories.log()
log = file(os.path.join(logDir, '%s.log' % channel), 'a') name = self.getLogName(channel)
log = file(os.path.join(logDir, name), 'a')
self.logs[channel] = log self.logs[channel] = log
return log return log
except IOError: except IOError:
self.log.exception('Error opening log:') self.log.exception('Error opening log:')
return StringIO() return FakeLog()
def timestamp(self, log): def timestamp(self, log):
format = conf.supybot.log.timestampFormat() format = conf.supybot.log.timestampFormat()

View File

@ -72,6 +72,7 @@ class BetterStreamHandler(logging.StreamHandler):
self.stream.write("%s\n" % msg.encode("UTF-8")) self.stream.write("%s\n" % msg.encode("UTF-8"))
self.flush() self.flush()
class StdoutStreamHandler(BetterStreamHandler): class StdoutStreamHandler(BetterStreamHandler):
def emit(self, record): def emit(self, record):
if conf.supybot.log.stdout(): if conf.supybot.log.stdout():
@ -91,25 +92,6 @@ class BetterFileHandler(logging.FileHandler):
self.flush() self.flush()
class DailyRotatingHandler(BetterFileHandler):
def __init__(self, *args):
self.lastRollover = time.localtime()
BetterFileHandler.__init__(self, *args)
def emit(self, record):
now = time.localtime()
if now[2] != self.lastRollover[2]:
self.doRollover()
self.lastRollover = now
BetterFileHandler.emit(self, record)
def doRollover(self):
self.stream.close()
extension = time.strftime('%d-%b-%Y', self.lastRollover)
os.rename(self.baseFilename, '%s.%s' % (self.baseFilename, extension))
self.stream = file(self.baseFilename, 'w')
class ColorizedFormatter(Formatter): class ColorizedFormatter(Formatter):
def formatException(self, (E, e, tb)): def formatException(self, (E, e, tb)):
if conf.supybot.log.stdout.colorized(): if conf.supybot.log.stdout.colorized():