diff options
| author | bwarsaw | 1998-07-02 19:33:22 +0000 |
|---|---|---|
| committer | bwarsaw | 1998-07-02 19:33:22 +0000 |
| commit | 91d9c5c5171c26bef1e07f3086888aed02d0db6f (patch) | |
| tree | 6eb99909c3bca3b319d5e06450dac7439d9984de | |
| parent | e347c2006bc969d1b3cade65f22ba2191a298f91 (diff) | |
| download | mailman-91d9c5c5171c26bef1e07f3086888aed02d0db6f.tar.gz mailman-91d9c5c5171c26bef1e07f3086888aed02d0db6f.tar.zst mailman-91d9c5c5171c26bef1e07f3086888aed02d0db6f.zip | |
| -rw-r--r-- | Mailman/Logging/.cvsignore | 1 | ||||
| -rw-r--r-- | Mailman/Logging/Logger.py | 79 | ||||
| -rw-r--r-- | Mailman/Logging/Makefile.in | 69 | ||||
| -rw-r--r-- | Mailman/Logging/MultiLogger.py | 69 | ||||
| -rw-r--r-- | Mailman/Logging/StampedLogger.py | 82 | ||||
| -rw-r--r-- | Mailman/Logging/Utils.py | 24 | ||||
| -rw-r--r-- | Mailman/Logging/__init__.py | 0 |
7 files changed, 324 insertions, 0 deletions
diff --git a/Mailman/Logging/.cvsignore b/Mailman/Logging/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/Mailman/Logging/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/Mailman/Logging/Logger.py b/Mailman/Logging/Logger.py new file mode 100644 index 000000000..8a111940a --- /dev/null +++ b/Mailman/Logging/Logger.py @@ -0,0 +1,79 @@ +# Copyright (C) 1998 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 +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +"""File-based logger, writes to named category files in mm_cfg.LOG_DIR.""" + +import sys +import os +import Mailman.mm_cfg +from Mailman.Logging.Utils import __logexc + + +class Logger: + def __init__(self, category, nofail=1): + """Nofail (by default) says to fallback to sys.stderr if write + fails to category file. A message is emitted, but the IOError is + caught. Set nofail=0 if you want to handle the error in your code, + instead. + """ + self.__filename = os.path.join(Mailman.mm_cfg.LOG_DIR, category) + self.__fp = None + self.__nofail = nofail + + def __del__(self): + self.close() + + def __repr__(self): + return '<Logger to file: %s>' % self.__filename + + def __get_f(self): + if self.__fp: + return self.__fp + else: + try: + ou = os.umask(002) + try: + f = self.__fp = open(self.__filename, 'a+') + finally: + os.umask(ou) + except IOError, msg: + if self.__nofail: + __logexc(self, msg) + else: + # re-raise the original exception + raise + return f + + def flush(self): + f = self.__get_f() + if hasattr(f, 'flush'): + f.flush() + + def write(self, msg): + f = self.__get_f() + try: + f.write(msg) + except IOError, msg: + __logexc(self, msg) + + def writelines(self, lines): + for l in lines: + self.write(l) + + def close(self): + if not self.__fp: + return + self.__get_f().close() diff --git a/Mailman/Logging/Makefile.in b/Mailman/Logging/Makefile.in new file mode 100644 index 000000000..8a11e0799 --- /dev/null +++ b/Mailman/Logging/Makefile.in @@ -0,0 +1,69 @@ +# Copyright (C) 1998 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 +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# NOTE: Makefile.in is converted into Makefile by the configure script +# in the parent directory. Once configure has run, you can recreate +# the Makefile by running just config.status. + +# Variables set by configure + +VERSION= @VERSION@ + +VPATH= @srcdir@ +srcdir= @srcdir@ +bindir= @bindir@ +prefix= @prefix@ +exec_prefix= @exec_prefix@ + +CC= @CC@ +CHMOD= @CHMOD@ +INSTALL= @INSTALL@ + +DEFS= @DEFS@ + +# Customizable but not set by configure + +OPT= @OPT@ +CFLAGS= $(OPT) $(DEFS) +PACKAGEDIR= $(prefix)/Mailman/Logging +SHELL= /bin/sh + +MODULES= __init__.py Logger.py MultiLogger.py StampedLogger.py \ +Utils.py + +# Modes for directories and executables created by the install +# process. Default to group-writable directories but +# user-only-writable for executables. +DIRMODE= 775 +EXEMODE= 755 +FILEMODE= 644 +INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE) + + +# Rules + +all: + +install: + for f in $(MODULES); \ + do \ + $(INSTALL) -m $(FILEMODE) $$f $(PACKAGEDIR); \ + done + +clean: + +distclean: + -rm Makefile diff --git a/Mailman/Logging/MultiLogger.py b/Mailman/Logging/MultiLogger.py new file mode 100644 index 000000000..728c5c7de --- /dev/null +++ b/Mailman/Logging/MultiLogger.py @@ -0,0 +1,69 @@ +# Copyright (C) 1998 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 +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +"""A mutiple sink logger. Any message written goes to all sub-loggers.""" + +import sys +from Mailman.Logging.Utils import __logexc + + + +class MultiLogger: + def __init__(self, *args): + self.__loggers = [] + for logger in args: + self.__loggers.append(logger) + + def add_logger(self, logger): + if logger not in self.__loggers: + self.__loggers.append(logger) + + def del_logger(self, logger): + if logger in self.__loggers: + self.__loggers.remove(logger) + + def write(self, msg): + for logger in self.__loggers: + # you want to be sure that a bug in one logger doesn't prevent + # logging to all the other loggers + try: + logger.write(msg) + except: + __logexc(logger, msg) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def flush(self): + for logger in self.__loggers: + if hasattr(logger, 'flush'): + # you want to be sure that a bug in one logger doesn't prevent + # logging to all the other loggers + try: + logger.flush() + except: + __logexc(logger) + + def close(self): + for logger in self.__loggers: + # you want to be sure that a bug in one logger doesn't prevent + # logging to all the other loggers + try: + if logger <> sys.__stderr__ and logger <> sys.__stdout__: + logger.close() + except: + __logexc(logger) diff --git a/Mailman/Logging/StampedLogger.py b/Mailman/Logging/StampedLogger.py new file mode 100644 index 000000000..a7a9d9b65 --- /dev/null +++ b/Mailman/Logging/StampedLogger.py @@ -0,0 +1,82 @@ +# Copyright (C) 1998 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 +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import time +from Mailman.Logging.Logger import Logger + +class StampedLogger(Logger): + """Record messages in log files, including date stamp and optional label. + + If manual_reprime is on (off by default), then timestamp prefix will + included only on first .write() and on any write immediately following a + call to the .reprime() method. This is useful for when StampedLogger is + substituting for sys.stderr, where you'd like to see the grouping of + multiple writes under a single timestamp (and there is often is one group, + for uncaught exceptions where a script is bombing). + + In any case, the identifying prefix will only follow writes that start on + a new line. + + Nofail (by default) says to fallback to sys.stderr if write fails to + category file. A message is emitted, but the IOError is caught. + Initialize with nofail=0 if you want to handle the error in your code, + instead. + + """ + def __init__(self, category, label=None, manual_reprime=0, nofail=1): + "If specified, optional label is included after timestamp." + self.__label = label + self.__manual_reprime = manual_reprime + self.__primed = 1 + self.__bol = 1 + Logger.__init__(self, category, nofail=nofail) + + def reprime(self): + """Reset so timestamp will be included with next write.""" + self.__primed = 1 + + def write(self, msg): + if not self.__bol: + prefix = "" + else: + if not self.__manual_reprime or self.__primed: + stamp = time.strftime("%b %d %H:%M:%S %Y ", + time.localtime(time.time())) + self.__primed = 0 + else: + stamp = "" + if self.__label == None: + label = "" + else: + label = "%s:" % self.__label + prefix = stamp + label + Logger.write(self, "%s %s" % (prefix, msg)) + if msg and msg[-1] == '\n': + self.__bol = 1 + else: + self.__bol = 0 + + def writelines(self, lines): + first = 1 + for l in lines: + if first: + self.write(l) + first = 0 + else: + if l and l[0] not in [' ', '\t', '\n']: + Logger.write(self, ' ' + l) + else: + Logger.write(self, l) diff --git a/Mailman/Logging/Utils.py b/Mailman/Logging/Utils.py new file mode 100644 index 000000000..aba3d389d --- /dev/null +++ b/Mailman/Logging/Utils.py @@ -0,0 +1,24 @@ +# Copyright (C) 1998 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 +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import sys +import traceback + + +def __logexc(logger=None, msg=''): + sys.__stderr__.write('Logging error: %s\n' % logger) + traceback.print_exc(file=sys.__stderr__) + sys.__stderr__.write('Original log message:\n%s\n' % msg) diff --git a/Mailman/Logging/__init__.py b/Mailman/Logging/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Mailman/Logging/__init__.py |
