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

counterService.py (12199B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\sys\counterService.py
      2 import types
      3 from collections import defaultdict
      4 import blue
      5 import uthread
      6 import log
      7 from carbon.common.script.sys import service
      8 from carbon.common.script.sys.serviceConst import ROLE_ADMIN, ROLE_PROGRAMMER, ROLE_SERVICE
      9 from carbon.common.script.util.format import GetTimeParts
     10 from stringutil import strx
     11 
     12 def CurrentTimeString():
     13     year, month, weekday, day, hour, minute, second, ms = GetTimeParts(blue.os.GetWallclockTime())
     14     line = '%d/%d/%d %d:%d:%d.%d' % (month,
     15      day,
     16      year,
     17      hour,
     18      minute,
     19      second,
     20      ms)
     21     return line
     22 
     23 
     24 class Counter:
     25 
     26     def __init__(self, name, parent):
     27         self.counter = 0
     28         self.parent = parent
     29         self.name = name
     30         self.filename = ''
     31         import log
     32         self.logChannel = log.GetChannel('Counters.' + self.name)
     33 
     34     def Reset(self):
     35         self.counter = 0
     36 
     37     def Add(self, value = 1):
     38         self.counter += value
     39 
     40     def Dec(self, value = 1):
     41         self.counter -= value
     42 
     43     def Set(self, value):
     44         self.counter = value
     45 
     46     def Value(self):
     47         return self.counter
     48 
     49     def Flush(self):
     50         self.logChannel.Log(strx(self.Value()), log.LGINFO)
     51 
     52 
     53 class TrafficCounter(Counter):
     54 
     55     def __init__(self, name, parent):
     56         Counter.__init__(self, name, parent)
     57         self.Reset()
     58 
     59     def Reset(self):
     60         self.currval = 0
     61         self.total = 0
     62         self.minval = 0
     63         self.maxval = 0
     64         self.lastcur = 0
     65         self.lasttot = 0
     66         self.perfrom = {}
     67         self.perfrom = defaultdict(lambda : 0)
     68         self.lastperfrom = {}
     69         self.lastperfrom = defaultdict(lambda : 0)
     70 
     71     def Add(self, value = 1):
     72         self.currval += value
     73         self.total += 1
     74         if value > self.maxval:
     75             self.maxval = value
     76         if (not self.minval or value < self.minval) and value:
     77             self.minval = value
     78 
     79     def AddFrom(self, nodeID, value = 1):
     80         self.perfrom[nodeID] += value
     81         self.Add(value)
     82 
     83     def Dec(self, value = 1):
     84         raise AttributeError('Dec is cwap on TrafficCounter')
     85 
     86     def Set(self, value):
     87         raise AttributeError('Set is cwap on TrafficCounter')
     88 
     89     def Current(self):
     90         return self.currval
     91 
     92     def Count(self):
     93         return self.total
     94 
     95     def LastFlow(self):
     96         return self.lastcur
     97 
     98     def LastCount(self):
     99         return self.lasttot
    100 
    101     def PerSource(self):
    102         return self.lastperfrom.items()
    103 
    104     def Min(self):
    105         return self.minval
    106 
    107     def Max(self):
    108         return self.maxval
    109 
    110     def Value(self):
    111         if type(self.currval) == types.FloatType:
    112             avg = 0.0
    113             if self.total != 0.0:
    114                 avg = float(self.currval / self.total)
    115             return 'curr=%f, min=%f, max=%f, count=%d, avg=%f' % (self.currval,
    116              self.minval,
    117              self.maxval,
    118              self.total,
    119              avg)
    120         else:
    121             avg = 0
    122             if self.total != 0:
    123                 avg = long(self.currval / self.total)
    124             out = 'curr=%d, min=%d, max=%d, count=%d, avg=%d' % (self.currval,
    125              self.minval,
    126              self.maxval,
    127              self.total,
    128              avg)
    129             for n in self.perfrom:
    130                 out += ', %s from %s' % (self.perfrom[n], n)
    131 
    132             return out
    133 
    134     def Flush(self):
    135         self.logChannel.Log(strx(self.Value()), log.LGINFO)
    136         if self.name == 'dataSent' or self.name == 'dataReceived':
    137             self.lastcur = self.currval
    138             self.lasttot = self.total
    139             self.currval = 0
    140             self.total = 0
    141             self.lastperfrom.clear()
    142             self.lastperfrom = self.perfrom.copy()
    143             self.perfrom.clear()
    144 
    145 
    146 class StatCounter(Counter):
    147 
    148     def __init__(self, name, parent):
    149         Counter.__init__(self, name, parent)
    150         self.Reset()
    151 
    152     def Reset(self):
    153         self.lastval = 0
    154         self.total = 0
    155         self.minval = 0
    156         self.maxval = 0
    157         self.count = 0
    158 
    159     def Add(self, value = 1):
    160         self.lastval = value
    161         self.total += value
    162         self.count += 1
    163         if value > self.maxval:
    164             self.maxval = value
    165         if (not self.minval or value < self.minval) and value:
    166             self.minval = value
    167 
    168     def Dec(self, value = 1):
    169         raise NotImplementedError
    170 
    171     def Set(self, value):
    172         raise NotImplementedError
    173 
    174     def Total(self):
    175         return self.total
    176 
    177     def Count(self):
    178         return self.count
    179 
    180     def Min(self):
    181         return self.minval
    182 
    183     def Max(self):
    184         return self.maxval
    185 
    186     def Avg(self):
    187         avg = 0.0
    188         if self.count > 0:
    189             avg = self.total / float(self.count)
    190         return avg
    191 
    192     def Value(self):
    193         return 'total=%f, last=%f, min=%f, max=%f, count=%f, avg=%f' % (self.total,
    194          self.lastval,
    195          self.minval,
    196          self.maxval,
    197          self.count,
    198          self.Avg())
    199 
    200     def Flush(self):
    201         pass
    202 
    203 
    204 class ListCounter(Counter):
    205 
    206     def __init__(self, name, parent):
    207         Counter.__init__(self, name, parent)
    208         self.counter = []
    209 
    210     def Reset(self):
    211         self.counter = []
    212 
    213     def Add(self, value = 1):
    214         if len(self.counter) == 0:
    215             self.counter.append(value)
    216         else:
    217             self.counter.append(self.counter[-1] + value)
    218 
    219     def Dec(self, value = 1):
    220         if len(self.counter) == 0:
    221             self.counter.append(value)
    222         else:
    223             self.counter.append(self.counter[-1] - value)
    224 
    225     def Flush(self):
    226         Counter.Flush(self)
    227         self.counter = []
    228 
    229     def Set(self, value):
    230         self.counter.append(value)
    231 
    232     def Value(self):
    233         raise RuntimeError('virtual method, must override')
    234 
    235 
    236 class AvgCounter(ListCounter):
    237 
    238     def __init__(self, name, parent):
    239         ListCounter.__init__(self, name, parent)
    240 
    241     def Value(self):
    242         result = 0
    243         if len(self.counter) == 0:
    244             result = 0
    245         else:
    246             for s in self.counter:
    247                 result += s
    248 
    249             result /= len(self.counter)
    250         return result
    251 
    252 
    253 class MaxCounter(ListCounter):
    254 
    255     def __init__(self, name, parent):
    256         ListCounter.__init__(self, name, parent)
    257 
    258     def Value(self):
    259         if len(self.counter) == 0:
    260             return 0
    261         max = self.counter[0]
    262         for s in self.counter:
    263             if s > max:
    264                 max = s
    265 
    266         return max
    267 
    268 
    269 class MinCounter(ListCounter):
    270 
    271     def __init__(self, name, parent):
    272         ListCounter.__init__(self, name, parent)
    273 
    274     def Value(self):
    275         if len(self.counter) == 0:
    276             return 0
    277         min = self.counter[0]
    278         for s in self.counter:
    279             if s < min:
    280                 min = s
    281 
    282         return min
    283 
    284 
    285 class CoreCounterService(service.Service):
    286     __exportedcalls__ = {'CreateCounter': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    287      'DestroyCounter': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    288      'GetCounter': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    289      'SetFlushInterval': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    290      'GetFlushInterval': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    291      'StartLogging': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    292      'StopLogging': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    293      'GetCountersList': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER],
    294      'IsLogging': [ROLE_SERVICE | ROLE_ADMIN | ROLE_PROGRAMMER]}
    295     __guid__ = 'svc.counter'
    296     __configvalues__ = {'countersInterval': 15,
    297      'logStart': 0}
    298 
    299     def Run(self, memStream = None):
    300         self.counters = []
    301         self.timer = None
    302         if self.logStart:
    303             self.StartLogging()
    304 
    305     def GetHtmlStateDetails(self, k, v, detailed):
    306         from carbon.common.script.util import htmlwriter
    307         if k == 'socket':
    308             if detailed:
    309                 hd = []
    310                 li = []
    311                 li.append(['Listen Port', 80])
    312                 return (k, htmlwriter.GetTable(hd, li, useFilter=True))
    313         elif k == 'counters':
    314             if detailed:
    315                 hd = ['Name',
    316                  'Value',
    317                  'Parent',
    318                  'Filename',
    319                  'Log Channel']
    320                 li = []
    321                 for each in self.counters:
    322                     li.append([each.name,
    323                      each.counter,
    324                      each.parent,
    325                      each.filename,
    326                      each.logChannel])
    327 
    328                 return (k, htmlwriter.GetTable(hd, li, useFilter=True))
    329             else:
    330                 v = ''
    331                 comma = ''
    332                 for each in self.counters:
    333                     v = v + comma + each.name + '=' + strx(each.counter)
    334                     comma = ', '
    335 
    336                 return (k, v)
    337         else:
    338             if k == 'countersInterval':
    339                 desc = 'The time in secounds between logging counter values, assuming that counter logging is started in the first place.'
    340                 if self.logStart:
    341                     desc = 'Thus as the service is currently configured, %d seconds will pass between each log operation' % v
    342                 else:
    343                     desc = 'Thus if you would enable counter logging, %d seconds would pass between each log operation as the service is currently configured.' % v
    344                 return ('Counter Interval', desc)
    345             if k == 'logStart':
    346                 desc = 'Whether or not counter logging should be started up when the service is started.  If 0, then logging will not be started, otherwise it will be.  '
    347                 if v:
    348                     desc = desc + 'The counter service is currently configured in such a manner that logging will be started'
    349                 else:
    350                     desc = desc + 'The counter service is currently configured in such a manner that logging will <b>not</b> be started'
    351                 return ('Start Logging?', desc)
    352 
    353     def Stop(self, memStream):
    354         pass
    355 
    356     def Flush(self):
    357         for s in self.counters:
    358             s.Flush()
    359 
    360     def FindCounter(self, name):
    361         for s in self.counters:
    362             if s.name == name:
    363                 return s
    364 
    365     def CreateCounter(self, name, type = 'normal'):
    366         counter = self.FindCounter(name)
    367         if counter:
    368             return counter
    369         if type == 'normal':
    370             counter = Counter(name, self)
    371         elif type == 'traffic':
    372             counter = TrafficCounter(name, self)
    373         elif type == 'statistic':
    374             counter = StatCounter(name, self)
    375         elif type == 'avg':
    376             counter = AvgCounter(name, self)
    377         elif type == 'max':
    378             counter = MaxCounter(name, self)
    379         else:
    380             raise RuntimeError('Countertype %s not supported' % type)
    381         self.counters.append(counter)
    382         return counter
    383 
    384     def AddCounter(self, counter):
    385         self.counters.append(counter)
    386 
    387     def GetCounter(self, name):
    388         for s in self.counters:
    389             if s.name == name:
    390                 return s
    391 
    392     def DestroyCounter(self, name):
    393         found = None
    394         for s in self.counters:
    395             if s.name == name:
    396                 found = s
    397                 break
    398 
    399         if found != None:
    400             self.counters.remove(found)
    401 
    402     def StartLogging(self):
    403         uthread.new(self.StartLogging_thread).context = 'counterService::FlushDaemon'
    404 
    405     def StartLogging_thread(self):
    406         self.logStart = 1
    407         while 1:
    408             blue.pyos.synchro.SleepWallclock(self.countersInterval * 1000)
    409             if not self.logStart:
    410                 return
    411             self.Flush()
    412 
    413     def StopLogging(self):
    414         self.logStart = 0
    415 
    416     def IsLogging(self):
    417         return self.logStart
    418 
    419     def GetFlushInterval(self):
    420         return self.countersInterval
    421 
    422     def SetFlushInterval(self, interval):
    423         self.countersInterval = interval
    424 
    425     def GetCountersList(self):
    426         titleList = []
    427         valueList = []
    428         for s in self.counters:
    429             titleList.append(s.name)
    430             valueList.append(s.Value())
    431 
    432         return (titleList, valueList)