-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstats.js
83 lines (67 loc) · 2.53 KB
/
stats.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Built-in modules
// (none)
// 3rd-party dependencies
const { _ } = require('lodash')
const simpleStatistics = require('simple-statistics')
// In-house modules
const { config } = require('./config.js')
const { isBadResponse } = require('./outages.js')
// TODO: better way of managing user configs for stats
let statsConfig = {
rttBinSize: 5 // Number in ms
}
class Stats {
constructor(){
}
static calcSessionStats(instancePinguno){
let session = instancePinguno
let sessionStats = {}
// BUG: doesn't handle negatives properly
let toNearestMultipleOf = (input, factor)=>{
if (typeof input !== 'number' || typeof factor !== 'number'){
throw Error(`toNearestMultipleOf - inputs need to be numbers`)
}
// TODO: properly handle negativity
let inputIsNegative = input < 0
input = Math.abs(input)
let halfFactor = factor / 2
if (input < halfFactor){
return 0
} else if (input >= halfFactor && input < factor){
return factor
} else if (input > factor){
let remainder = input % factor
if (remainder >= halfFactor){
return input - remainder + factor
} else if (remainder < halfFactor){
return input - remainder
}
}
return inputIsNegative ? -input : input
}
for (let target of session.pingTargets){
let thisStatTarget = {}
if (target.pingList.length <= 0){
console.warn(`calcSessionStats - no pings for target ${target.IPV4}`)
thisStatTarget = null
} else {
let sortedPings = _.sortBy(target.pingList, (ping)=> ping.icmpSeq)
let rTTs = sortedPings.map(val => val.roundTripTimeMs)
let successfulRTTs = rTTs.filter(val => val)
let successfulRTTsBinned = successfulRTTs.map(val => toNearestMultipleOf(val, statsConfig.rttBinSize))
let badResponses = sortedPings.filter( val => {
return isBadResponse(val)
})
thisStatTarget.meanGoodRTT = successfulRTTs.length > 0 ? _.mean(successfulRTTs) : null
thisStatTarget.modeGoodRTT = successfulRTTsBinned.length > 0 ? simpleStatistics.mode(successfulRTTsBinned) : null
thisStatTarget.medianGoodRTT = successfulRTTs.length > 0 ? simpleStatistics.median(successfulRTTs) : null
thisStatTarget.maxGoodRTT = successfulRTTs.length > 0 ? successfulRTTs.reduce((a, b) => Math.max(a, b)) : null
thisStatTarget.minGoodRTT = successfulRTTs.length > 0 ? successfulRTTs.reduce((a, b) => Math.min(a, b)) : null
thisStatTarget.uptimeFraction = 1 - (badResponses.length / target.pingList.length)
}
sessionStats[target.IPV4] = thisStatTarget
}
return sessionStats
}
}
exports.Stats = Stats