__init__.py (8815B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\stdlogutils\__init__.py 2 import __builtin__ 3 import cStringIO 4 import logging 5 import os 6 import sys 7 import traceback2 8 import zlib 9 from brennivin.logutils import * 10 from stringutil import strx 11 try: 12 import devenv 13 except ImportError: 14 devenv = None 15 16 def GetStack(traceback_list, caughtAt_list = None, show_locals = 0, show_lines = True): 17 stackText = GetStackDescriptionText(traceback_list, caughtAt_list, show_locals, show_lines) 18 stackID = GetStackID(traceback_list, caughtAt_list) 19 cleanStackText = CleanupStack(stackText) 20 return (cleanStackText, stackID) 21 22 23 def GetStackID(traceback_list, caughtAt_list = None): 24 miniStack = GetStackDescriptionText(traceback_list, caughtAt_list, show_locals=0, show_lines=False) 25 miniStack = ''.join(miniStack)[-4000:] 26 stackHash = zlib.adler32(miniStack) 27 return (stackHash, miniStack) 28 29 30 def GetStackDescriptionText(traceback_list, caughtAt_list = None, show_locals = 0, show_lines = True): 31 if caughtAt_list is not None: 32 stack = [' \nCaught at:\n'] 33 stack += FormatList(caughtAt_list, show_locals=0, show_lines=show_lines) 34 stack.append(' \nThrown at:\n') 35 else: 36 stack = [' \nTraced at:\n'] 37 stack += FormatList(traceback_list, show_locals=show_locals, show_lines=show_lines) 38 return stack 39 40 41 def FormatList(traceback_list, show_locals = 0, show_lines = True): 42 cleaned_list = [] 43 for line in traceback_list: 44 l2 = list(line) 45 l2[0] = GetFriendlyPathName(l2[0]) 46 if not show_lines: 47 l2[3] = '' 48 cleaned_list.append(l2) 49 50 lines = traceback2.format_list(cleaned_list, show_locals, format=traceback2.FORMAT_LOGSRV | traceback2.FORMAT_SINGLE) 51 return lines 52 53 54 traceID = 0 55 cachedFriendlyPathNames = {} 56 57 def GetFriendlyPathName(pathName): 58 if pathName not in cachedFriendlyPathNames: 59 friendlyName = os.path.normpath(pathName) 60 friendlyName = friendlyName.replace('\\', '/') 61 cachedFriendlyPathNames[pathName] = strx(friendlyName) 62 return cachedFriendlyPathNames[pathName] 63 64 65 def CleanupStack(stack): 66 pathLines = [ line.lower() for line in stack if isWorthPrefixing(line) ] 67 prefix = os.path.commonprefix(pathLines) 68 prefix = prefix.rstrip('/') 69 out = ['Common path prefix = %s\n' % prefix] 70 trimFrom = len(prefix) 71 out += [ ('<pre>' + line[trimFrom:] if isWorthPrefixing(line) else line) for line in stack ] 72 return out 73 74 75 def isWorthPrefixing(line): 76 return isPathy(line) and '/cache/effectCode.py' not in line 77 78 79 def isPathy(line): 80 return len(line) > 1 and line[1] == ':' 81 82 83 def NextTraceID(): 84 global traceID 85 traceID += 1 86 return traceID 87 88 89 class EveExceptionsFormatter(logging.Formatter): 90 91 def _LogThreadLocals(self, file): 92 file.write('Thread Locals:') 93 if hasattr(__builtin__, 'session'): 94 file.write(' session was ') 95 file.write(str(session) + '\n') 96 else: 97 file.write('No session information available.\n') 98 99 def _LogServerInfo(self, file): 100 from eveprefs import boot 101 if boot is not None: 102 if boot.role != 'client': 103 try: 104 import blue 105 ram = blue.sysinfo.GetMemory().pageFile / 1024 / 1024 106 cpuLoad = sm.GetService('machoNet').GetCPULoad() 107 memLeft = blue.sysinfo.GetMemory().availablePhysical / 1024 / 1024 108 txt = 'System Information: ' 109 txt += ' Node ID: %s' % sm.GetService('machoNet').GetNodeID() 110 if boot.role == 'server': 111 txt += ' | Node Name: %s' % sm.GetService('machoNet').GetLocalHostName() 112 txt += ' | Total CPU load: %s%%%%' % int(cpuLoad) 113 txt += ' | Process memory in use: %s MB' % ram 114 txt += ' | Physical memory left: %s MB' % memLeft 115 file.write(txt + '\n') 116 except Exception: 117 sys.exc_clear() 118 119 else: 120 file.write('No boot role available.\n') 121 122 def format(self, record): 123 record.message = record.getMessage() 124 if self.usesTime(): 125 record.asctime = self.formatTime(record, self.datefmt) 126 s = self._fmt % record.__dict__ 127 if record.exc_info: 128 if not record.exc_text: 129 record.exc_text = self.formatException(record.exc_info) 130 if record.exc_text: 131 try: 132 record.asctime = self.formatTime(record, self.datefmt) 133 traceID = NextTraceID() 134 sys.stderr.write('#nolog: An exception has occurred. It will be logged in the log server as exception #{}\n'.format(traceID)) 135 exceptionString = 'EXCEPTION #%d' % traceID + ' logged at %(asctime)s : %(message)s\n%(exc_text)s\nReported from: ' + __name__ + '\nEXCEPTION END' 136 s = exceptionString % record.__dict__ 137 except UnicodeError: 138 s += record.exc_text.decode(sys.getfilesystemencoding(), 'replace') 139 140 return s 141 142 def formatException(self, ei): 143 exctype, exc, tb = ei 144 exception_list = traceback2.extract_tb(tb, extract_locals=True) 145 if tb: 146 caughtAt_list = traceback2.extract_stack(tb.tb_frame) 147 else: 148 caughtAt_list = traceback2.extract_stack(up=2) 149 stack, stackID = GetStack(exception_list, caughtAt_list, show_locals=True) 150 sio = cStringIO.StringIO() 151 formatted_exception = traceback2.format_exception_only(exctype, exc) 152 sio.write(' \n') 153 sio.write('Formatted exception info:\n') 154 for line in formatted_exception: 155 sio.write(line) 156 157 sio.write(' \n') 158 for line in stack: 159 sio.write(line) 160 161 sio.write(' \n') 162 self._LogThreadLocals(sio) 163 self._LogServerInfo(sio) 164 try: 165 sio.write('Stackhash: {}\n'.format(stackID[0])) 166 except Exception: 167 pass 168 169 s = sio.getvalue() 170 sio.close() 171 return s 172 173 174 class FmtExt(Fmt): 175 EVETIME = '%d/%m/%y %H:%M:%S' 176 FMT_EVE = EveExceptionsFormatter(None, EVETIME) 177 178 179 Fmt = FmtExt 180 181 def getLoggerExt(name = None, defaultHandler = None, defaultFormatter = None): 182 lo = logging.getLogger(name) 183 if not lo.handlers and defaultHandler: 184 if defaultFormatter: 185 defaultHandler.setFormatter(defaultFormatter) 186 lo.addHandler(defaultHandler) 187 return lo 188 189 190 GetTimestampedFilename = timestamped_filename 191 GetTimestamp = timestamp 192 193 def GetTimestampedFilename2(appname, basename = None, ext = '.log', fmt = '%Y-%m-%d-%H-%M-%S', timestruct = None, _getpid = os.getpid): 194 if basename is None: 195 basename = appname 196 folder = devenv.GetAppFolder(appname, makedirs=True) 197 return get_timestamped_logfilename(folder, basename, ext, fmt, timestruct, _getpid) 198 199 200 class _LogLevelDisplayInfo(object): 201 202 def __init__(self): 203 self.nameToLevel = {'Not Set': logging.NOTSET, 204 'Debug': logging.DEBUG, 205 'Info': logging.INFO, 206 'Warn': logging.WARN, 207 'Error': logging.ERROR, 208 'Critical': logging.CRITICAL} 209 self.levelToName = dict(zip(self.nameToLevel.values(), self.nameToLevel.keys())) 210 sortedByLevel = sorted(self.nameToLevel.items(), key=lambda kvp: kvp[1]) 211 self.namesSortedByLevel = map(lambda kvp: kvp[0], sortedByLevel) 212 213 214 LogLevelDisplayInfo = _LogLevelDisplayInfo() 215 GetFilenamesFromLoggers = get_filenames_from_loggers 216 RemoveOldFiles = remove_old_files 217 _sentinel = object() 218 219 def AppLogConfig(appname, prefs = None, defaultUseStdOut = False, defaultLogLevelName = 'INFO'): 220 if getattr(AppLogConfig, '__called', False): 221 raise AssertionError('Should only be called once!') 222 223 def getValue(reg, key): 224 if prefs: 225 return prefs.GetValue(reg, key, _sentinel) 226 return _sentinel 227 228 useStdOut = getValue('logging', 'usestdout') 229 if useStdOut == _sentinel: 230 useStdOut = defaultUseStdOut 231 if prefs: 232 prefs.SetValue('logging', 'usestdout', useStdOut) 233 if useStdOut: 234 sh = logging.StreamHandler() 235 sh.setFormatter(Fmt.FMT_LM) 236 logging.root.addHandler(sh) 237 loglevelname = getValue('logging', 'loglevelname') 238 if loglevelname == _sentinel: 239 loglevelname = defaultLogLevelName 240 if prefs: 241 prefs.SetValue('logging', 'loglevelname', loglevelname) 242 loglevel = getattr(logging, loglevelname) 243 logging.root.setLevel(loglevel) 244 logfilename = GetTimestampedFilename2(appname) 245 fh = logging.FileHandler(logfilename) 246 fh.setFormatter(Fmt.FMT_NTLM) 247 logging.root.addHandler(fh) 248 AppLogConfig.__called = True 249 250 251 LineWrap = wrap_line