machoRunTimeStats.py (5276B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\net\machoRunTimeStats.py 2 import sys 3 import blue 4 import uthread 5 import collections 6 import string 7 from eveprefs import prefs 8 BASE_SAMPLE_RATE = 1000 9 GLOBAL_SAMPLE_PERIODS = 5 10 SAMPLE_RATE = GLOBAL_SAMPLE_PERIODS * BASE_SAMPLE_RATE 11 HISTORY_LENGHT = 2000 12 13 class MachoRunTimeStats: 14 __guid__ = 'macho.MachoRunTimeStats' 15 16 def __init__(self, transportsByID): 17 self.stop = False 18 self.worker = None 19 self.transportsByID = transportsByID 20 self.socketStatsEnabled = prefs.GetValue('socketStatsEnabled', False) 21 22 def Enable(self): 23 self.stop = False 24 self.last = [0, 25 0, 26 0, 27 0, 28 0, 29 0, 30 0, 31 0] 32 self.maxValues = [0, 33 0, 34 0, 35 0, 36 0, 37 0, 38 0, 39 0] 40 self.history = collections.deque(maxlen=HISTORY_LENGHT) 41 self.packetsSendPerSecond = 0 42 self.packetsReceivedPerSecond = 0 43 self.totalPacketsPerSecond = 0 44 self.KBIn = 0 45 self.KBOut = 0 46 self.maxPacketsSendPerSecond = 0 47 self.maxPacketsReceivedPerSecond = 0 48 self.maxTotalPacketsPerSecond = 0 49 self.maxKBIn = 0 50 self.maxKBOut = 0 51 self.lastupdate = blue.os.GetWallclockTime() 52 self.worker = uthread.new(self.Worker, self.transportsByID) 53 54 def Disable(self): 55 self.stop = True 56 if self.worker: 57 self.worker.kill() 58 self.worker = None 59 60 def Worker(self, transportsByID): 61 numSamplePeriods = 0 62 while not self.stop: 63 delta = blue.os.TimeDiffInMs(self.lastupdate, blue.os.GetWallclockTime()) / 1000 64 self.lastupdate = blue.os.GetWallclockTime() 65 if numSamplePeriods % GLOBAL_SAMPLE_PERIODS == 0: 66 values = self.last[:] 67 mn = sm.services['machoNet'] 68 self.last[0] = mn.dataSent.Count() 69 self.last[1] = mn.dataReceived.Count() 70 self.last[2] = mn.dataSent.Current() 71 self.last[3] = mn.dataReceived.Current() 72 if delta != 0: 73 self.packetsSendPerSecond = float(self.last[0] - values[0]) / delta 74 self.packetsReceivedPerSecond = float(self.last[1] - values[1]) / delta 75 self.totalPacketsPerSecond = self.packetsSendPerSecond + self.packetsReceivedPerSecond 76 self.KBIn = float(self.last[2] - values[2]) / delta 77 self.KBOut = float(self.last[3] - values[3]) / delta 78 self.maxPacketsSendPerSecond = max(self.maxPacketsSendPerSecond, self.packetsSendPerSecond) 79 self.maxPacketsReceivedPerSecond = max(self.maxPacketsReceivedPerSecond, self.packetsReceivedPerSecond) 80 self.maxTotalPacketsPerSecond = max(self.maxTotalPacketsPerSecond, self.totalPacketsPerSecond) 81 self.maxKBIn = max(self.maxKBIn, self.KBIn) 82 self.maxKBOut = max(self.maxKBOut, self.KBOut) 83 self.history.append((blue.os.GetWallclockTime(), 84 self.packetsSendPerSecond, 85 self.packetsReceivedPerSecond, 86 self.KBIn, 87 self.KBOut)) 88 numSamplePeriods += 1 89 if self.socketStatsEnabled: 90 for id, machoTransport in transportsByID.iteritems(): 91 try: 92 tsp = machoTransport.transport 93 if tsp is not None: 94 tsp.statsBytesRead.Sample() 95 tsp.statsBytesWritten.Sample() 96 tsp.statsPacketsRead.Sample() 97 tsp.statsPacketsWritten.Sample() 98 except AttributeError: 99 sys.exc_clear() 100 101 blue.pyos.synchro.SleepWallclock(BASE_SAMPLE_RATE) 102 103 104 class EWMA(object): 105 __guid__ = 'macho.EWMA' 106 107 def __init__(self, factors = None, initialAverage = 0.0, reprFormat = '%.2f'): 108 self.factors = factors if factors else [0.1] 109 self.averages = [ float(initialAverage) for n in range(0, len(self.factors)) ] 110 self.runningTotal = 0 111 self.reprFormat = reprFormat 112 113 @classmethod 114 def FromSampleCounts(cls, sampleCounts = None, initialAverage = 0.0): 115 return EWMA([ 2.0 / (cnt + 1) for cnt in (sampleCounts if sampleCounts else [1]) ], initialAverage) 116 117 def AddSample(self, v = 1): 118 self.averages = [ v * f + (1 - f) * avg for f, avg in zip(self.factors, self.averages) ] 119 120 def Add(self, v = 1): 121 if self.runningTotal is not None: 122 self.runningTotal += v 123 else: 124 self.runningTotal = v 125 126 def Sample(self, defaultRunningTotal = 0.0): 127 if self.runningTotal is not None: 128 self.AddSample(self.runningTotal) 129 self.runningTotal = None 130 elif defaultRunningTotal is not None: 131 self.AddSample(defaultRunningTotal) 132 133 def Averages(self): 134 return zip(self.averages, self.factors) 135 136 def __repr__(self): 137 return string.join([ self.reprFormat % avg for avg in self.averages ], ', ')