_cplogging.py (8226B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\_cplogging.py 2 import datetime 3 import logging 4 logging.Logger.manager.emittedNoHandlerWarning = 1 5 logfmt = logging.Formatter('%(message)s') 6 import os 7 import sys 8 import cherrypy 9 from cherrypy import _cperror 10 11 class LogManager(object): 12 appid = None 13 error_log = None 14 access_log = None 15 access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' 16 logger_root = None 17 18 def __init__(self, appid = None, logger_root = 'cherrypy'): 19 self.logger_root = logger_root 20 self.appid = appid 21 if appid is None: 22 self.error_log = logging.getLogger('%s.error' % logger_root) 23 self.access_log = logging.getLogger('%s.access' % logger_root) 24 else: 25 self.error_log = logging.getLogger('%s.error.%s' % (logger_root, appid)) 26 self.access_log = logging.getLogger('%s.access.%s' % (logger_root, appid)) 27 self.error_log.setLevel(logging.INFO) 28 self.access_log.setLevel(logging.INFO) 29 cherrypy.engine.subscribe('graceful', self.reopen_files) 30 31 def reopen_files(self): 32 for log in (self.error_log, self.access_log): 33 for h in log.handlers: 34 if isinstance(h, logging.FileHandler): 35 h.acquire() 36 h.stream.close() 37 h.stream = open(h.baseFilename, h.mode) 38 h.release() 39 40 def error(self, msg = '', context = '', severity = logging.INFO, traceback = False): 41 if traceback: 42 msg += _cperror.format_exc() 43 self.error_log.log(severity, ' '.join((self.time(), context, msg))) 44 45 def __call__(self, *args, **kwargs): 46 return self.error(*args, **kwargs) 47 48 def access(self): 49 request = cherrypy.serving.request 50 remote = request.remote 51 response = cherrypy.serving.response 52 outheaders = response.headers 53 inheaders = request.headers 54 if response.output_status is None: 55 status = '-' 56 else: 57 status = response.output_status.split(' ', 1)[0] 58 atoms = {'h': remote.name or remote.ip, 59 'l': '-', 60 'u': getattr(request, 'login', None) or '-', 61 't': self.time(), 62 'r': request.request_line, 63 's': status, 64 'b': dict.get(outheaders, 'Content-Length', '') or '-', 65 'f': dict.get(inheaders, 'Referer', ''), 66 'a': dict.get(inheaders, 'User-Agent', '')} 67 for k, v in atoms.items(): 68 if isinstance(v, unicode): 69 v = v.encode('utf8') 70 elif not isinstance(v, str): 71 v = str(v) 72 v = repr(v)[1:-1] 73 atoms[k] = v.replace('"', '\\"') 74 75 try: 76 self.access_log.log(logging.INFO, self.access_log_format % atoms) 77 except: 78 self(traceback=True) 79 80 def time(self): 81 now = datetime.datetime.now() 82 monthnames = ['jan', 83 'feb', 84 'mar', 85 'apr', 86 'may', 87 'jun', 88 'jul', 89 'aug', 90 'sep', 91 'oct', 92 'nov', 93 'dec'] 94 month = monthnames[now.month - 1].capitalize() 95 return '[%02d/%s/%04d:%02d:%02d:%02d]' % (now.day, 96 month, 97 now.year, 98 now.hour, 99 now.minute, 100 now.second) 101 102 def _get_builtin_handler(self, log, key): 103 for h in log.handlers: 104 if getattr(h, '_cpbuiltin', None) == key: 105 return h 106 107 def _set_screen_handler(self, log, enable, stream = None): 108 h = self._get_builtin_handler(log, 'screen') 109 if enable: 110 if not h: 111 if stream is None: 112 stream = sys.stderr 113 h = logging.StreamHandler(stream) 114 h.setFormatter(logfmt) 115 h._cpbuiltin = 'screen' 116 log.addHandler(h) 117 elif h: 118 log.handlers.remove(h) 119 120 def _get_screen(self): 121 h = self._get_builtin_handler 122 has_h = h(self.error_log, 'screen') or h(self.access_log, 'screen') 123 return bool(has_h) 124 125 def _set_screen(self, newvalue): 126 self._set_screen_handler(self.error_log, newvalue, stream=sys.stderr) 127 self._set_screen_handler(self.access_log, newvalue, stream=sys.stdout) 128 129 screen = property(_get_screen, _set_screen, doc="Turn stderr/stdout logging on or off.\n \n If you set this to True, it'll add the appropriate StreamHandler for\n you. If you set it to False, it will remove the handler.\n ") 130 131 def _add_builtin_file_handler(self, log, fname): 132 h = logging.FileHandler(fname) 133 h.setFormatter(logfmt) 134 h._cpbuiltin = 'file' 135 log.addHandler(h) 136 137 def _set_file_handler(self, log, filename): 138 h = self._get_builtin_handler(log, 'file') 139 if filename: 140 if h: 141 if h.baseFilename != os.path.abspath(filename): 142 h.close() 143 log.handlers.remove(h) 144 self._add_builtin_file_handler(log, filename) 145 else: 146 self._add_builtin_file_handler(log, filename) 147 elif h: 148 h.close() 149 log.handlers.remove(h) 150 151 def _get_error_file(self): 152 h = self._get_builtin_handler(self.error_log, 'file') 153 if h: 154 return h.baseFilename 155 return '' 156 157 def _set_error_file(self, newvalue): 158 self._set_file_handler(self.error_log, newvalue) 159 160 error_file = property(_get_error_file, _set_error_file, doc="The filename for self.error_log.\n \n If you set this to a string, it'll add the appropriate FileHandler for\n you. If you set it to ``None`` or ``''``, it will remove the handler.\n ") 161 162 def _get_access_file(self): 163 h = self._get_builtin_handler(self.access_log, 'file') 164 if h: 165 return h.baseFilename 166 return '' 167 168 def _set_access_file(self, newvalue): 169 self._set_file_handler(self.access_log, newvalue) 170 171 access_file = property(_get_access_file, _set_access_file, doc="The filename for self.access_log.\n \n If you set this to a string, it'll add the appropriate FileHandler for\n you. If you set it to ``None`` or ``''``, it will remove the handler.\n ") 172 173 def _set_wsgi_handler(self, log, enable): 174 h = self._get_builtin_handler(log, 'wsgi') 175 if enable: 176 if not h: 177 h = WSGIErrorHandler() 178 h.setFormatter(logfmt) 179 h._cpbuiltin = 'wsgi' 180 log.addHandler(h) 181 elif h: 182 log.handlers.remove(h) 183 184 def _get_wsgi(self): 185 return bool(self._get_builtin_handler(self.error_log, 'wsgi')) 186 187 def _set_wsgi(self, newvalue): 188 self._set_wsgi_handler(self.error_log, newvalue) 189 190 wsgi = property(_get_wsgi, _set_wsgi, doc="Write errors to wsgi.errors.\n \n If you set this to True, it'll add the appropriate\n :class:`WSGIErrorHandler<cherrypy._cplogging.WSGIErrorHandler>` for you\n (which writes errors to ``wsgi.errors``).\n If you set it to False, it will remove the handler.\n ") 191 192 193 class WSGIErrorHandler(logging.Handler): 194 195 def flush(self): 196 try: 197 stream = cherrypy.serving.request.wsgi_environ.get('wsgi.errors') 198 except (AttributeError, KeyError): 199 pass 200 else: 201 stream.flush() 202 203 def emit(self, record): 204 try: 205 stream = cherrypy.serving.request.wsgi_environ.get('wsgi.errors') 206 except (AttributeError, KeyError): 207 pass 208 else: 209 try: 210 msg = self.format(record) 211 fs = '%s\n' 212 import types 213 if not hasattr(types, 'UnicodeType'): 214 stream.write(fs % msg) 215 else: 216 try: 217 stream.write(fs % msg) 218 except UnicodeError: 219 stream.write(fs % msg.encode('UTF-8')) 220 221 self.flush() 222 except: 223 self.handleError(record)