Pretty frequently I find myself needing to log my exceptions, and rather than produce a tangled mess of boilerplate code, I went ahead and put together this snippet to act as a base class for all those exceptions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 | #! /usr/bin/env python3
"""
selflogger.py
Written by Geremy Condra
Licensed under GPLv3
Released 27 May 2009
This module contains a simple exception
designed to self-log.
"""
import logging
import traceback
class LoggingError(Exception):
"""Basic logging error"""
# set the logging options
filename = 'log'
datefmt = '%a, %d %b %Y %H:%M:%S'
format = '%(asctime)s %(levelname)-8s %(message)s'
# build the logger
logging.basicConfig(level=logging.DEBUG,
filename=filename,
datefmt=datefmt,
format=format)
# and get a local variable for it
log = logging.getLogger('')
def __init__(self, *args):
# build the message from the user
user_msg = args[0] if args else "An error has occurred"
# get the traceback from the last error if it exists
try: tb = traceback.format_exc()
# otherwise, get the tb prior to this frame and pretend its us
except:
tb = "Traceback (most recent call last):\n"
tb += ''.join(traceback.format_stack()[:-1])
tb += self.__class__.__name__ + ": " + user_msg
tb += '\n'
# build the complete log message
log_msg = user_msg + "\n" + tb
# and log it
self.log.error(log_msg)
# store the args
self.args = args
if __name__ == "__main__":
# example 1: raise it all by itself
raise LoggingError("AIEEE!")
# example 2: using it to log a re-raise
try: dict()[5]
except: raise LoggingError
|
Comments
Have you looked into Logger.exception?
Calling basicConfig from inside library code isn't nice - only the first call has any effect, and that should be reserved to application code.
Also, the exception should be logged when it is raised, not when it's created.
@Sridhar Yes, I opted to do it this way so that both possibilities would be handled by my formatting code, which is somewhat different in use.
Sign in to comment