[or-cvs] [pytorctl/master 1/5] Implement Python logging support for plog().

mikeperry at torproject.org mikeperry at torproject.org
Fri Aug 20 20:46:12 UTC 2010


Author: Harry Bock <hbock at ele.uri.edu>
Date: Fri, 23 Jul 2010 22:47:31 -0400
Subject: Implement Python logging support for plog().
Commit: 6570597de4080595ecb7849de1ea2b228306c772

This patch converts plog() to map to Python's logging module without
changing API compatibility.  If an application wishes to integrate
its own Python logger with TorCtl, it can call TorUtil.plog_use_logger
with the name of the desired logger.  Otherwise, TorUtil will create
its own logger that retains its original log format and emission behavior.

This patch retains the standard plog() loglevels and maps them to
logging constants where appropriate.
---
 TorUtil.py |   60 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/TorUtil.py b/TorUtil.py
index 859a224..6e9acbc 100644
--- a/TorUtil.py
+++ b/TorUtil.py
@@ -14,6 +14,7 @@ import socket
 import binascii
 import math
 import time
+import logging
 import ConfigParser
 
 if sys.version_info < (2, 5):
@@ -301,18 +302,55 @@ def s2k_check(secret, k):
 
 ## XXX: Make this a class?
 loglevel = "DEBUG"
-loglevels = {"DEBUG" : 0, "INFO" : 1, "NOTICE" : 2, "WARN" : 3, "ERROR" : 4, "NONE" : 5}
-logfile=None
-
-def plog(level, msg): # XXX: Timestamps
-  if(loglevels[level] >= loglevels[loglevel]):
-    t = time.strftime("%a %b %d %H:%M:%S %Y")
-    if logfile:
-      logfile.write(level+'['+t+']:'+msg+"\n")
-      logfile.flush()
+#loglevels = {"DEBUG" : 0, "INFO" : 1, "NOTICE" : 2, "WARN" : 3, "ERROR" : 4, "NONE" : 5}
+logfile = None
+logger = None
+
+# Python logging levels are in increments of 10, so place our custom
+# levels in between Python's default levels.
+loglevels = { "DEBUG":  logging.DEBUG,
+              "INFO":   logging.INFO,
+              "NOTICE": logging.INFO + 5,
+              "WARN":   logging.WARN,
+              "ERROR":  logging.ERROR,
+              "NONE":   logging.ERROR + 5 }
+# Set loglevel => name translation.
+for name, value in loglevels.iteritems():
+  logging.addLevelName(value, name)
+
+def plog_use_logger(name):
+  """ Set the Python logger to use with plog() by name.
+      Useful when TorCtl is integrated with an application using logging.
+      The logger specified by name must be set up before the first call
+      to plog()! """
+  global logger, loglevels
+  logger = logging.getLogger(name)
+
+def plog(level, msg, *args):
+  global logger, logfile
+  if not logger:
+    # Default init = old TorCtl format + default behavior
+    # Default behavior = log to stdout if TorUtil.logfile is None,
+    # or to the open file specified otherwise.
+    logger = logging.getLogger("TorCtl")
+    formatter = logging.Formatter("%(levelname)s[%(asctime)s]:%(message)s",
+                                  "%a %b %d %H:%M:%S %Y")
+
+    if not logfile:
+      logfile = sys.stdout
+    # HACK: if logfile is a string, assume is it the desired filename.
+    if type(logfile) is str:
+      f = logging.FileHandler(logfile)
+      f.setFormatter(formatter)
+      logger.addHandler(f)
+    # otherwise, pretend it is a stream.
     else:
-      print level, '[', t, ']:', msg
-      sys.stdout.flush()
+      ch = logging.StreamHandler(logfile)
+      ch.setFormatter(formatter)
+      logger.addHandler(ch)
+    logger.setLevel(loglevels[loglevel])
+
+  logger.log(loglevels[level], msg, *args)
 
 # Stolen from
 # http://www.nmr.mgh.harvard.edu/Neural_Systems_Group/gary/python/stats.py
-- 
1.7.1




More information about the tor-commits mailing list