repeated alarm message suppression

This commit is contained in:
Wolfgang Hottgenroth 2017-09-05 22:52:38 +02:00
parent 7963bb98fe
commit 0c6ebdc76e
6 changed files with 47 additions and 18 deletions

View File

@ -5,6 +5,8 @@
"brokerCa": "/home/wn/server-ca.crt", "brokerCa": "/home/wn/server-ca.crt",
"disableDatabaseAccess": true, "disableDatabaseAccess": true,
"mongoDbUrl": "mongodb://localhost/hottis", "mongoDbUrl": "mongodb://localhost/hottis",
"checkPeriod": 5,
"alarmRepeatPeriod": 15,
"smtpHost": "localhost", "smtpHost": "localhost",
"smtpPort": 25, "smtpPort": 25,
"smtpSender": "dispatcher@hottis.de", "smtpSender": "dispatcher@hottis.de",

6
dist/log.js vendored
View File

@ -30,7 +30,7 @@ function setLevel(value) {
} }
} }
exports.setLevel = setLevel; exports.setLevel = setLevel;
function sendAlarmMail(message) { function sendAlarmMail(subject, message) {
let transport = nodemailer.createTransport({ let transport = nodemailer.createTransport({
host: config.dict.smtpHost, host: config.dict.smtpHost,
port: config.dict.smtpPort, port: config.dict.smtpPort,
@ -42,12 +42,12 @@ function sendAlarmMail(message) {
let mail = { let mail = {
from: config.dict.smtpSender, from: config.dict.smtpSender,
to: config.dict.smtpReceiver, to: config.dict.smtpReceiver,
subject: "Alarm from Dispatcher", subject: subject,
text: message text: message
}; };
transport.sendMail(mail) transport.sendMail(mail)
.then((v) => { .then((v) => {
info(`Alarm mail sent, ${message}, ${v.response}`); info(`Mail sent, ${subject}, ${message}, ${v.response}`);
}) })
.catch((reason) => { .catch((reason) => {
error(`Failure when sending alarm mail: ${message}, ${reason}`); error(`Failure when sending alarm mail: ${message}, ${reason}`);

2
dist/main.js vendored
View File

@ -9,7 +9,7 @@ const MissingEventDetector = require("./missingeventdetector");
log.info("Dispatcher starting"); log.info("Dispatcher starting");
config.readConfig(); config.readConfig();
let dispatcher = new mqtt.MqttDispatcher(config.dict.brokerUrl, config.dict.brokerUser, config.dict.brokerPass, config.dict.brokerCa); let dispatcher = new mqtt.MqttDispatcher(config.dict.brokerUrl, config.dict.brokerUser, config.dict.brokerPass, config.dict.brokerCa);
const ESP_THERM_TOPIC = 'IoT/espThermometer3/#'; const ESP_THERM_TOPIC = 'IoT/espThermometer2/#';
dispatcher.register(ESP_THERM_TOPIC, 'toJson', EspThermToJson.espThermToJson); dispatcher.register(ESP_THERM_TOPIC, 'toJson', EspThermToJson.espThermToJson);
let missingeventdetector = new MissingEventDetector.MissingEventDetector(); let missingeventdetector = new MissingEventDetector.MissingEventDetector();
dispatcher.register(ESP_THERM_TOPIC, 'MissingEventDetector', missingeventdetector); dispatcher.register(ESP_THERM_TOPIC, 'MissingEventDetector', missingeventdetector);

View File

@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const log = require("./log"); const log = require("./log");
const CallChain = require("./callchain"); const CallChain = require("./callchain");
const Processor = require("./processor"); const Processor = require("./processor");
const CHECK_PERIOD = 60; // seconds const config = require("./config");
class ClientEntry { class ClientEntry {
} }
class MissingEventProcessor extends Processor.AProcessor { class MissingEventProcessor extends Processor.AProcessor {
@ -15,11 +15,18 @@ class MissingEventProcessor extends Processor.AProcessor {
let currentTime = new Date().getTime(); let currentTime = new Date().getTime();
let elapsedTime = currentTime - value.lastEvent; let elapsedTime = currentTime - value.lastEvent;
log.info(`MissingEventProcessor: Checking ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`); log.info(`MissingEventProcessor: Checking ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`);
if ((value.avgDelay != 0) && (elapsedTime > (value.avgDelay * 3))) { if (value.alarmState && ((value.lastAlarmMessage + config.dict.alarmRepeatPeriod * 1000) < currentTime)) {
log.sendAlarmMail(`Missing Event Detected: ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`); value.lastAlarmMessage = currentTime;
value.alarmMessageCounter += 1;
log.sendAlarmMail('Repeated Alarm', `Missing Event Detected: ${key}, repeated: ${value.alarmMessageCounter}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`);
}
if ((!value.alarmState) && ((value.avgDelay != 0) && (elapsedTime > (value.avgDelay * 3)))) {
log.sendAlarmMail('Alarm', `Missing Event Detected: ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`);
value.alarmState = true;
value.lastAlarmMessage = currentTime;
} }
}); });
}, CHECK_PERIOD * 1000); }, config.dict.checkPeriod * 1000);
} }
process(message) { process(message) {
let client = message.metadata.client; let client = message.metadata.client;
@ -35,6 +42,11 @@ class MissingEventProcessor extends Processor.AProcessor {
clientEntry.delaySum += clientEntry.delay; clientEntry.delaySum += clientEntry.delay;
clientEntry.avgDelay = clientEntry.delaySum / clientEntry.count; clientEntry.avgDelay = clientEntry.delaySum / clientEntry.count;
} }
if (clientEntry.alarmState) {
log.sendAlarmMail('Release', `Event received again: ${client}`);
clientEntry.alarmMessageCounter = 0;
}
clientEntry.alarmState = false;
this.clientMap.set(client, clientEntry); this.clientMap.set(client, clientEntry);
log.info(`MissingEventProcessor: Entry for ${client} updated`); log.info(`MissingEventProcessor: Entry for ${client} updated`);
} }
@ -46,6 +58,8 @@ class MissingEventProcessor extends Processor.AProcessor {
clientEntry.count = -1; clientEntry.count = -1;
clientEntry.delaySum = 0; clientEntry.delaySum = 0;
clientEntry.avgDelay = 0; clientEntry.avgDelay = 0;
clientEntry.alarmState = false;
clientEntry.alarmMessageCounter = 0;
this.clientMap.set(client, clientEntry); this.clientMap.set(client, clientEntry);
log.info(`MissingEventProcessor: Entry for ${client} inserted`); log.info(`MissingEventProcessor: Entry for ${client} inserted`);
} }

View File

@ -26,7 +26,7 @@ export function setLevel(value: string): void {
} }
} }
export function sendAlarmMail(message : string): void { export function sendAlarmMail(subject : string, message : string): void {
let transport = nodemailer.createTransport({ let transport = nodemailer.createTransport({
host: config.dict.smtpHost, host: config.dict.smtpHost,
port: config.dict.smtpPort, port: config.dict.smtpPort,
@ -39,13 +39,13 @@ export function sendAlarmMail(message : string): void {
let mail : nodemailer.SendMailOptions = { let mail : nodemailer.SendMailOptions = {
from: config.dict.smtpSender, from: config.dict.smtpSender,
to: config.dict.smtpReceiver, to: config.dict.smtpReceiver,
subject: "Alarm from Dispatcher", subject: subject,
text: message text: message
}; };
transport.sendMail(mail) transport.sendMail(mail)
.then((v : nodemailer.SentMessageInfo) => { .then((v : nodemailer.SentMessageInfo) => {
info(`Alarm mail sent, ${message}, ${v.response}`) info(`Mail sent, ${subject}, ${message}, ${v.response}`)
}) })
.catch((reason : any) => { .catch((reason : any) => {
error(`Failure when sending alarm mail: ${message}, ${reason}`) error(`Failure when sending alarm mail: ${message}, ${reason}`)

View File

@ -4,9 +4,6 @@ import * as Processor from './processor'
import * as config from './config' import * as config from './config'
const CHECK_PERIOD : number = 60 // seconds
class ClientEntry { class ClientEntry {
client : string client : string
lastEvent : number lastEvent : number
@ -14,6 +11,9 @@ class ClientEntry {
count : number count : number
delaySum : number delaySum : number
avgDelay : number avgDelay : number
alarmState : boolean
lastAlarmMessage : number
alarmMessageCounter: number
} }
class MissingEventProcessor extends Processor.AProcessor { class MissingEventProcessor extends Processor.AProcessor {
@ -30,12 +30,18 @@ class MissingEventProcessor extends Processor.AProcessor {
let currentTime : number = new Date().getTime() let currentTime : number = new Date().getTime()
let elapsedTime : number = currentTime - value.lastEvent let elapsedTime : number = currentTime - value.lastEvent
log.info(`MissingEventProcessor: Checking ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`) log.info(`MissingEventProcessor: Checking ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`)
if (value.alarmState && ((value.lastAlarmMessage + config.dict.alarmRepeatPeriod * 1000) < currentTime)) {
if ((value.avgDelay != 0) && (elapsedTime > (value.avgDelay * 3))) { value.lastAlarmMessage = currentTime
log.sendAlarmMail(`Missing Event Detected: ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`) value.alarmMessageCounter += 1
log.sendAlarmMail('Repeated Alarm', `Missing Event Detected: ${key}, repeated: ${value.alarmMessageCounter}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`)
}
if ((! value.alarmState) && ((value.avgDelay != 0) && (elapsedTime > (value.avgDelay * 3)))) {
log.sendAlarmMail('Alarm', `Missing Event Detected: ${key}, elapsed: ${elapsedTime / 1000}, avg. delay: ${value.avgDelay / 1000}`)
value.alarmState = true
value.lastAlarmMessage = currentTime
} }
}) })
}, CHECK_PERIOD * 1000) }, config.dict.checkPeriod * 1000)
} }
protected process(message : any) : void { protected process(message : any) : void {
@ -52,6 +58,11 @@ class MissingEventProcessor extends Processor.AProcessor {
clientEntry.delaySum += clientEntry.delay clientEntry.delaySum += clientEntry.delay
clientEntry.avgDelay = clientEntry.delaySum / clientEntry.count clientEntry.avgDelay = clientEntry.delaySum / clientEntry.count
} }
if (clientEntry.alarmState) {
log.sendAlarmMail('Release', `Event received again: ${client}`)
clientEntry.alarmMessageCounter = 0
}
clientEntry.alarmState = false
this.clientMap.set(client, clientEntry) this.clientMap.set(client, clientEntry)
log.info(`MissingEventProcessor: Entry for ${client} updated`) log.info(`MissingEventProcessor: Entry for ${client} updated`)
} else { } else {
@ -62,6 +73,8 @@ class MissingEventProcessor extends Processor.AProcessor {
clientEntry.count = -1 clientEntry.count = -1
clientEntry.delaySum = 0 clientEntry.delaySum = 0
clientEntry.avgDelay = 0 clientEntry.avgDelay = 0
clientEntry.alarmState = false
clientEntry.alarmMessageCounter = 0
this.clientMap.set(client, clientEntry) this.clientMap.set(client, clientEntry)
log.info(`MissingEventProcessor: Entry for ${client} inserted`) log.info(`MissingEventProcessor: Entry for ${client} inserted`)
} }