147
147
# Defines the time percentage increase at which the SMI call is considered to
148
148
# be long-running
149
149
OUTLIER_THRESHOLD = 10
150
+ OUTLIER_STD_DEV = 2
150
151
151
152
# Scan mode delay before SMI calls
152
153
SCAN_MODE_DELAY = 0.01
@@ -205,6 +206,12 @@ def __init__(self):
205
206
self .outliers_hist = 0
206
207
self .records = {'deltas' : [], 'times' : []}
207
208
self .msr_count = self .get_msr_count ()
209
+ self .stdev = 0
210
+ self .stdev_hist = 0
211
+ self .m2 = 0
212
+ self .m2_hist = 0
213
+ self .difference = 0
214
+ self .difference_hist = 0
208
215
209
216
def get_msr_count (self ):
210
217
cpu = 0
@@ -252,6 +259,7 @@ def add(self, duration, time, code, data, gprs, confirmed=False):
252
259
self .records ['times' ].append (time )
253
260
self .acc_smi_duration += duration
254
261
self .acc_smi_num += 1
262
+ self .update_stdev (duration )
255
263
if not outlier :
256
264
if duration > self .max .duration :
257
265
self .max .update (duration , code , data , gprs .copy ())
@@ -272,19 +280,30 @@ def avg(self):
272
280
self .acc_smi_duration = 0
273
281
self .acc_smi_num = 0
274
282
283
+ def update_stdev (self , value ):
284
+ self .difference = value - self .avg_smi_duration
285
+ self .difference_hist = value - self .hist_smi_duration
286
+ self .avg ()
287
+ self .m2 += self .difference * (value - self .avg_smi_duration )
288
+ self .m2_hist = self .difference_hist * (value - self .hist_smi_duration )
289
+ variance = self .m2 / self .avg_smi_num
290
+ variance_hist = self .m2_hist / self .hist_smi_num
291
+ self .stdev = math .sqrt (variance )
292
+ self .stdev_hist = math .sqrt (variance_hist )
293
+
275
294
def is_slow_outlier (self , value ):
276
295
ret = False
277
- if self . avg_smi_duration and value > self .avg_smi_duration * ( 1 + OUTLIER_THRESHOLD / 100 ) :
296
+ if value > self .avg_smi_duration + OUTLIER_STD_DEV * self . stdev :
278
297
ret = True
279
- if self . hist_smi_duration and value > self .hist_smi_duration * ( 1 + OUTLIER_THRESHOLD / 100 ) :
298
+ if value > self .hist_smi_duration + OUTLIER_STD_DEV * self . stdev_hist :
280
299
ret = True
281
300
return ret
282
301
283
302
def is_fast_outlier (self , value ):
284
303
ret = False
285
- if self . avg_smi_duration and value < self .avg_smi_duration * ( 1 - OUTLIER_THRESHOLD / 100 ) :
304
+ if value < self .avg_smi_duration - OUTLIER_STD_DEV * self . stdev :
286
305
ret = True
287
- if self . hist_smi_duration and value < self .hist_smi_duration * ( 1 - OUTLIER_THRESHOLD / 100 ) :
306
+ if value < self .hist_smi_duration - OUTLIER_STD_DEV * self . stdev_hist :
288
307
ret = True
289
308
return ret
290
309
0 commit comments