sys.modules['bsddb3'] is already in the local namespace.
[cvs2svn.git] / cvs2svn_lib / log.py
blob1ab4614f9eca2fa962989f5fcaf5dad6f718f147
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2008 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module contains a simple logging facility for cvs2svn."""
20 import sys
21 import time
22 import threading
25 class _Log:
26 """A Simple logging facility.
28 If self.log_level is DEBUG or higher, each line will be timestamped
29 with the number of wall-clock seconds since the time when this
30 module was first imported.
32 The public methods of this class are thread-safe."""
34 # These constants represent the log levels that this class supports.
35 # The increase_verbosity() and decrease_verbosity() methods rely on
36 # these constants being consecutive integers:
37 ERROR = -2
38 WARN = -1
39 QUIET = 0
40 NORMAL = 1
41 VERBOSE = 2
42 DEBUG = 3
44 start_time = time.time()
46 def __init__(self):
47 self.log_level = _Log.NORMAL
49 # The output file to use for errors:
50 self._err = sys.stderr
52 # The output file to use for lower-priority messages:
53 self._out = sys.stdout
55 # Lock to serialize writes to the log:
56 self.lock = threading.Lock()
58 def increase_verbosity(self):
59 self.lock.acquire()
60 try:
61 self.log_level = min(self.log_level + 1, _Log.DEBUG)
62 finally:
63 self.lock.release()
65 def decrease_verbosity(self):
66 self.lock.acquire()
67 try:
68 self.log_level = max(self.log_level - 1, _Log.ERROR)
69 finally:
70 self.lock.release()
72 def is_on(self, level):
73 """Return True iff messages at the specified LEVEL are currently on.
75 LEVEL should be one of the constants _Log.WARN, _Log.QUIET, etc."""
77 return self.log_level >= level
79 def _timestamp(self):
80 """Return a timestamp if needed, as a string with a trailing space."""
82 retval = []
84 if self.log_level >= _Log.DEBUG:
85 retval.append('%f: ' % (time.time() - self.start_time,))
87 return ''.join(retval)
89 def _write(self, out, *args):
90 """Write a message to OUT.
92 If there are multiple ARGS, they will be separated by spaces. If
93 there are multiple lines, they will be output one by one with the
94 same timestamp prefix."""
96 timestamp = self._timestamp()
97 s = ' '.join(map(str, args))
98 lines = s.split('\n')
99 if lines and not lines[-1]:
100 del lines[-1]
102 self.lock.acquire()
103 try:
104 for s in lines:
105 out.write('%s%s\n' % (timestamp, s,))
106 # Ensure that log output doesn't get out-of-order with respect to
107 # stderr output.
108 out.flush()
109 finally:
110 self.lock.release()
112 def write(self, *args):
113 """Write a message to SELF._out.
115 This is a public method to use for writing to the output log
116 unconditionally."""
118 self._write(self._out, *args)
120 def error(self, *args):
121 """Log a message at the ERROR level."""
123 if self.is_on(_Log.ERROR):
124 self._write(self._err, *args)
126 def warn(self, *args):
127 """Log a message at the WARN level."""
129 if self.is_on(_Log.WARN):
130 self._write(self._out, *args)
132 def quiet(self, *args):
133 """Log a message at the QUIET level."""
135 if self.is_on(_Log.QUIET):
136 self._write(self._out, *args)
138 def normal(self, *args):
139 """Log a message at the NORMAL level."""
141 if self.is_on(_Log.NORMAL):
142 self._write(self._out, *args)
144 def verbose(self, *args):
145 """Log a message at the VERBOSE level."""
147 if self.is_on(_Log.VERBOSE):
148 self._write(self._out, *args)
150 def debug(self, *args):
151 """Log a message at the DEBUG level."""
153 if self.is_on(_Log.DEBUG):
154 self._write(self._out, *args)
157 # Create an instance that everybody can use:
158 logger = _Log()