summaryrefslogtreecommitdiff
path: root/logger.py
diff options
context:
space:
mode:
authorroot <devnull@localhost>2006-04-26 10:48:09 +0000
committerroot <devnull@localhost>2006-04-26 10:48:09 +0000
commit8b1e1c104bdff504b3e775b450432e6462b8d09b (patch)
tree0367359f6a18f318741f387d82dc3dcfd8139950 /logger.py
downloadlogilab-common-8b1e1c104bdff504b3e775b450432e6462b8d09b.tar.gz
forget the past.
forget the past.
Diffstat (limited to 'logger.py')
-rw-r--r--logger.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/logger.py b/logger.py
new file mode 100644
index 0000000..bf98422
--- /dev/null
+++ b/logger.py
@@ -0,0 +1,152 @@
+# 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.
+""" Copyright (c) 2002-2003 LOGILAB S.A. (Paris, FRANCE).
+ http://www.logilab.fr/ -- mailto:contact@logilab.fr
+
+Define a logger interface and two concrete loggers : one which prints
+everything on stdout, the other using syslog.
+"""
+
+__revision__ = "$Id: logger.py,v 1.18 2006-02-03 14:17:42 adim Exp $"
+
+
+import sys
+import traceback
+import time
+
+
+LOG_EMERG = 0
+LOG_ALERT = 1
+LOG_CRIT = 2
+LOG_ERR = 3
+LOG_WARN = 4
+LOG_NOTICE = 5
+LOG_INFO = 6
+LOG_DEBUG = 7
+
+INDICATORS = ['emergency', 'alert', 'critical', 'error',
+ 'warning', 'notice', 'info', 'debug']
+
+
+def make_logger(method='print', threshold=LOG_DEBUG, sid=None, output=None):
+ """return a logger for the given method
+
+ known methods are 'print', 'eprint' and syslog'
+ """
+ if method == 'print':
+ if output is None:
+ output = sys.stdout
+ return PrintLogger(threshold, output, sid=sid)
+ elif method == 'eprint':
+ return PrintLogger(threshold, sys.stderr, sid=sid)
+ elif method == 'syslog':
+ return SysLogger(threshold, sid)
+ elif method == 'file':
+ if not output:
+ raise ValueError('No logfile specified')
+ else:
+ logfile = open(output, 'a')
+ return PrintLogger(threshold, logfile, sid=sid)
+ else:
+ raise ValueError('Unknown logger method: %r' % method)
+
+
+class AbstractLogger:
+ """logger interface.
+ Priorities allow to filter on the importance of events
+ An event gets logged if it's priority is lower than the threshold"""
+
+ def __init__(self, threshold=LOG_DEBUG, priority_indicator=1):
+ self.threshold = threshold
+ self.priority_indicator = priority_indicator
+
+ def log(self, priority=LOG_DEBUG, message='', substs=None):
+ """log a message with priority <priority>
+ substs are optional substrings
+ """
+ #print 'LOG', self, priority, self.threshold, message
+ if priority <= self.threshold :
+ if substs is not None:
+ message = message % substs
+ if self.priority_indicator:
+ message = '[%s] %s' % (INDICATORS[priority], message)
+ self._writelog(priority, message)
+
+ def _writelog(self, priority, message):
+ """Override this method in concrete class """
+ raise NotImplementedError()
+
+ def log_traceback(self, priority=LOG_ERR, tb_info=None):
+ """log traceback information with priority <priority>
+ """
+ assert tb_info is not None
+ e_type, value, tbck = tb_info
+ stacktb = traceback.extract_tb(tbck)
+ l = ['Traceback (most recent call last):']
+ for stackentry in stacktb :
+ if stackentry[3]:
+ plus = '\n %s' % stackentry[3]
+ else:
+ plus = ''
+ l.append('filename="%s" line_number="%s" function_name="%s"%s' %
+ (stackentry[0], stackentry[1], stackentry[2], plus))
+ l.append('%s: %s' % (e_type, value))
+ self.log(priority, '\n'.join(l))
+
+
+class PrintLogger(AbstractLogger):
+ """logger implementation
+
+ log everything to a file, using the standard output by default
+ """
+
+ def __init__(self, threshold, output=sys.stdout, sid=None,
+ encoding='UTF-8'):
+ AbstractLogger.__init__(self, threshold)
+ self.output = output
+ self.sid = sid
+ self.encoding = encoding
+
+ def _writelog(self, priority, message):
+ """overriden from AbstractLogger"""
+ if isinstance(message, unicode):
+ message = message.encode(self.encoding, 'replace')
+ if self.sid is not None:
+ self.output.write('[%s] [%s] %s\n' % (time.asctime(), self.sid,
+ message))
+ else:
+ self.output.write('[%s] %s\n' % (time.asctime(), message))
+ self.output.flush()
+
+class SysLogger(AbstractLogger):
+ """ logger implementation
+
+ log everything to syslog daemon
+ use the LOCAL_7 facility
+ """
+
+ def __init__(self, threshold, sid=None, encoding='UTF-8'):
+ import syslog
+ AbstractLogger.__init__(self, threshold)
+ if sid is None:
+ sid = 'syslog'
+ self.encoding = encoding
+ syslog.openlog(sid, syslog.LOG_PID)
+
+ def _writelog(self, priority, message):
+ """overriden from AbstractLogger"""
+ import syslog
+ if isinstance(message, unicode):
+ message = message.encode(self.encoding, 'replace')
+ syslog.syslog(priority | syslog.LOG_LOCAL7, message)
+