WIPP
This commit is contained in:
parent
3a99b7a6bc
commit
00d986376e
8 changed files with 149 additions and 155 deletions
|
|
@ -1,23 +1,20 @@
|
|||
var crypto = require('crypto')
|
||||
var R = require('ramda')
|
||||
var prettyMs = require('pretty-ms')
|
||||
var numeral = require('numeral')
|
||||
var db = null
|
||||
var getBalances = null
|
||||
const crypto = require('crypto')
|
||||
const R = require('ramda')
|
||||
const prettyMs = require('pretty-ms')
|
||||
const numeral = require('numeral')
|
||||
|
||||
var LOW_BALANCE_THRESHOLD = null
|
||||
var STALE_STATE = 2 * 60 * 1000
|
||||
var NETWORK_DOWN_TIME = 60 * 1000
|
||||
const configManager = require('./config-manager')
|
||||
const settingsLoader = require('./settingsLoader')
|
||||
const db = require('./postgresql_interface')
|
||||
|
||||
function init (_db, _getBalances, config) {
|
||||
db = _db
|
||||
const STALE_STATE = 2 * 60 * 1000
|
||||
const NETWORK_DOWN_TIME = 60 * 1000
|
||||
|
||||
let getBalances
|
||||
|
||||
function init (_getBalances) {
|
||||
getBalances = _getBalances
|
||||
|
||||
if (config && config.lowBalanceThreshold) {
|
||||
LOW_BALANCE_THRESHOLD = config.lowBalanceThreshold
|
||||
}
|
||||
}
|
||||
exports.init = init
|
||||
|
||||
function toInt10 (str) { return parseInt(str, 10) }
|
||||
|
||||
|
|
@ -30,7 +27,10 @@ function sameState (a, b) {
|
|||
}
|
||||
|
||||
function checkBalance (rec) {
|
||||
return LOW_BALANCE_THRESHOLD && rec.fiatBalance < LOW_BALANCE_THRESHOLD
|
||||
const settings = settingsLoader.settings
|
||||
const config = configManager.unscoped(settings.config)
|
||||
const lowBalanceThreshold = config.notifications.lowBalanceThreshold
|
||||
return lowBalanceThreshold && rec.fiatBalance < lowBalanceThreshold
|
||||
? {code: 'lowBalance', cryptoCode: rec.cryptoCode, fiatBalance: rec.fiatBalance, fiatCode: rec.fiatCode}
|
||||
: null
|
||||
}
|
||||
|
|
@ -41,14 +41,14 @@ function checkBalances () {
|
|||
}
|
||||
|
||||
function checkPing (deviceEvents) {
|
||||
var sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
|
||||
var lastEvent = R.last(sortedEvents)
|
||||
const sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
|
||||
const lastEvent = R.last(sortedEvents)
|
||||
|
||||
if (!lastEvent) {
|
||||
return [{code: 'ping'}]
|
||||
}
|
||||
|
||||
var age = Math.floor(lastEvent.age)
|
||||
const age = Math.floor(lastEvent.age)
|
||||
if (age > NETWORK_DOWN_TIME) {
|
||||
return [{code: 'ping', age: age}]
|
||||
}
|
||||
|
|
@ -57,22 +57,22 @@ function checkPing (deviceEvents) {
|
|||
}
|
||||
|
||||
function checkStuckScreen (deviceEvents) {
|
||||
var sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
|
||||
var noRepeatEvents = R.dropRepeatsWith(sameState, sortedEvents)
|
||||
var lastEvent = R.last(noRepeatEvents)
|
||||
const sortedEvents = R.sortBy(R.compose(toInt10, R.prop('device_time')), R.map(jsonParse, deviceEvents))
|
||||
const noRepeatEvents = R.dropRepeatsWith(sameState, sortedEvents)
|
||||
const lastEvent = R.last(noRepeatEvents)
|
||||
|
||||
if (!lastEvent) {
|
||||
return []
|
||||
}
|
||||
|
||||
var state = lastEvent.note.state
|
||||
var isIdle = lastEvent.note.isIdle
|
||||
const state = lastEvent.note.state
|
||||
const isIdle = lastEvent.note.isIdle
|
||||
|
||||
if (isIdle) {
|
||||
return []
|
||||
}
|
||||
|
||||
var age = Math.floor(lastEvent.age)
|
||||
const age = Math.floor(lastEvent.age)
|
||||
if (age > STALE_STATE) {
|
||||
return [{code: 'stale', state: state, age: age}]
|
||||
}
|
||||
|
|
@ -86,24 +86,22 @@ function devicesAndEvents () {
|
|||
}
|
||||
|
||||
function checkStatus () {
|
||||
var alerts = {devices: {}, deviceNames: {}}
|
||||
const alerts = {devices: {}, deviceNames: {}}
|
||||
|
||||
return Promise.all([checkBalances(), devicesAndEvents()])
|
||||
.then(([balances, rec]) => {
|
||||
var devices = rec.devices
|
||||
var events = rec.events
|
||||
const devices = rec.devices
|
||||
const events = rec.events
|
||||
|
||||
alerts.general = balances
|
||||
devices.forEach(function (deviceRow) {
|
||||
var deviceId = deviceRow.device_id
|
||||
var deviceName = deviceRow.name || deviceId
|
||||
var deviceEvents = events.filter(function (eventRow) {
|
||||
const deviceId = deviceRow.device_id
|
||||
const deviceName = deviceRow.name || deviceId
|
||||
const deviceEvents = events.filter(function (eventRow) {
|
||||
return eventRow.device_id === deviceId
|
||||
})
|
||||
|
||||
var deviceAlerts = []
|
||||
deviceAlerts = R.concat(deviceAlerts, checkStuckScreen(deviceEvents))
|
||||
deviceAlerts = R.concat(deviceAlerts, checkPing(deviceEvents))
|
||||
const deviceAlerts = checkStuckScreen(deviceEvents).concat(checkPing(deviceEvents))
|
||||
|
||||
alerts.devices[deviceId] = deviceAlerts
|
||||
alerts.deviceNames[deviceId] = deviceName
|
||||
|
|
@ -112,7 +110,6 @@ function checkStatus () {
|
|||
return alerts
|
||||
})
|
||||
}
|
||||
exports.checkStatus = checkStatus
|
||||
|
||||
function formatCurrency (num, code) {
|
||||
return numeral(num).format('0,0.00') + ' ' + code
|
||||
|
|
@ -122,15 +119,15 @@ function emailAlert (alert) {
|
|||
switch (alert.code) {
|
||||
case 'ping':
|
||||
if (alert.age) {
|
||||
var pingAge = prettyMs(alert.age, {compact: true, verbose: true})
|
||||
const pingAge = prettyMs(alert.age, {compact: true, verbose: true})
|
||||
return 'Connection to machine down for ' + pingAge
|
||||
}
|
||||
return 'Machine down for a while or never connected'
|
||||
case 'stale':
|
||||
var stuckAge = prettyMs(alert.age, {compact: true, verbose: true})
|
||||
const stuckAge = prettyMs(alert.age, {compact: true, verbose: true})
|
||||
return 'Machine is stuck on ' + alert.state + 'screen for ' + stuckAge
|
||||
case 'lowBalance':
|
||||
var balance = formatCurrency(alert.fiatBalance, alert.fiatCode)
|
||||
const balance = formatCurrency(alert.fiatBalance, alert.fiatCode)
|
||||
return 'Low balance of ' + balance + ' in ' + alert.cryptoCode + ' wallet'
|
||||
}
|
||||
}
|
||||
|
|
@ -140,7 +137,7 @@ function emailAlerts (alerts) {
|
|||
}
|
||||
|
||||
function printEmailAlerts (alertRec) {
|
||||
var body = 'Errors were reported by your Lamassu Machines.\n'
|
||||
let body = 'Errors were reported by your Lamassu Machines.\n'
|
||||
|
||||
if (alertRec.general.length !== 0) {
|
||||
body = body + '\nGeneral errors:\n'
|
||||
|
|
@ -148,29 +145,34 @@ function printEmailAlerts (alertRec) {
|
|||
}
|
||||
|
||||
R.keys(alertRec.devices).forEach(function (device) {
|
||||
var deviceName = alertRec.deviceNames[device]
|
||||
const deviceName = alertRec.deviceNames[device]
|
||||
body = body + '\nErrors for ' + deviceName + ':\n'
|
||||
body = body + emailAlerts(alertRec.devices[device])
|
||||
})
|
||||
|
||||
return body
|
||||
}
|
||||
exports.printEmailAlerts = printEmailAlerts
|
||||
|
||||
function alertSubject (alertRec) {
|
||||
var alerts = alertRec.general
|
||||
let alerts = alertRec.general
|
||||
R.keys(alertRec.devices).forEach(function (device) {
|
||||
alerts = R.concat(alerts, alertRec.devices[device])
|
||||
})
|
||||
if (alerts.length === 0) return null
|
||||
var alertTypes = R.uniq(R.pluck('code', alerts)).sort()
|
||||
const alertTypes = R.uniq(R.pluck('code', alerts)).sort()
|
||||
return '[Lamassu] Errors reported: ' + alertTypes.join(', ')
|
||||
}
|
||||
exports.alertSubject = alertSubject
|
||||
|
||||
function alertFingerprint (alertRec) {
|
||||
var subject = alertSubject(alertRec)
|
||||
const subject = alertSubject(alertRec)
|
||||
if (!subject) return null
|
||||
return crypto.createHash('sha256').update(subject).digest('hex')
|
||||
}
|
||||
exports.alertFingerprint = alertFingerprint
|
||||
|
||||
module.exports = {
|
||||
init,
|
||||
checkStatus,
|
||||
printEmailAlerts,
|
||||
alertFingerprint,
|
||||
alertSubject
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue