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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
# Copyright (C) 2014 Ipsilon Project Contributors
#
# See the file named COPYING for the project license
import cherrypy
import cStringIO
import inspect
import os
import traceback
class Log(object):
@staticmethod
def stacktrace():
buf = cStringIO.StringIO()
stack = traceback.extract_stack()
traceback.print_list(stack[:-2], file=buf)
stacktrace_string = buf.getvalue()
buf.close()
return stacktrace_string
@staticmethod
def get_class_from_frame(frame_obj):
'''
Taken from:
http://stackoverflow.com/questions/2203424/
python-how-to-retrieve-class-information-from-a-frame-object
At the frame object level, there does not seem to be any way
to find the actual python function object that has been
called.
However, if your code relies on the common convention of naming
the instance parameter of a method self, then you could do this.
'''
args, _, _, value_dict = inspect.getargvalues(frame_obj)
# Is the functions first parameter named 'self'?
if len(args) and args[0] == 'self':
# in that case, 'self' will be referenced in value_dict
instance = value_dict.get('self', None)
if instance:
# return its class
return getattr(instance, '__class__', None)
# return None otherwise
return None
@staticmethod
def call_location():
frame = inspect.stack()[2]
frame_obj = frame[0]
filename = frame[1]
line_number = frame[2]
func = frame[3]
# Only report the last 3 components of the path
filename = os.sep.join(filename.split(os.sep)[-3:])
cls = Log.get_class_from_frame(frame_obj)
if cls:
location = '%s:%s %s.%s()' % \
(filename, line_number, cls.__name__, func)
else:
location = '%s:%s %s()' % (filename, line_number, func)
return location
def debug(self, fact):
if cherrypy.config.get('debug', False):
location = Log.call_location()
cherrypy.log('DEBUG(%s): %s' % (location, fact))
# for compatibility with existing code
_debug = debug
def log(self, fact):
cherrypy.log(fact)
def error(self, fact):
cherrypy.log.error('ERROR: %s' % fact)
if cherrypy.config.get('stacktrace_on_error', False):
cherrypy.log.error(Log.stacktrace())
|