Skip to content

Instantly share code, notes, and snippets.

@benkitzelman
Last active August 15, 2018 12:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save benkitzelman/a74fea2efe011c940616ae276b36c58f to your computer and use it in GitHub Desktop.
Save benkitzelman/a74fea2efe011c940616ae276b36c58f to your computer and use it in GitHub Desktop.
Telstra honesty report - monitor connection drops
<?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>
# 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
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