From 82a30cc837951264889a5b0fa82672a95dc3e331 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 19 Apr 2014 11:50:26 +0200 Subject: [PATCH] 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. --- src/utils/logger.py | 71 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/src/utils/logger.py b/src/utils/logger.py index a0c93f4ecf..b2a8341f08 100644 --- a/src/utils/logger.py +++ b/src/utils/logger.py @@ -1,12 +1,25 @@ """ Logging facilities -This file should have an absolute minimum in imports. If you'd like to layer -additional functionality on top of some of the methods below, wrap them in -a higher layer module. +These are thin wrappers on top of Twisted's +logging facilities; logs are all directed +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 twisted.python import log +from twisted.internet.threads import deferToThread def log_trace(errmsg=None): @@ -29,9 +42,10 @@ def log_trace(errmsg=None): log.msg('[EE] %s' % line) except Exception: 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. @@ -44,9 +58,10 @@ def log_errmsg(errmsg): for line in errmsg.splitlines(): log.msg('[EE] %s' % line) #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. @@ -59,9 +74,10 @@ def log_warnmsg(warnmsg): for line in warnmsg.splitlines(): log.msg('[WW] %s' % line) #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. @@ -73,9 +89,10 @@ def log_infomsg(infomsg): infomsg = str(e) for line in infomsg.splitlines(): log.msg('[..] %s' % line) +log_infomsg = log_info -def log_depmsg(depmsg): +def log_dep(depmsg): """ Prints a deprecation message """ @@ -85,3 +102,43 @@ def log_depmsg(depmsg): depmsg = str(e) for line in depmsg.splitlines(): 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)