Added logger.log_file(msg, filename) as an easy way to log data to an arbitrary file in game/log. log_file() uses threading and open file handles to be non-blocking and inexpensive when logging often.

This commit is contained in:
Griatch 2014-04-19 11:50:26 +02:00
parent b7b68afe20
commit 82a30cc837

View file

@ -1,12 +1,25 @@
""" """
Logging facilities Logging facilities
This file should have an absolute minimum in imports. If you'd like to layer These are thin wrappers on top of Twisted's
additional functionality on top of some of the methods below, wrap them in logging facilities; logs are all directed
a higher layer module. either to stdout (if Evennia is running in
interactive mode) or to game/logs.
The log_file() function uses its own threading
system to log to arbitrary files in game/logs.
Note:
All logging functions have two aliases,
log_type() and log_typemsg(). This is for
historical, back-compatible reasons.
""" """
from datetime import datetime
from traceback import format_exc from traceback import format_exc
from twisted.python import log from twisted.python import log
from twisted.internet.threads import deferToThread
def log_trace(errmsg=None): def log_trace(errmsg=None):
@ -29,9 +42,10 @@ def log_trace(errmsg=None):
log.msg('[EE] %s' % line) log.msg('[EE] %s' % line)
except Exception: except Exception:
log.msg('[EE] %s' % errmsg) log.msg('[EE] %s' % errmsg)
log_tracemsg = log_trace
def log_errmsg(errmsg): def log_err(errmsg):
""" """
Prints/logs an error message to the server log. Prints/logs an error message to the server log.
@ -44,9 +58,10 @@ def log_errmsg(errmsg):
for line in errmsg.splitlines(): for line in errmsg.splitlines():
log.msg('[EE] %s' % line) log.msg('[EE] %s' % line)
#log.err('ERROR: %s' % (errormsg,)) #log.err('ERROR: %s' % (errormsg,))
log_errmsg = log_err
def log_warnmsg(warnmsg): def log_warn(warnmsg):
""" """
Prints/logs any warnings that aren't critical but should be noted. Prints/logs any warnings that aren't critical but should be noted.
@ -59,9 +74,10 @@ def log_warnmsg(warnmsg):
for line in warnmsg.splitlines(): for line in warnmsg.splitlines():
log.msg('[WW] %s' % line) log.msg('[WW] %s' % line)
#log.msg('WARNING: %s' % (warnmsg,)) #log.msg('WARNING: %s' % (warnmsg,))
log_warnmsg = log_warn
def log_infomsg(infomsg): def log_info(infomsg):
""" """
Prints any generic debugging/informative info that should appear in the log. Prints any generic debugging/informative info that should appear in the log.
@ -73,9 +89,10 @@ def log_infomsg(infomsg):
infomsg = str(e) infomsg = str(e)
for line in infomsg.splitlines(): for line in infomsg.splitlines():
log.msg('[..] %s' % line) log.msg('[..] %s' % line)
log_infomsg = log_info
def log_depmsg(depmsg): def log_dep(depmsg):
""" """
Prints a deprecation message Prints a deprecation message
""" """
@ -85,3 +102,43 @@ def log_depmsg(depmsg):
depmsg = str(e) depmsg = str(e)
for line in depmsg.splitlines(): for line in depmsg.splitlines():
log.msg('[DP] %s' % line) log.msg('[DP] %s' % line)
log_depmsg = log_dep
# Arbitrary file logger
LOG_FILE_HANDLES = {} # holds open log handles
def log_file(msg, filename="game.log"):
"""
Arbitrary file logger using threads. Filename defaults to
'game.log'. All logs will appear in game/logs directory and log
entries will start on new lines following datetime info.
"""
global LOG_FILE_HANDLES
def callback(filehandle, msg):
"Writing to file and flushing result"
msg = "\n%s [-] %s" % (datetime.now(), msg.strip())
filehandle.write(msg)
# since we don't close the handle, we need to flush
# manually or log file won't be written to until the
# write buffer is full.
filehandle.flush()
def errback(failure):
"Catching errors to normal log"
log_trace()
# save to game/logs/ directory
filename = "logs/" + filename
if filename in LOG_FILE_HANDLES:
filehandle = LOG_FILE_HANDLES[filename]
else:
try:
filehandle = open(filename, "a")
LOG_FILE_HANDLES[filename] = filehandle
except IOError:
log_trace()
return
deferToThread(callback, filehandle, msg).addErrback(errback)