source file: /Library/Python/2.3/site-packages/CherryPy-3.0.1-py2.3.egg/cherrypy/_cplogging.py
file stats: 146 lines, 92 executed: 63.0% covered
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. 14. class LogManager(object): 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. 42. def __call__(self, *args, **kwargs): 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. 50. def access(self): 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. 72. def time(self): 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. 79. def _get_builtin_handler(self, log, key): 80. for h in log.handlers: 81. if getattr(h, "_cpbuiltin", None) == key: 82. return h 83. 84. 85. # ------------------------- Screen handlers ------------------------- # 86. 87. def _set_screen_handler(self, log, enable): 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. 99. def _get_screen(self): 100. h = self._get_builtin_handler 101. has_h = h(self.error_log, "screen") or h(self.access_log, "screen") 102. return bool(has_h) 103. 104. def _set_screen(self, newvalue): 105. self._set_screen_handler(self.error_log, newvalue) 106. self._set_screen_handler(self.access_log, newvalue) 107. screen = property(_get_screen, _set_screen, 108. doc="If True, error and access will print to stdout.") 109. 110. 111. # -------------------------- File handlers -------------------------- # 112. 113. def _add_builtin_file_handler(self, log, fname): 114. h = logging.FileHandler(fname) 115. h.setLevel(logging.DEBUG) 116. h.setFormatter(logfmt) 117. h._cpbuiltin = "file" 118. log.addHandler(h) 119. 120. def _set_file_handler(self, log, filename): 121. h = self._get_builtin_handler(log, "file") 122. if filename: 123. if h: 124. if h.baseFilename != os.path.abspath(filename): 125. h.close() 126. log.handlers.remove(h) 127. self._add_builtin_file_handler(log, filename) 128. else: 129. self._add_builtin_file_handler(log, filename) 130. else: 131. if h: 132. h.close() 133. log.handlers.remove(h) 134. 135. def _get_error_file(self): 136. h = self._get_builtin_handler(self.error_log, "file") 137. if h: 138. return h.baseFilename 139. return '' 140. def _set_error_file(self, newvalue): 141. self._set_file_handler(self.error_log, newvalue) 142. error_file = property(_get_error_file, _set_error_file, 143. doc="The filename for self.error_log.") 144. 145. def _get_access_file(self): 146. h = self._get_builtin_handler(self.access_log, "file") 147. if h: 148. return h.baseFilename 149. return '' 150. def _set_access_file(self, newvalue): 151. self._set_file_handler(self.access_log, newvalue) 152. access_file = property(_get_access_file, _set_access_file, 153. doc="The filename for self.access_log.") 154. 155. 156. # ------------------------- WSGI handlers ------------------------- # 157. 158. def _set_wsgi_handler(self, log, enable): 159. h = self._get_builtin_handler(log, "wsgi") 160. if enable: 161. if not h: 162. h = WSGIErrorHandler() 163. h.setLevel(logging.DEBUG) 164. h.setFormatter(logfmt) 165. h._cpbuiltin = "wsgi" 166. log.addHandler(h) 167. elif h: 168. log.handlers.remove(h) 169. 170. def _get_wsgi(self): 171. return bool(self._get_builtin_handler(self.error_log, "wsgi")) 172. 173. def _set_wsgi(self, newvalue): 174. self._set_wsgi_handler(self.error_log, newvalue) 175. wsgi = property(_get_wsgi, _set_wsgi, 176. doc="If True, error messages will be sent to wsgi.errors.") 177. 178. 179. class WSGIErrorHandler(logging.Handler): 180. "A handler class which writes logging records to environ['wsgi.errors']." 181. 182. def flush(self): 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"): #if no unicode support... 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)