diff options
| author | bwarsaw | 2006-04-17 04:08:17 +0000 |
|---|---|---|
| committer | bwarsaw | 2006-04-17 04:08:17 +0000 |
| commit | 0ed815a216c7bb6f820cfdf99fc8d31bcfd19fc0 (patch) | |
| tree | 7b710a785331abfe28b5b46a7695e6cbd81b7794 /scripts/driver | |
| parent | 9934c9b2b0e76a0b77b7869ecf68cd960d4d5bd7 (diff) | |
| download | mailman-0ed815a216c7bb6f820cfdf99fc8d31bcfd19fc0.tar.gz mailman-0ed815a216c7bb6f820cfdf99fc8d31bcfd19fc0.tar.zst mailman-0ed815a216c7bb6f820cfdf99fc8d31bcfd19fc0.zip | |
- Convert all logging to Python's standard logging module. Get rid of all
traces of our crufty old Syslog. Most of this work was purely mechanical,
except for:
1) Initializing the loggers. For this, there's a new module
Mailman/loginit.py (yes all modules from now on will use PEP 8
names). We can't call this 'logging.py' because that will
interfere with importing the stdlib module of the same name (can
you say Python 2.5 and absolute imports?).
If you want to write log messages both to the log file and to
stderr, pass True to loginit.initialize(). This will turn on
propagation of log messages to the parent 'mailman' logger, which
is set up to print to stderr. This is how bin/qrunner works when
not running as a subprocess of mailmanctl.
2) The driver script. I had to untwist the StampedLogger stuff and
implement differently printing exceptions and such to log/error
because standard logging objects don't have a write() method. So
we write to a cStringIO and then pass that to the logger.
3) SMTPDirect.py because of the configurability of the log messages.
This required changing SafeDict into a dict subclass (which is
better than using UserDicts anyway -- yay Python 2.3!). It's
probably still possible to flummox things up if you change the
name of the loggers in the SMTP_LOG_* variables in mm_cfg.py.
However, the worst you can do is cause output to go to stderr and
not go to a log file.
Note too that all entry points into the Mailman system must call
Mailman.loginit.initialize() or the log output will go to stderr
(which may occasionally be what you want). Currently all CGIs and
qrunners should be working properly.
I wish I could have tested all code paths that touch the logger, but
that's infeasible. I have tested this, but it's possible that there
were some mistakes in the translation.
- Mailman.Bouncers.BounceAPI.Stop is a singleton, but not a class
instance any more.
- True/False code cleanup, PEP 8 import restructuring, whitespace
normalization, and copyright year updates, as appropriate.
Diffstat (limited to 'scripts/driver')
| -rw-r--r-- | scripts/driver | 121 |
1 files changed, 67 insertions, 54 deletions
diff --git a/scripts/driver b/scripts/driver index ea43c40eb..08bee07bd 100644 --- a/scripts/driver +++ b/scripts/driver @@ -1,6 +1,6 @@ # -*- python -*- -# Copyright (C) 1998-2004 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. # This better succeed. If this fails, Python is royally screwed so we might # as well let the Web server give us a fatal and obtrusive error. @@ -25,15 +26,17 @@ import sys # The driver script prints out a lot of information when a Mailman bug is # encountered. This really helps for development, but it also reveals # information about the host system that some administrators are not -# comfortable with. By setting STEALTH_MODE to 1, you disable the printing of -# this information to the web pages. This information is still, and always, -# printed in the error logs. -STEALTH_MODE = 1 +# comfortable with. By setting STEALTH_MODE to True, you disable the printing +# of this information to the web pages. This information is still, and +# always, printed in the error logs. +STEALTH_MODE = True # This will be set to the entity escaper. def websafe(s): return s +SPACE = ' ' + # This standard driver script is used to run CGI programs, wrapped in code @@ -62,7 +65,7 @@ def run_main(): # These will ensure that even if something between now and the # creation of the real logger below fails, we can still get # *something* meaningful. - logger = None + log = None try: import paths # When running in non-stealth mode, we need to escape entities, @@ -71,19 +74,18 @@ def run_main(): if not STEALTH_MODE: from Mailman.Utils import websafe except: - STEALTH_MODE = 1 + STEALTH_MODE = True raise - # Map stderr to a logger, if possible. - from Mailman.Logging.StampedLogger import StampedLogger - logger = StampedLogger('error', - label='admin', - manual_reprime=1, - nofail=0, - immediate=1) - # Collect stdout in a cStringIO so that if /any/ errors occur during - # printing it won't mess up our diagnostics page. + # Initialize the standard loggers + from Mailman.loginit import initialize + initialize() + import logging + log = logging.getLogger('mailman.error') + # Collect stdout and stderr in cStringIOs so that if /any/ errors + # occur during printing it won't mess up our diagnostics page. from cStringIO import StringIO tempstdout = StringIO() + tempstderr = StringIO() # The name of the module to run is passed in argv[1]. What we # actually do is import the module named by argv[1] that lives in the # Mailman.Cgi package. That module must have a main() function, which @@ -96,10 +98,11 @@ def run_main(): main = getattr(module, 'main') try: try: - sys.stderr = logger sys.stdout = tempstdout + sys.stderr = tempstderr main() sys.__stdout__.write(tempstdout.getvalue()) + sys.__stderr__.write(tempstderr.getvalue()) finally: sys.stderr = sys.__stderr__ sys.stdout = sys.__stdout__ @@ -108,19 +111,15 @@ def run_main(): # produced is still written out to the browser. sys.stdout.write(tempstdout.getvalue()) except: - print_traceback(logger) - print_environment(logger) + print_traceback(log) + print_environment(log) -# We are printing error reporting to two places. One will always be stdout -# and the other will always be the log file. It is assumed that stdout is an -# HTML sink and the log file is a plain text sink. - -def print_traceback(logfp=None): - if logfp is None: - logfp = sys.__stderr__ - +# If possible, we print the error to two places. One will always be stdout +# and the other will be the log file if a log file was created. It is assumed +# that stdout is an HTML sink. +def print_traceback(log=None): try: import traceback except ImportError: @@ -131,14 +130,22 @@ def print_traceback(logfp=None): VERSION = '<undetermined>' # Write to the log file first. - print >> logfp, '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' - print >> logfp, '[----- Mailman Version: %s -----]' % VERSION - print >> logfp, '[----- Traceback ------]' - if traceback: - traceback.print_exc(file=logfp) - else: - print >> logfp, '[failed to import module traceback]' - print >> logfp, '[exc: %s, var: %s]' % sys.exc_info()[0:2] + if log: + from cStringIO import StringIO + outfp = StringIO() + + print >> outfp, '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' + print >> outfp, '[----- Mailman Version: %s -----]' % VERSION + print >> outfp, '[----- Traceback ------]' + if traceback: + traceback.print_exc(file=outfp) + else: + print >> outfp, '[failed to import module traceback]' + print >> outfp, '[exc: %s, var: %s]' % sys.exc_info()[0:2] + # Don't use .exception() since that'll give us the exception twice. + # IWBNI we could print directly to the log's stream, or treat a log + # like an output stream. + log.error('%s', outfp.getvalue()) # Write to the HTML sink. print """\ @@ -170,23 +177,24 @@ Mailman error logs.''' -def print_environment(logfp=None): - if logfp is None: - logfp = sys.__stderr__ - +def print_environment(log=None): try: import os except ImportError: os = None - # Write some information about our Python executable to the log file. - print >> logfp, '[----- Python Information -----]' - print >> logfp, 'sys.version =', sys.version - print >> logfp, 'sys.executable =', sys.executable - print >> logfp, 'sys.prefix =', sys.prefix - print >> logfp, 'sys.exec_prefix =', sys.exec_prefix - print >> logfp, 'sys.path =', sys.exec_prefix - print >> logfp, 'sys.platform =', sys.platform + if log: + from cStringIO import StringIO + outfp = StringIO() + + # Write some information about our Python executable to the log file. + print >> outfp, '[----- Python Information -----]' + print >> outfp, 'sys.version =', sys.version + print >> outfp, 'sys.executable =', sys.executable + print >> outfp, 'sys.prefix =', sys.prefix + print >> outfp, 'sys.exec_prefix =', sys.exec_prefix + print >> outfp, 'sys.path =', sys.exec_prefix + print >> outfp, 'sys.platform =', sys.platform # Write the same information to the HTML sink. if not STEALTH_MODE: @@ -211,12 +219,13 @@ def print_environment(logfp=None): print '</table>' # Write environment variables to the log file. - print >> logfp, '[----- Environment Variables -----]' - if os: - for k, v in os.environ.items(): - print >> logfp, '\t%s: %s' % (k, v) - else: - print >> logfp, '[failed to import module os]' + if log: + print >> logfp, '[----- Environment Variables -----]' + if os: + for k, v in os.environ.items(): + print >> outfp, '\t%s: %s' % (k, v) + else: + print >> outfp, '[failed to import module os]' # Write environment variables to the HTML sink. if not STEALTH_MODE: @@ -235,6 +244,10 @@ def print_environment(logfp=None): else: print '<p><hr>[failed to import module os]' + # Dump the log output + if log: + log.error('%s', outfp.getvalue()) + try: |
