NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

__init__.py (16009B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\logmodule\__init__.py
      2 from __future__ import print_function
      3 import sys
      4 import datetime
      5 import traceback2
      6 import __builtin__
      7 from cStringIO import StringIO
      8 import os
      9 import blue
     10 import localstorage
     11 from stdlogutils import GetStack, NextTraceID
     12 from stdlogutils.logserver import LGINFO, LGNOTICE, LGWARN, LGERR
     13 from stdlogutils.logserver import ChannelWrapper, LogChannelStream
     14 from eveexceptions import UserError
     15 DATETIME_FORMAT_STR = '%m/%d/%Y %H:%M:%S'
     16 Suppress = ChannelWrapper.Suppress
     17 Unsuppress = ChannelWrapper.Unsuppress
     18 SuppressAllChannels = ChannelWrapper.SuppressAllChannels
     19 UnsuppressAllChannels = ChannelWrapper.UnsuppressAllChannels
     20 channelDict = ChannelWrapper.channelDict
     21 uiMessageFunc = None
     22 sentry_client = None
     23 _WIN_EBADF = 9
     24 Channel = ChannelWrapper
     25 for f in Channel.flags:
     26     globals()[f] = Channel.flags[f]
     27     globals()[f.lower()] = Channel.flags[f]
     28 
     29 baseName = ''
     30 channels = {}
     31 logExceptionLevel = 0
     32 postStackTraceAll = None
     33 
     34 def MsgWindowStreamToMsgWindow():
     35     from eveprefs import prefs
     36     if hasattr(session, 'userid') and session.userid and settings.generic:
     37         return settings.generic.Get('exceptionPopups', 0)
     38     if prefs:
     39         return prefs.GetValue('exceptionPopups', 0)
     40     return 0
     41 
     42 
     43 def SetUiMessageFunc(func):
     44     global uiMessageFunc
     45     uiMessageFunc = func
     46 
     47 
     48 def SetStackFileNameSubPaths(filePaths):
     49     pass
     50 
     51 
     52 def DefaultUIMessage(*args):
     53     print(args)
     54 
     55 
     56 def init(base_name = '', prefs = None):
     57     global baseName
     58     baseName = base_name
     59     if prefs is not None:
     60         ChannelWrapper.Initialize(prefs)
     61     SetUiMessageFunc(DefaultUIMessage)
     62 
     63 
     64 def AddGlobalChannels(channels):
     65     g = globals()
     66     for channel in channels:
     67         if channel.lower() not in g:
     68             g[channel.lower()] = GetChannel(channel)
     69 
     70 
     71 def GetChannel(name):
     72     if '.' not in name:
     73         name = baseName + '.' + name
     74     if name not in channels:
     75         s = name.split('.')
     76         facility = '.'.join(s[:-1])
     77         obj = s[-1]
     78         channels[name] = Channel(facility.encode('utf-8'), obj.encode('utf-8'))
     79     return channels[name]
     80 
     81 
     82 ui = GetChannel('UI')
     83 general = GetChannel('General')
     84 methodcalls = GetChannel('MethodCalls')
     85 unittest = GetChannel('Unittest')
     86 
     87 def LogException(extraText = '', channel = 'general', toConsole = 1, toLogServer = 1, toAlertSvc = None, toMsgWindow = 1, exctype = None, exc = None, tb = None, severity = None, show_locals = 1):
     88     global logExceptionLevel
     89     if logExceptionLevel > 0:
     90         return
     91     _tmpctx = blue.pyos.taskletTimer.EnterTasklet('logmodule::LogException')
     92     logExceptionLevel += 1
     93     if not exctype:
     94         exctype, exc, tb = sys.exc_info()
     95     try:
     96         try:
     97             _LogException((exctype, exc, tb), extraText, channel, toConsole, toLogServer, toAlertSvc, toMsgWindow, severity, show_locals)
     98             return
     99         except Exception:
    100             try:
    101                 traceback2.print_exc(show_locals=3)
    102                 stream = LogChannelStream(GetChannel('general'), ERR)
    103                 traceback2.print_exc(show_locals=3, file=stream)
    104                 stream.close()
    105             except Exception:
    106                 pass
    107 
    108         try:
    109             traceback2.print_exception(exctype, exc, tb, file=sys.stdout, show_locals=show_locals)
    110             stream = LogChannelStream(GetChannel(channel), ERR)
    111             print('retrying traceback log, got an error in _LogException', file=stream)
    112             traceback2.print_exception(exctype, exc, tb, file=stream, show_locals=show_locals)
    113             stream.close()
    114         except Exception:
    115             try:
    116                 traceback2.print_exc(show_locals=3)
    117             except:
    118                 pass
    119 
    120     finally:
    121         del tb
    122         logExceptionLevel -= 1
    123         blue.pyos.taskletTimer.ReturnFromTasklet(_tmpctx)
    124 
    125 
    126 def _LogException(exc_info, extraText, channel, toConsole, toLogServer, toAlertSvc, toMsgWindow, severity, show_locals):
    127     from eveprefs import boot
    128     if sentry_client:
    129         sentry_client(message=extraText, exc_info=exc_info)
    130     exctype, exc, tb = exc_info
    131     exception_list = traceback2.extract_tb(tb, extract_locals=show_locals)
    132     if tb:
    133         caught_list = traceback2.extract_stack(tb.tb_frame)
    134     else:
    135         caught_list = traceback2.extract_stack(up=2)
    136     stack, stackID = GetStack(exception_list, caught_list, show_locals=show_locals)
    137     if severity is None:
    138         severity = (ERR, WARN)[isinstance(exc, UserError)]
    139     if toAlertSvc is None:
    140         toAlertSvc = severity in (ERR,)
    141     if toMsgWindow and isinstance(exc, UserError) and boot.role == 'client':
    142         toMsgWindow = 0
    143         uiMessageFunc(*exc.args)
    144     out = GetMultiplex(channel, severity, toConsole, toLogServer, toMsgWindow, toAlertSvc, stackID)
    145     formatted_exception = traceback2.format_exception_only(exctype, exc)
    146     if not extraText:
    147         try:
    148             extraText = 'Info: %s' % formatted_exception[-1].strip()
    149         except:
    150             extraText = 'Info: <none>'
    151 
    152     prefix = 'REMOTE ' if channel == 'remote.exc' else ''
    153     traceID = NextTraceID()
    154     print('%sEXCEPTION #%d logged at %s : %s ' % (prefix,
    155      traceID,
    156      datetime.datetime.utcnow().strftime(DATETIME_FORMAT_STR),
    157      extraText), file=out)
    158     print(' ', file=out)
    159     print('Formatted exception info:', end=' ', file=out)
    160     for line in formatted_exception:
    161         print(line, end=' ', file=out)
    162 
    163     print(' ', file=out)
    164     for line in stack:
    165         print(line, end=' ', file=out)
    166 
    167     print(' ', file=out)
    168     if exctype is MemoryError:
    169         try:
    170             DumpMemoryStatus(out)
    171             DumpMemHistory(out)
    172         except:
    173             pass
    174 
    175     try:
    176         _LogThreadLocals(out)
    177     except MemoryError:
    178         pass
    179 
    180     if boot.role != 'client':
    181         try:
    182             ram = blue.sysinfo.GetMemory().pageFile / 1024 / 1024
    183             cpuLoad = sm.GetService('machoNet').GetCPULoad()
    184             memLeft = blue.sysinfo.GetMemory().availablePhysical / 1024 / 1024
    185             txt = 'System Information: '
    186             txt += ' Node ID: %s' % sm.GetService('machoNet').GetNodeID()
    187             if boot.role == 'server':
    188                 txt += ' | Node Name: %s' % sm.GetService('machoNet').GetLocalHostName()
    189             txt += ' | Total CPU load: %s%%' % int(cpuLoad)
    190             txt += ' | Process memory in use: %s MB' % ram
    191             txt += ' | Physical memory left: %s MB' % memLeft
    192             print(txt, file=out)
    193         except Exception as e:
    194             sys.exc_clear()
    195 
    196     try:
    197         print('Stackhash: %s' % stackID[0], file=out)
    198     except Exception:
    199         pass
    200 
    201     print('Reported from: ', __name__, file=out)
    202     print('%sEXCEPTION END' % (prefix,), file=out)
    203     out.flush()
    204     if toConsole:
    205         if toLogServer:
    206             print('#nolog: An exception has occurred. It has been logged in the log server as exception #%d' % traceID, file=sys.stderr)
    207         else:
    208             print('There is no useful information accompanying this exception in the log server', file=sys.stderr)
    209 
    210 
    211 def DumpMemHistory(out):
    212     from eveprefs import boot
    213     try:
    214         if boot.role != 'client':
    215             import blue, cPickle
    216             fname = blue.paths.ResolvePath(u'root:/') + 'logs/memhist.b%d.%s.pikl' % (boot.build, blue.os.pid)
    217             print('dumping cpu and memory history in ' + fname, file=out)
    218             f = file(fname, 'w')
    219             cPickle.dump(blue.pyos.cpuUsage, f)
    220             f.close()
    221             print('dump done.', file=out)
    222     except Exception:
    223         pass
    224 
    225 
    226 def LogTraceback(extraText = '', channel = 'general', toConsole = 1, toAlertSvc = None, toLogServer = 1, nthParent = 0, daStack = None, severity = LGERR, show_locals = 1, limit = None):
    227     if logExceptionLevel > 0:
    228         return
    229     _tmpctx = blue.pyos.taskletTimer.EnterTasklet('logmodule::LogTraceback')
    230     try:
    231         if daStack is None:
    232             daStack = traceback2.extract_stack(limit=limit, up=nthParent + 1, extract_locals=show_locals)
    233         stack, stackID = GetStack(daStack, None, show_locals, True)
    234         if toAlertSvc is None:
    235             toAlertSvc = severity in (ERR,)
    236         toMsgWindow = False
    237         multiplexToConsole = False if toLogServer else toConsole
    238         out = GetMultiplex(channel, severity, multiplexToConsole, toLogServer, toMsgWindow, toAlertSvc, stackID)
    239         traceID = NextTraceID()
    240         logMessage = StringIO()
    241         logMessage.write('STACKTRACE #%d logged at %s : %s\n' % (traceID, datetime.datetime.utcnow().strftime(DATETIME_FORMAT_STR), extraText))
    242         logMessage.write(' \n')
    243         for line in stack:
    244             logMessage.write(line)
    245 
    246         logMessage.write(' \n')
    247         _LogThreadLocals(logMessage)
    248         logMessage.write('Stackhash: %s\n' % stackID[0])
    249         logMessage.write('Reported from: ' + __name__ + '\n')
    250         logMessage.write('STACKTRACE END')
    251         print(logMessage.getvalue(), file=out)
    252         out.flush()
    253         if toConsole:
    254             if toLogServer:
    255                 if '/jessica' in blue.pyos.GetArg():
    256                     print('#nolog: ' + logMessage.getvalue(), file=sys.stderr)
    257                 else:
    258                     print('#nolog: A traceback has been generated. It has been logged in the log server as stacktrace #%d' % traceID, file=sys.stderr)
    259             else:
    260                 print('There is no useful information accompanying this traceback in the log server', file=sys.stderr)
    261     finally:
    262         blue.pyos.taskletTimer.ReturnFromTasklet(_tmpctx)
    263 
    264 
    265 def LogMemoryStatus(extraText = '', channel = 'general'):
    266     out = GetMultiplex(channel, WARN, 0, 1, 0, 0, 0)
    267     print('Logging memory status : ', extraText, file=out)
    268     DumpMemoryStatus(out)
    269 
    270 
    271 def WhoCalledMe(up = 3):
    272     try:
    273         trc = traceback2.extract_stack(limit=1, up=up)[0]
    274         fileName = os.path.basename(trc[0])
    275         lineNum = trc[1]
    276         funcName = trc[2]
    277         ret = '%s(%s) in %s' % (fileName, lineNum, funcName)
    278     except:
    279         ret = 'unknown'
    280 
    281     return ret
    282 
    283 
    284 def DumpMemoryStatus(out):
    285     if blue.sysinfo.os.platform == blue.OsPlatform.WINDOWS:
    286         m = blue.win32.GlobalMemoryStatus()
    287         print('GlobalMemoryStatus:', file=out)
    288         for k, v in m.items():
    289             print('%s : %r' % (k, v), file=out)
    290 
    291         print('ProcessMemoryInfo:', file=out)
    292         m = blue.win32.GetProcessMemoryInfo()
    293         for k, v in m.items():
    294             print('%s : %r' % (k, v), file=out)
    295 
    296     print('Python memory usage: %r' % sys.getpymalloced(), file=out)
    297     try:
    298         print('blue WriteStreams: %s, mem use: %s' % (blue.marshal.GetNWriteStreams(), blue.marshal.GetWriteStreamMem()), file=out)
    299     except:
    300         pass
    301 
    302     print('end of memory status', file=out)
    303     out.flush()
    304 
    305 
    306 def _LogThreadLocals(out):
    307     out.write('Thread Locals:')
    308     if hasattr(__builtin__, 'session'):
    309         out.write('  session was ')
    310         out.write(str(session))
    311     else:
    312         out.write('sorry, no session for ya.')
    313     try:
    314         ctk = localstorage.GetLocalStorage().get('calltimer.key', None)
    315     except NameError:
    316         return
    317 
    318     if ctk:
    319         out.write('  calltimer.key was ')
    320         out.write(ctk)
    321     currentcall = localstorage.GetLocalStorage().get('base.currentcall', None)
    322     if currentcall:
    323         try:
    324             currentcall = currentcall()
    325             out.write('  currentcall was: ')
    326             out.write(str(currentcall))
    327         except ReferenceError:
    328             pass
    329 
    330     out.write('\n')
    331 
    332 
    333 def GetMultiplex(channel, mode, toConsole, toLogServer, toMsgWindow, toAlertSvc, stackID):
    334     to = []
    335     if toConsole:
    336         if mode == INFO:
    337             to.append(sys.__stdout__)
    338         else:
    339             to.append(sys.__stderr__)
    340     if toLogServer:
    341         to.append(LogChannelStream(GetChannel(channel), mode))
    342     if toMsgWindow and hasattr(__builtin__, 'session'):
    343         to.append(MsgWindowStream())
    344     if toAlertSvc and hasattr(__builtin__, 'sm') and 'machoNet' in sm.services:
    345         to.append(LogAlertServiceStream(GetChannel(channel), mode, stackID))
    346     return Multiplex(to)
    347 
    348 
    349 class LogAlertServiceStream(object):
    350 
    351     def __init__(self, channel, mode, stackID):
    352         self.channel, self.mode, self.buff, self.stackID = (channel,
    353          mode,
    354          StringIO(),
    355          stackID)
    356 
    357     def write(self, what):
    358         self.buff.write(what.encode('utf-8'))
    359 
    360     def flush(self):
    361         if not self.buff.tell():
    362             return
    363         try:
    364             self.buff.seek(0)
    365             buff = self.buff.read()
    366             sm.GetService('alert').SendStackTraceAlert(self.stackID, buff, {ERR: 'Error',
    367              WARN: 'Warning',
    368              INFO: 'Info'}.get(self.mode, 'Unknown'))
    369         except:
    370             print('Exception in LogAlertServiceStream')
    371 
    372         self.buff = StringIO()
    373 
    374 
    375 class MsgWindowStream(object):
    376     __bad_to_good__ = [('<', '&lt;'),
    377      ('>', '&gt;'),
    378      ('\r', ''),
    379      ('\n', '<br>')]
    380 
    381     def __init__(self):
    382         self.buff = []
    383 
    384     def write(self, what):
    385         for bad, good in self.__bad_to_good__:
    386             what = what.replace(bad, good)
    387 
    388         self.buff.append(what)
    389 
    390     def flush(self):
    391         if not self.buff:
    392             return
    393         try:
    394             if not MsgWindowStreamToMsgWindow():
    395                 return
    396             buff = ''.join(self.buff)
    397             if len(buff) > 10000:
    398                 buff = buff[:10000] + '... [long traceback clipped; more info in the logger]'
    399             import uthread
    400             uthread.new(uiMessageFunc, 'ErrSystemError', {'text': buff})
    401         except:
    402             pass
    403 
    404         self.buff = []
    405 
    406 
    407 class Multiplex(object):
    408 
    409     def __init__(self, streams):
    410         self.streams = streams
    411 
    412     def __del__(self):
    413         self.flush()
    414 
    415     def write(self, what):
    416         for each in self.streams:
    417             each.write(what)
    418 
    419     def flush(self):
    420         for each in self.streams:
    421             try:
    422                 getattr(each, 'flush', lambda : None)()
    423             except IOError as ioe:
    424                 if each in (sys.__stderr__, sys.__stdout__) and ioe[0] == _WIN_EBADF and blue.os.HasStartupArg('noconsole'):
    425                     pass
    426                 else:
    427                     raise
    428 
    429     def close(self):
    430         for each in self.streams:
    431             getattr(each, 'close', lambda : None)()
    432 
    433 
    434 def RegisterPostStackTraceAll(func):
    435     global postStackTraceAll
    436     postStackTraceAll = func
    437 
    438 
    439 def StackTraceAll(reason = '(no reason stated)'):
    440     import stackless, traceback2, os, time
    441     from eveprefs import boot
    442     logsFolder = blue.paths.ResolvePath(u'root:') + 'logs'
    443     if not os.path.exists(logsFolder):
    444         os.mkdir(logsFolder)
    445     y, m, wd, d, h, m, s, ms = blue.os.GetTimeParts(blue.os.GetWallclockTime())
    446     args = (boot.build,
    447      y,
    448      m,
    449      d,
    450      h,
    451      m,
    452      s)
    453     filename = logsFolder + '/#stacktrace b%d %.4d.%.2d.%.2d %.2d.%.2d.%.2d.txt' % args
    454     GetChannel('General').Log('Writing out stacktrace at ' + filename, LGERR)
    455     out = open(filename, 'w')
    456     out.write('Stack trace of all tasklets as requested: %s\n' % reason)
    457     out.write('Node ID: %s\n' % getattr(sm.services['machoNet'], 'nodeID', 'unknown'))
    458     out.write(time.ctime() + '\n\n')
    459     t = stackless.getcurrent()
    460     first = t
    461     no = 1
    462     while t:
    463         out.write('Tasklet #%s -------------------------------------------------' % no + '\n')
    464         no += 1
    465         if str(t.frame).find('cframe') == -1:
    466             traceback2.print_stack(t.frame, file=out)
    467         else:
    468             out.write('%s\n' % t.frame)
    469         out.write('\n')
    470         t = t.next
    471         if t is None or t == first:
    472             break
    473 
    474     if postStackTraceAll:
    475         postStackTraceAll(out)
    476 
    477 
    478 def Quit(reason = '(no reason stated)'):
    479     try:
    480         StackTraceAll(reason)
    481     except:
    482         try:
    483             LogTraceback('Exception in stack-trace-all, shutdown bombing')
    484         except:
    485             pass
    486 
    487     try:
    488         import bluepy
    489         bluepy.Terminate(1, reason)
    490     except ImportError:
    491         sys.exit(1)