Last active
August 15, 2018 12:43
-
-
Save benkitzelman/a74fea2efe011c940616ae276b36c58f to your computer and use it in GitHub Desktop.
Telstra honesty report - monitor connection drops
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Label</key> | |
<string>telstra-monitor</string> | |
<key>KeepAlive</key> | |
<true/> | |
<key>EnvironmentVariables</key> | |
<dict> | |
<key>THRESHOLD</key> | |
<string>20000</string> | |
<key>SUMMARY_LOG</key> | |
<string>/var/log/telstra-monitor-summary.log</string> | |
</dict> | |
<key>ProgramArguments</key> | |
<array> | |
<string>/Users/benkitzelman/.nvm/versions/node/v8.6.0/bin/node</string> | |
<string>/Users/benkitzelman/dev/projects/telstra-monitor/index.js</string> | |
</array> | |
<key>StandardErrorPath</key> | |
<string>/var/log/telstra-monitor.err</string> | |
<key>StandardOutPath</key> | |
<string>/var/log/telstra-monitor.log</string> | |
</dict> | |
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# will signal the telstra-monitor daemon to write the summary of outages so far to the configured file | |
# run this as sudo if querying as a daemon | |
pgrep -lf telstra-monitor | awk '{print $1}' | sudo xargs kill -s HUP && cat /var/log/telstra-monitor-summary.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var spawn = require('child_process').spawn; | |
const ADDR = process.env.PING_HOST || "8.8.8.8" | |
const THRESHOLD_FOR_REPORT_MS = process.env.THRESHOLD || 2000 | |
const SUMMARY_LOG_FILE = process.env.SUMMARY_LOG || `${__dirname}/telstra-summary.log` | |
var serviceStart = new Date | |
var pingCount = 0 | |
var failedPingCount = 0 | |
var downtimeCount = 0 | |
var totalDowntimeMs = 0 | |
var longestOutage = { value: 0, start: '', end: '' } | |
var start; | |
var seconds = (ms) => { | |
return `${ ms / 1000 }s` | |
} | |
var mins = (ms) => { | |
return `${ ms / 1000 / 60 }m` | |
} | |
var hours = (ms) => { | |
return `${ ms / 1000 / 60 / 60 }h` | |
} | |
var durations = (ms) => { | |
return `${ seconds(ms) } (${ mins(ms) } or ${ hours(ms) })` | |
} | |
var log = (msg) => { | |
console.log.apply( console, [ (new Date).toString(), msg ] ) | |
} | |
var logSummary = () => { | |
var pingFailureRate = failedPingCount / pingCount * 100 | |
var averageDowntime = ( totalDowntimeMs / downtimeCount ) || 0 | |
return ` | |
FROM ${ serviceStart.toString() } TO ${ (new Date).toString() }: | |
=========== | |
Total Dropouts: ${ downtimeCount } | |
Ping failure rate: ${ pingFailureRate }% (${ failedPingCount } of ${ pingCount } pings failed) | |
avg downtime: ${ durations( averageDowntime ) } | |
Total downtime: ${ durations( totalDowntimeMs ) } | |
Longest outage: | |
downtime: ${ durations( longestOutage.value ) } | |
started: ${ longestOutage.start } | |
ended: ${ longestOutage.end } | |
=========== | |
` | |
} | |
var writeLogSummary = () => { | |
require('fs').writeFileSync(SUMMARY_LOG_FILE, logSummary()) | |
} | |
log(`Started Connectivity Monitor - logging drops longer than ${ seconds( THRESHOLD_FOR_REPORT_MS ) }\n`) | |
var child = spawn("ping", [ ADDR ]) | |
child.stdout.on('data', (data) => { | |
var now = new Date | |
pingCount++ | |
var str = data.toString() | |
if( new RegExp(`.*from ${ ADDR.replace(/\./, '\.') }.+time=`).test( str ) ) { | |
var downtime = now - (start || now) | |
if(downtime >= THRESHOLD_FOR_REPORT_MS ) { | |
if(downtime > longestOutage.value) { | |
longestOutage.value = downtime | |
longestOutage.start = start | |
longestOutage.end = now | |
} | |
totalDowntimeMs += downtime | |
log(`Reconnected. Outage lasted ${ seconds( downtime ) }\n`) | |
start = null | |
} | |
return | |
} | |
failedPingCount++ | |
if(start) return | |
start = new Date(); | |
downtimeCount++ | |
log(`DISCONNECTION STARTED: ${ str.replace(/\n/g, '') }`) | |
}); | |
child.stderr.on('data', (data) => { log(`Error: ${data}`) }); | |
child.on('close', (code) => { log(`Closing ${code}`) }); | |
[ "SIGINT", "SIGTERM" ].forEach( (signal) => { | |
process.on(signal, () => { | |
log( logSummary() ) | |
process.exit() | |
}) | |
}) | |
process.on('SIGHUP', writeLogSummary) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment