|
21 | 21 | Should work under Python versions >= 1.5.2, except that source line |
22 | 22 | information is not available unless 'sys._getframe()' is. |
23 | 23 |
|
24 | | -Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved. |
| 24 | +Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved. |
25 | 25 |
|
26 | 26 | To use, simply 'import logging' and log away! |
27 | 27 | """ |
|
36 | 36 |
|
37 | 37 | __author__ = "Vinay Sajip <[email protected]>" |
38 | 38 | __status__ = "beta" |
39 | | -__version__ = "0.4.8.1" |
40 | | -__date__ = "26 June 2003" |
| 39 | +__version__ = "0.4.9" |
| 40 | +__date__ = "20 February 2004" |
41 | 41 |
|
42 | 42 | #--------------------------------------------------------------------------- |
43 | 43 | # Miscellaneous module data |
@@ -198,6 +198,7 @@ def __init__(self, name, level, pathname, lineno, msg, args, exc_info): |
198 | 198 | self.filename = pathname |
199 | 199 | self.module = "Unknown module" |
200 | 200 | self.exc_info = exc_info |
| 201 | + self.exc_text = None # used to cache the traceback text |
201 | 202 | self.lineno = lineno |
202 | 203 | self.created = ct |
203 | 204 | self.msecs = (ct - long(ct)) * 1000 |
@@ -364,9 +365,14 @@ def format(self, record): |
364 | 365 | record.asctime = self.formatTime(record, self.datefmt) |
365 | 366 | s = self._fmt % record.__dict__ |
366 | 367 | if record.exc_info: |
| 368 | + # Cache the traceback text to avoid converting it multiple times |
| 369 | + # (it's constant anyway) |
| 370 | + if not record.exc_text: |
| 371 | + record.exc_text = self.formatException(record.exc_info) |
| 372 | + if record.exc_text: |
367 | 373 | if s[-1] != "\n": |
368 | 374 | s = s + "\n" |
369 | | - s = s + self.formatException(record.exc_info) |
| 375 | + s = s + record.exc_text |
370 | 376 | return s |
371 | 377 |
|
372 | 378 | # |
@@ -613,10 +619,17 @@ def close(self): |
613 | 619 | """ |
614 | 620 | Tidy up any resources used by the handler. |
615 | 621 |
|
616 | | - This version does nothing and is intended to be implemented by |
617 | | - subclasses. |
| 622 | + This version does removes the handler from an internal list |
| 623 | + of handlers which is closed when shutdown() is called. Subclasses |
| 624 | + should ensure that this gets called from overridden close() |
| 625 | + methods. |
618 | 626 | """ |
619 | | - pass |
| 627 | + #get the module data lock, as we're updating a shared structure. |
| 628 | + _acquireLock() |
| 629 | + try: #unlikely to raise an exception, but you never know... |
| 630 | + del _handlers[self] |
| 631 | + finally: |
| 632 | + _releaseLock() |
620 | 633 |
|
621 | 634 | def handleError(self, record): |
622 | 635 | """ |
@@ -700,6 +713,7 @@ def close(self): |
700 | 713 | Closes the stream. |
701 | 714 | """ |
702 | 715 | self.stream.close() |
| 716 | + StreamHandler.close(self) |
703 | 717 |
|
704 | 718 | #--------------------------------------------------------------------------- |
705 | 719 | # Manager classes and functions |
@@ -989,7 +1003,8 @@ def _log(self, level, msg, args, exc_info=None): |
989 | 1003 | else: |
990 | 1004 | fn, lno = "<unknown file>", 0 |
991 | 1005 | if exc_info: |
992 | | - exc_info = sys.exc_info() |
| 1006 | + if type(exc_info) != types.TupleType: |
| 1007 | + exc_info = sys.exc_info() |
993 | 1008 | record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info) |
994 | 1009 | self.handle(record) |
995 | 1010 |
|
@@ -1194,3 +1209,16 @@ def shutdown(): |
1194 | 1209 | for h in _handlers.keys(): |
1195 | 1210 | h.flush() |
1196 | 1211 | h.close() |
| 1212 | + |
| 1213 | +#Let's try and shutdown automatically on application exit... |
| 1214 | +try: |
| 1215 | + import atexit |
| 1216 | + atexit.register(shutdown) |
| 1217 | +except ImportError: # for Python versions < 2.0 |
| 1218 | + def exithook(status, old_exit=sys.exit): |
| 1219 | + try: |
| 1220 | + shutdown() |
| 1221 | + finally: |
| 1222 | + old_exit(status) |
| 1223 | + |
| 1224 | + sys.exit = exithook |
0 commit comments