summaryrefslogtreecommitdiff
path: root/mailman/core/logging.py
diff options
context:
space:
mode:
Diffstat (limited to 'mailman/core/logging.py')
-rw-r--r--mailman/core/logging.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/mailman/core/logging.py b/mailman/core/logging.py
new file mode 100644
index 000000000..608b59c2c
--- /dev/null
+++ b/mailman/core/logging.py
@@ -0,0 +1,109 @@
+# Copyright (C) 2006-2008 by the Free Software Foundation, Inc.
+#
+# This file is part of GNU Mailman.
+#
+# GNU Mailman is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
+
+"""Logging initialization, using Python's standard logging package."""
+
+from __future__ import absolute_import
+
+import os
+import sys
+import codecs
+import logging
+import ConfigParser
+
+from mailman.config import config
+from mailman.config.helpers import as_boolean, as_log_level
+
+
+_handlers = []
+
+
+
+class ReopenableFileHandler(logging.Handler):
+ def __init__(self, filename):
+ self._filename = filename
+ self._stream = self._open()
+ logging.Handler.__init__(self)
+
+ def _open(self):
+ return codecs.open(self._filename, 'a', 'utf-8')
+
+ def flush(self):
+ if self._stream:
+ self._stream.flush()
+
+ def emit(self, record):
+ # It's possible for the stream to have been closed by the time we get
+ # here, due to the shut down semantics. This mostly happens in the
+ # test suite, but be defensive anyway.
+ stream = (self._stream if self._stream else sys.stderr)
+ try:
+ msg = self.format(record)
+ fs = '%s\n'
+ try:
+ stream.write(fs % msg)
+ except UnicodeError:
+ stream.write(fs % msg.encode('string-escape'))
+ self.flush()
+ except:
+ self.handleError(record)
+
+ def close(self):
+ self.flush()
+ self._stream.close()
+ self._stream = None
+ logging.Handler.close(self)
+
+ def reopen(self):
+ self._stream.close()
+ self._stream = self._open()
+
+
+
+def initialize(propagate=False):
+ # First, find the root logger and configure the logging subsystem.
+ # Initialize the root logger, then create a formatter for all the sublogs.
+ logging.basicConfig(format=config.logging.root.format,
+ datefmt=config.logging.root.datefmt,
+ level=as_log_level(config.logging.root.level))
+ # Create the subloggers
+ for logger_config in config.logger_configs:
+ logger_name = 'mailman.' + logger_config.name.split('.')[-1]
+ log = logging.getLogger(logger_name)
+ # Get settings from log configuration file (or defaults).
+ log_format = logger_config.format
+ log_datefmt = logger_config.datefmt
+ # Propagation to the root logger is how we handle logging to stderr
+ # when the qrunners are not run as a subprocess of mailmanctl.
+ log.propagate = as_boolean(logger_config.propagate)
+ # Set the logger's level.
+ log.setLevel(as_log_level(logger_config.level))
+ # Create a formatter for this logger, then a handler, and link the
+ # formatter to the handler.
+ formatter = logging.Formatter(fmt=log_format, datefmt=log_datefmt)
+ path_str = logger_config.path
+ path_abs = os.path.normpath(os.path.join(config.LOG_DIR, path_str))
+ handler = ReopenableFileHandler(path_abs)
+ _handlers.append(handler)
+ handler.setFormatter(formatter)
+ log.addHandler(handler)
+
+
+
+def reopen():
+ for handler in _handlers:
+ handler.reopen()