1 """CherryPy logging."""
2
3 import datetime
4 import logging
5 logfmt = logging.Formatter("%(message)s")
6 import os
7 import rfc822
8 import sys
9
10 import cherrypy
11 from cherrypy import _cperror
12
13
15
16 appid = None
17 error_log = None
18 access_log = None
19
20 - def __init__(self, appid=None, logger_root="cherrypy"):
21 self.logger_root = logger_root
22 self.appid = appid
23 if appid is None:
24 self.error_log = logging.getLogger("%s.error" % logger_root)
25 self.access_log = logging.getLogger("%s.access" % logger_root)
26 else:
27 self.error_log = logging.getLogger("%s.error.%s" % (logger_root, appid))
28 self.access_log = logging.getLogger("%s.access.%s" % (logger_root, appid))
29 self.error_log.setLevel(logging.DEBUG)
30 self.access_log.setLevel(logging.INFO)
31
32 - def error(self, msg='', context='', severity=logging.DEBUG, traceback=False):
33 """Write to the error log.
34
35 This is not just for errors! Applications may call this at any time
36 to log application-specific information.
37 """
38 if traceback:
39 msg += _cperror.format_exc()
40 self.error_log.log(severity, ' '.join((self.time(), context, msg)))
41
43 """Write to the error log.
44
45 This is not just for errors! Applications may call this at any time
46 to log application-specific information.
47 """
48 return self.error(*args, **kwargs)
49
51 """Write to the access log."""
52 request = cherrypy.request
53 remote = request.remote
54 response = cherrypy.response
55 outheaders = response.headers
56 tmpl = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
57 s = tmpl % {'h': remote.name or remote.ip,
58 'l': '-',
59 'u': getattr(request, "login", None) or "-",
60 't': self.time(),
61 'r': request.request_line,
62 's': response.status.split(" ", 1)[0],
63 'b': outheaders.get('Content-Length', '') or "-",
64 'f': outheaders.get('referer', ''),
65 'a': outheaders.get('user-agent', ''),
66 }
67 try:
68 self.access_log.log(logging.INFO, s)
69 except:
70 self(traceback=True)
71
73 """Return now() in Apache Common Log Format (no timezone)."""
74 now = datetime.datetime.now()
75 month = rfc822._monthnames[now.month - 1].capitalize()
76 return ('[%02d/%s/%04d:%02d:%02d:%02d]' %
77 (now.day, month, now.year, now.hour, now.minute, now.second))
78
80 for h in log.handlers:
81 if getattr(h, "_cpbuiltin", None) == key:
82 return h
83
84
85
86
88 h = self._get_builtin_handler(log, "screen")
89 if enable:
90 if not h:
91 h = logging.StreamHandler(sys.stdout)
92 h.setLevel(logging.DEBUG)
93 h.setFormatter(logfmt)
94 h._cpbuiltin = "screen"
95 log.addHandler(h)
96 elif h:
97 log.handlers.remove(h)
98
103
107 screen = property(_get_screen, _set_screen,
108 doc="If True, error and access will print to stdout.")
109
110
111
112
114 h = logging.FileHandler(fname)
115 h.setLevel(logging.DEBUG)
116 h.setFormatter(logfmt)
117 h._cpbuiltin = "file"
118 log.addHandler(h)
119
134
142 error_file = property(_get_error_file, _set_error_file,
143 doc="The filename for self.error_log.")
144
152 access_file = property(_get_access_file, _set_access_file,
153 doc="The filename for self.access_log.")
154
155
156
157
169
172
175 wsgi = property(_get_wsgi, _set_wsgi,
176 doc="If True, error messages will be sent to wsgi.errors.")
177
178
180 "A handler class which writes logging records to environ['wsgi.errors']."
181
183 """Flushes the stream."""
184 try:
185 stream = cherrypy.request.wsgi_environ.get('wsgi.errors')
186 except AttributeError, KeyError:
187 pass
188 else:
189 stream.flush()
190
191 - def emit(self, record):
192 """Emit a record."""
193 try:
194 stream = cherrypy.request.wsgi_environ.get('wsgi.errors')
195 except AttributeError, KeyError:
196 pass
197 else:
198 try:
199 msg = self.format(record)
200 fs = "%s\n"
201 import types
202 if not hasattr(types, "UnicodeType"):
203 stream.write(fs % msg)
204 else:
205 try:
206 stream.write(fs % msg)
207 except UnicodeError:
208 stream.write(fs % msg.encode("UTF-8"))
209 self.flush()
210 except:
211 self.handleError(record)
212