changeset 3105:80e1a910a2f1

make logging more configurable and flexible, packages/modules shall call MoinMoin.server.getLogger
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 23 Feb 2008 21:43:47 +0100
parents a78bf6977df8
children af3dd2bc85cc
files MoinMoin/conftest.py MoinMoin/server/__init__.py MoinMoin/server/server_cgi.py MoinMoin/server/server_fastcgi.py MoinMoin/server/server_modpython.py MoinMoin/server/server_standalone.py MoinMoin/server/server_twisted.py MoinMoin/server/server_wsgi.py docs/CHANGES wiki/config/logging/README wiki/config/logging/logfile wiki/server/moin.cgi wiki/server/moin.fcg wiki/server/moin.wsgi wiki/server/moin_flup_wsgi.py wiki/server/moinmodpy.py wiki/server/mointwisted.py
diffstat 17 files changed, 134 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/conftest.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/conftest.py	Sat Feb 23 21:43:47 2008 +0100
@@ -19,11 +19,41 @@
 @license: GNU GPL, see COPYING for details.
 """
 
+# here you can configure logging used while running the tests,
+# see http://www.python.org/doc/lib/logging-config-fileformat.html
+logging_defaults = {
+    'loglevel': 'DEBUG',
+}
+logging_config = """\
+[loggers]
+keys=root
+
+[handlers]
+keys=stderr
+
+[formatters]
+keys=screen
+
+[logger_root]
+level=%(loglevel)s
+handlers=stderr
+
+[handler_stderr]
+class=StreamHandler
+level=NOTSET
+formatter=screen
+args=(sys.stderr, )
+
+[formatter_screen]
+format=%(asctime)s %(name)s %(levelname)s %(message)s
+datefmt=%H%M%S
+class=logging.Formatter
+"""
+
 import atexit
 from inspect import isclass
 from sys import modules
 import sys
-import logging
 
 import py
 
@@ -87,23 +117,6 @@
     return request
 
 
-def init_test_logging(loglevel_stderr=logging.DEBUG):
-    """ initialize python stdlib logging framework to output stuff to stderr """
-    logger = logging.getLogger('') # root logger
-    logger.setLevel(logging.NOTSET) # otherwise it has WARNING by default!
-
-    # define a Handler which writes to sys.stderr
-    logstderr = logging.StreamHandler()
-    logstderr.setLevel(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")
-
 class TestConfig:
     """ Custom configuration for unit tests
 
@@ -209,7 +222,8 @@
     Function = MoinTestFunction
 
     def __init__(self, *args, **kwargs):
-        init_test_logging()
+        from MoinMoin.server import configureLogging
+        configureLogging(logging_config, logging_defaults)
         self.request = init_test_request()
         super(Module, self).__init__(*args, **kwargs)
 
--- a/MoinMoin/server/__init__.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/__init__.py	Sat Feb 23 21:43:47 2008 +0100
@@ -9,10 +9,25 @@
 """
 
 import os
-import logging
+from StringIO import StringIO
 
 from MoinMoin import config
 
+import logging as _logging
+
+def configureLogging(conf, defaults):
+   from logging.config import fileConfig
+   fileConfig(StringIO(conf), defaults)
+
+def getLogger(name):
+    logger = _logging.getLogger(name)
+    for levelnumber, levelname in _logging._levelNames.items():
+        if isinstance(levelnumber, int): # that list has also the reverse mapping...
+            setattr(logger, levelname, levelnumber)
+    return logger
+
+logging = getLogger('')
+
 def switchUID(uid, gid):
     """ Switch identity to safe user and group
 
@@ -53,12 +68,39 @@
     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
+    # Here you can configure the default logging used when running moin,
+    # see http://www.python.org/doc/lib/logging-config-fileformat.html
+    # We just use moin.log in current directory by default, if you want
+    # anything else, override logging_conf in your server script's Config class.
+    logging_defaults = {
+        'logdir': '.',
+        'loglevel': 'DEBUG',
+}
+    logging_config = """\
+[loggers]
+keys=root
+
+[handlers]
+keys=logfile
+
+[formatters]
+keys=logfile
+
+[logger_root]
+level=%(loglevel)s
+handlers=logfile
+
+[handler_logfile]
+class=StreamHandler
+level=NOTSET
+formatter=logfile
+args=('%(logdir)s/moin.log', 'at')
+
+[formatter_logfile]
+format=%(asctime)s %(name)s %(levelname)s %(message)s
+datefmt=
+class=logging.Formatter
+"""
 
     def __init__(self):
         """ Validate and post process configuration values
@@ -66,30 +108,7 @@
         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)
+        configureLogging(self.logging_config, self.logging_defaults)
 
         # Check that docs path is accessible
         if self.docs:
--- a/MoinMoin/server/server_cgi.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/server_cgi.py	Sat Feb 23 21:43:47 2008 +0100
@@ -32,10 +32,8 @@
 
 class CgiConfig(Config):
     """ CGI default config """
-
     name = 'moin'
     properties = {}
-    logPath = None
 
     # Development options
     hotshotProfile = None # e.g. "moin.prof"
--- a/MoinMoin/server/server_fastcgi.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/server_fastcgi.py	Sat Feb 23 21:43:47 2008 +0100
@@ -35,10 +35,6 @@
 
 class FastCgiConfig(Config):
     """ Set up default server """
-
-    logPath = None # 'moin.log'
-    loglevel_stderr = None # do not write to stderr when using fcgi
-
     properties = {}
     # properties = {'script_name': '/'}
 
--- a/MoinMoin/server/server_modpython.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/server_modpython.py	Sat Feb 23 21:43:47 2008 +0100
@@ -36,8 +36,6 @@
 
 class ModpythonConfig(Config):
     """ Set up default server """
-
-    logPath = None
     properties = {}
 
     # Set up log handler to log to apache log!
--- a/MoinMoin/server/server_standalone.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/server_standalone.py	Sat Feb 23 21:43:47 2008 +0100
@@ -542,7 +542,6 @@
 
 class StandaloneConfig(Config):
     """ Standalone server default config """
-
     name = 'moin'
     properties = {}
     docs = '/usr/share/moin/htdocs'
@@ -550,7 +549,6 @@
     group = 'www-data'
     port = 8000
     interface = 'localhost'
-    logPath = None
 
     # Advanced options
     serverClass = 'ThreadPoolServer'
--- a/MoinMoin/server/server_twisted.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/server_twisted.py	Sat Feb 23 21:43:47 2008 +0100
@@ -207,7 +207,6 @@
     interfaces = ['']
     threads = 10
     timeout = 15 * 60 # 15 minutes
-    logPath = None # moin log file
     logPath_twisted = None # Twisted log file
     virtualHosts = None
     memoryProfile = None
--- a/MoinMoin/server/server_wsgi.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/MoinMoin/server/server_wsgi.py	Sat Feb 23 21:43:47 2008 +0100
@@ -7,8 +7,7 @@
     from MoinMoin.server.server_wsgi import WsgiConfig, moinmoinApp
 
     class Config(WsgiConfig):
-        logPath = 'moin.log' # define your log file here
-        #loglevel_file = logging.INFO # if you do not like the default
+        pass
 
     config = Config() # you MUST create an instance to initialize logging!
     # use moinmoinApp here with your WSGI server / gateway
@@ -23,7 +22,7 @@
 
 class WsgiConfig(Config):
     """ WSGI default config """
-    loglevel_stderr = None # we do not want to write to stderr!
+    pass
 
 
 def moinmoinApp(environ, start_response):
--- a/docs/CHANGES	Sat Feb 23 16:14:04 2008 +0100
+++ b/docs/CHANGES	Sat Feb 23 21:43:47 2008 +0100
@@ -62,6 +62,7 @@
       because you can render the stuff between link start and link end yourself)
 
   New Features:
+    * new powerful and flexible logging, please see wiki/config/logging/.
     * changed markup for links, images and macros, see:
       MoinMoin:MoinMoinTodo/Release 1.7/HelpOnLinking and
       MoinMoin:LinkMarkupCollection
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wiki/config/logging/README	Sat Feb 23 21:43:47 2008 +0100
@@ -0,0 +1,9 @@
+In this directory is a collection of pre-made snippets you can put into your
+wiki config to configure logging. You may have to edit them at some places,
+please read the comments in the snippet.
+
+You can make very flexible and powerful logging configurations using this
+mechanism, for more details see:
+
+http://www.python.org/doc/lib/logging-config-fileformat.html
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wiki/config/logging/logfile	Sat Feb 23 21:43:47 2008 +0100
@@ -0,0 +1,34 @@
+    logging_defaults = {
+        # Directory where logfiles will be created.
+        # Make sure the running moin process has create/write rights there.
+        'logdir': '/path/to/logdir',
+        # Default loglevel, to adjust verbosity: DEBUG, INFO, WARNING, ERROR, CRITICAL
+        'loglevel': 'DEBUG',
+    }
+    logging_config = """\
+[loggers]
+keys=root
+
+[handlers]
+keys=logfile
+
+[formatters]
+keys=logfile
+
+[logger_root]
+level=NOTSET
+handlers=logfile
+
+[handler_logfile]
+class=StreamHandler
+formatter=logfile
+level=%(loglevel)s
+args=('%(logdir)s/moin.log', 'at')
+
+[formatter_logfile]
+format=%(asctime)s %(name)s %(levelname)s %(message)s
+datefmt=
+class=logging.Formatter
+"""
+
+
--- a/wiki/server/moin.cgi	Sat Feb 23 16:14:04 2008 +0100
+++ b/wiki/server/moin.cgi	Sat Feb 23 21:43:47 2008 +0100
@@ -29,12 +29,9 @@
 from MoinMoin.server.server_cgi import CgiConfig, run
 
 class Config(CgiConfig):
-    # Server name
-    # Used to create .log and .prof files
+    # Server name - used to create .prof files
     name = 'moin'
 
-    ## logPath = name + '.log'
-
     # Properties
     # Allow overriding any request property by the value defined in
     # this dict e.g properties = {'script_name': '/mywiki'}.
--- a/wiki/server/moin.fcg	Sat Feb 23 16:14:04 2008 +0100
+++ b/wiki/server/moin.fcg	Sat Feb 23 21:43:47 2008 +0100
@@ -27,9 +27,6 @@
 from MoinMoin.server.server_fastcgi import FastCgiConfig, run
 
 class Config(FastCgiConfig):
-    #loglevel_file = logging.DEBUG  # adapt if you don't like the default
-    logPath = 'moin.log'
-
     properties = {}
     # properties = {'script_name': '/'} # use this instead of the line above if your wiki runs under "/" url
 
--- a/wiki/server/moin.wsgi	Sat Feb 23 16:14:04 2008 +0100
+++ b/wiki/server/moin.wsgi	Sat Feb 23 21:43:47 2008 +0100
@@ -39,8 +39,7 @@
 from MoinMoin.server.server_wsgi import WsgiConfig, moinmoinApp
 
 class Config(WsgiConfig):
-    logPath = 'moin.log' # adapt this to your needs!
-    #loglevel_file = logging.INFO # adapt if you don't like the default
+    pass
 
 config = Config() # MUST create an instance to init logging!
 
--- a/wiki/server/moin_flup_wsgi.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/wiki/server/moin_flup_wsgi.py	Sat Feb 23 21:43:47 2008 +0100
@@ -21,8 +21,7 @@
 from MoinMoin.server.server_wsgi import moinmoinApp, WsgiConfig
 
 class Config(WsgiConfig):
-    logPath = 'moin.log' # adapt to your needs!
-    #loglevel_file = logging.INFO # adapt if you don't like the default
+    pass
 
 config = Config() # MUST create an instance to init logging
 
--- a/wiki/server/moinmodpy.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/wiki/server/moinmodpy.py	Sat Feb 23 21:43:47 2008 +0100
@@ -56,11 +56,6 @@
 
 class MyConfig(ModpythonConfig):
     """ Set up local server-specific stuff here """
-
-    # Make sure moin will have permission to write to this file!
-    # Otherwise it will cause a server error.
-    logPath = "/var/log/apache2/moinlog"
-    
     # Properties
     # Allow overriding any request property by the value defined in
     # this dict e.g properties = {'script_name': '/mywiki'}.
--- a/wiki/server/mointwisted.py	Sat Feb 23 16:14:04 2008 +0100
+++ b/wiki/server/mointwisted.py	Sat Feb 23 21:43:47 2008 +0100
@@ -32,9 +32,8 @@
 
 class Config(TwistedConfig):
 
-    # Server name
-    # Used to create .log, .pid and .prof files
-    name = 'mointwisted'
+    # Server name - used to create .pid and .prof files
+    name = 'moin'
 
     # Path to moin shared files (default '/usr/share/moin/wiki/htdocs')
     docs = '/usr/share/moin/htdocs'
@@ -72,9 +71,6 @@
     # which analyze them and display statistics.
     ## 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
     ## from MoinMoin.util.profile import TwistedProfiler