changeset 1585:a843bc5793fb

introduce stdlib's logging module
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Mon, 25 Sep 2006 22:17:59 +0200
parents 1a1d6e0fe14f
children cae5575b07fa
files MoinMoin/request/CGI.py MoinMoin/request/TWISTED.py MoinMoin/request/__init__.py MoinMoin/server/__init__.py MoinMoin/server/cgi.py MoinMoin/server/standalone.py MoinMoin/server/twistedmoin.py MoinMoin/util/lock.py docs/CHANGES wiki/server/mointwisted.py
diffstat 10 files changed, 62 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/request/CGI.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/request/CGI.py	Mon Sep 25 22:17:59 2006 +0200
@@ -34,12 +34,6 @@
         form = cgi.FieldStorage()
         return RequestBase._setup_args_from_cgi_form(self, form)
 
-    def open_logs(self):
-        # create log file for catching stderr output
-        if not self.opened_logs:
-            sys.stderr = open(os.path.join(self.cfg.data_dir, 'error.log'), 'at')
-            self.opened_logs = 1
-
     def read(self, n=None):
         """ Read from input stream. """
         if n is None:
--- a/MoinMoin/request/TWISTED.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/request/TWISTED.py	Mon Sep 25 22:17:59 2006 +0200
@@ -103,13 +103,6 @@
         RequestBase.finish(self)
         self.reactor.callFromThread(self.twistd.finish)
 
-    def open_logs(self):
-        return
-        # create log file for catching stderr output
-        if not self.opened_logs:
-            sys.stderr = open(os.path.join(self.cfg.data_dir, 'error.log'), 'at')
-            self.opened_logs = 1
-
     # Headers ----------------------------------------------------------
 
     def _emit_http_headers(self, headers):
--- a/MoinMoin/request/__init__.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/request/__init__.py	Mon Sep 25 22:17:59 2006 +0200
@@ -208,7 +208,6 @@
                 if not self.forbidden and self.surge_protect():
                     self.makeUnavailable503()
 
-            self.logger = None
             self.pragma = {}
             self.mode_getpagelinks = 0
 
@@ -218,7 +217,6 @@
             self.content_lang = self.cfg.language_default
             self.getText = lambda text, i18n=self.i18n, request=self, lang=self.lang, **kv: i18n.getText(text, request, lang, kv.get('formatted', True))
 
-            self.opened_logs = 0
             self.reset()
             self.clock.stop('base__init__')
 
@@ -758,14 +756,12 @@
             self.writestack = []
 
     def log(self, msg):
-        """ Log to stderr, which may be error.log """
+        """ Log msg to logging framework """
         msg = msg.strip()
         # Encode unicode msg
         if isinstance(msg, unicode):
             msg = msg.encode(config.charset)
-        # Add time stamp
-        msg = '[%s] %s\n' % (time.asctime(), msg)
-        sys.stderr.write(msg)
+        logging.info(msg)
 
     def write(self, *data):
         """ Write to output stream. """
@@ -1039,7 +1035,6 @@
             # Don't sleep() here, it binds too much of our resources!
             return self.finish()
 
-        self.open_logs()
         _ = self.getText
         self.clock.start('run')
 
@@ -1284,9 +1279,6 @@
         from MoinMoin import failure
         failure.handle(self)
 
-    def open_logs(self):
-        pass
-
     def makeUniqueID(self, base):
         """
         Generates a unique ID using a given base name. Appends a running count to the base.
--- a/MoinMoin/server/__init__.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/server/__init__.py	Mon Sep 25 22:17:59 2006 +0200
@@ -9,6 +9,8 @@
 """
 
 import os
+import logging
+
 from MoinMoin import config
 
 def switchUID(uid, gid):
@@ -32,8 +34,7 @@
         # those calls.
         raise RuntimeError("can't change uid/gid to %s/%s" %
                            (uid, gid))
-    import sys
-    sys.stderr.write("Running as uid/gid %d/%d\n" % (uid, gid))
+    logging.info("Running as uid/gid %d/%d" % (uid, gid))
 
 
 class Config:
@@ -52,11 +53,45 @@
     group = None # group ...
     port = None # tcp port number (if supported)
 
+    # log levels for different log handlers
+    # None means "don't use this handler", otherwise specify the minimum loglevel, e.g. logging.DEBUG
+    # TODO: change later to an appropriate level, for now, we want everything
+    loglevel_file = logging.DEBUG # None
+    loglevel_stderr = logging.DEBUG # None
+    logPath = None
+
     def __init__(self):
         """ Validate and post process configuration values
 
         Will raise RuntimeError for any wrong config value.
         """
+        # First, initialize the logging
+        logger = logging.getLogger('') # root logger
+        logger.setLevel(logging.NOTSET) # otherwise it has WARNING by default!
+
+        if self.loglevel_file is not None and self.logPath is not None:
+            # define a Handler which writes to a log file
+            logfile = logging.FileHandler(self.logPath, 'at') # XXX we can't say ", 0" for sync here :(
+            logfile.setLevel(self.loglevel_file)
+            # set a format which is better for logfile use
+            formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+            # tell the handler to use this format
+            logfile.setFormatter(formatter)
+            # add the handler to the root logger
+            logger.addHandler(logfile)
+
+        if self.loglevel_stderr is not None:
+            # define a Handler which writes INFO to sys.stderr
+            logstderr = logging.StreamHandler()
+            logstderr.setLevel(self.loglevel_stderr)
+            # set a format which is simpler for console use
+            formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s', '%H%M%S')
+            # tell the handler to use this format
+            logstderr.setFormatter(formatter)
+            # add the handler to the root logger
+            logger.addHandler(logstderr)
+
+        logging.info("logging initialized")
 
         # Check that docs path is accessible
         if self.docs:
--- a/MoinMoin/server/cgi.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/server/cgi.py	Mon Sep 25 22:17:59 2006 +0200
@@ -59,9 +59,6 @@
         config.hotshotProfile = hotshot.Profile(config.hotshotProfile)
         config.hotshotProfile.start()
 
-    if config.logPath:
-        sys.stderr = file(config.logPath, 'at', 0)
-
     from MoinMoin.request import CGI
     request = CGI.Request(properties=config.properties)
     request.run()
--- a/MoinMoin/server/standalone.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/server/standalone.py	Mon Sep 25 22:17:59 2006 +0200
@@ -34,7 +34,7 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-import os, sys, time, socket, errno, shutil
+import os, sys, time, socket, errno, shutil, logging
 import BaseHTTPServer, SimpleHTTPServer, SocketServer
 
 from MoinMoin import version, wikiutil
@@ -64,7 +64,7 @@
 
     def server_activate(self):
         BaseHTTPServer.HTTPServer.server_activate(self)
-        sys.stderr.write("Serving on %s:%d\n" % self.server_address)
+        logging.info("Serving on %s:%d" % self.server_address)
 
     def serve_forever(self):
         """Handle one request at a time until we die """
@@ -279,6 +279,9 @@
         SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request,
             client_address, server)
 
+    def log_message(self, format, *args):
+        logging.info("%s %s" % (self.address_string(), format % args))
+
     # -------------------------------------------------------------------
     # do_METHOD dispatchers - called for each request
 
@@ -478,7 +481,7 @@
 def quit(signo, stackframe):
     """ Signal handler for aborting signals """
     global httpd
-    print "\nThanks for using MoinMoin!"
+    logging.info("Thanks for using MoinMoin!")
     if httpd:
         httpd.die()
 
@@ -510,9 +513,8 @@
     if serverClass is ForkingServer and not hasattr(os, "fork"):
         serverClass = SimpleServer
     if serverClass.__name__ != config.serverClass:
-        sys.stderr.write('%s is not available on this platform, falling back '
-                         'to %s\n' % (config.serverClass,
-                                      serverClass.__name__))
+        logging.error('%s is not available on this platform, falling back '
+                      'to %s\n' % (config.serverClass, serverClass.__name__))
 
     from MoinMoin import config as _config
     _config.use_threads = serverClass.use_threads
@@ -573,8 +575,6 @@
         MoinRequestHandler.serve_moin = memoryProfileDecorator(
             MoinRequestHandler.serve_moin, config.memoryProfile)
 
-    if config.logPath:
-        sys.stderr = file(config.logPath, 'at', 0)
     registerSignalHandlers(quit)
     httpd = makeServer(config)
 
--- a/MoinMoin/server/twistedmoin.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/server/twistedmoin.py	Mon Sep 25 22:17:59 2006 +0200
@@ -206,7 +206,8 @@
     port = 8080
     interfaces = ['']
     threads = 10
-    logPath = None
+    logPath = None # moin log file
+    logPath_twisted = None # Twisted log file
     virtualHosts = None
     memoryProfile = None
     hotshotProfile = None
@@ -250,7 +251,7 @@
     root = vhost.NameVirtualHost()
     root.default = default
     # ----------------------------------------------
-    site = MoinSite(root, logPath=config.logPath, timeout=2*60) # 2 minutes timeout
+    site = MoinSite(root, logPath=config.logPath_twisted, timeout=2*60) # 2 minutes timeout
 
     # Make application
     application = service.Application("web", uid=config.uid, gid=config.gid)
--- a/MoinMoin/util/lock.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/MoinMoin/util/lock.py	Mon Sep 25 22:17:59 2006 +0200
@@ -9,13 +9,6 @@
 import os, sys, tempfile, time, errno
 
 
-# Temporary debugging aid, to be replaced with system wide debuging
-# in release 3000.
-#import sys
-#def log(msg):
-#    sys.stderr.write('[%s] lock: %s' % (time.asctime(), msg))
-
-
 class Timer:
     """ Simple count down timer
     
--- a/docs/CHANGES	Mon Sep 25 16:15:57 2006 +0200
+++ b/docs/CHANGES	Mon Sep 25 22:17:59 2006 +0200
@@ -152,6 +152,14 @@
     * Moin got multicall support, including a module that makes it usable on the
       client-side without requiring Python 2.4
     * Added no_magic to text_html formatter to disable tag autoclosing.
+    * Added logging framework, using stdlib's "logging" module. Just do
+      import logging ; logging.debug("your text"). Depending on configuration
+      in the server Config class, your stuff will be written to screen (stderr),
+      to a moin logfile, to apache's error.log, etc.:
+      logPath = None # 'moin.log'
+      loglevel_file = None # logging.DEBUG/INFO/WARNING/ERROR/CRITICAL
+      loglevel_stderr = None # logging.DEBUG/INFO/WARNING/ERROR/CRITICAL
+      NOTE: this is NOT in wikiconfig, but e.g. in moin.cgi or moin.py or ...
 
   New Features:
     * Removed "underscore in URL" == "blank in pagename magic" - it made more
--- a/wiki/server/mointwisted.py	Mon Sep 25 16:15:57 2006 +0200
+++ b/wiki/server/mointwisted.py	Mon Sep 25 22:17:59 2006 +0200
@@ -70,7 +70,10 @@
     # Leaving this as None will have no Apache compatible log file. Apache
     # compatible logfiles are useful because there are quite a few programs
     # which analyze them and display statistics.
-    ## logPath = 'mointwisted.log'
+    ## logPath_twisted = 'mointwisted.log'
+
+    # moin log file
+    ## logPath = 'moin.log'
 
     # Memory profile (default commented)
     # Useful only if you are a developer or interested in moin memory usage