Finalized SNMP monitor

This commit is contained in:
Matt Visnovsky 2024-04-30 15:18:25 -06:00
parent 9848ce49f3
commit 704ffd3f4b

View file

@ -1,5 +1,5 @@
const { MonitorType } = require("./monitor-type"); const { MonitorType } = require("./monitor-type");
const { UP, DOWN } = require("../../src/util"); const { UP, DOWN, log } = require("../../src/util");
const snmp = require("net-snmp"); const snmp = require("net-snmp");
class SNMPMonitorType extends MonitorType { class SNMPMonitorType extends MonitorType {
@ -13,18 +13,17 @@ class SNMPMonitorType extends MonitorType {
*/ */
async check(monitor, heartbeat, _server) { async check(monitor, heartbeat, _server) {
console.log("IP Address:", monitor._hostname); log.debug("monitor", `SNMP: Community String: ${monitor.snmpCommunityString}`);
console.log("SNMP Community String:", monitor._snmpCommunityString); log.debug("monitor", `SNMP: OID: ${monitor.snmpOid}`);
console.log("SNMP OID:", monitor._snmpOid); log.debug("monitor", `SNMP: Version: ${monitor.snmpVersion}`);
console.log("SNMP Version:", monitor._snmpVersion); log.debug("monitor", `SNMP: Condition: ${monitor.snmpCondition}`);
console.log("SNMP Condition:", monitor._snmpCondition); log.debug("monitor", `SNMP: Control Value: ${monitor.snmpControlValue}`);
console.log("SNMP Control Value:", monitor._snmpControlValue);
const options = { const options = {
port: monitor._port || 161, port: monitor.port || '161',
retries: 1, retries: monitor.maxretries,
timeout: 1000, timeout: 1000,
version: getKey(snmp.Version, monitor._snmpVersion) || snmp.Version2c, version: getKey(snmp.Version, monitor.snmpVersion) || snmp.Version2c,
}; };
function getKey(obj, value) { function getKey(obj, value) {
@ -34,56 +33,70 @@ class SNMPMonitorType extends MonitorType {
try { try {
const session = snmp.createSession(monitor.hostname, monitor.snmpCommunityString, options); const session = snmp.createSession(monitor.hostname, monitor.snmpCommunityString, options);
// Handle errors during session creation
session.on('error', (error) => {
heartbeat.status = DOWN;
heartbeat.msg = `SNMP: Error creating SNMP session: ${error.message}`;
log.debug("monitor", `SNMP: ${heartbeat.msg}`);
});
const varbinds = await new Promise((resolve, reject) => { const varbinds = await new Promise((resolve, reject) => {
session.get([monitor._snmpOid], (error, varbinds) => { session.get([monitor.snmpOid], (error, varbinds) => {
if (error) { if (error) {
reject(error); reject(error);
} else { } else {
log.debug("monitor", `SNMP: Received varbinds: Type: ${getKey(snmp.ObjectType, varbinds[0].type)}, Value: ${varbinds[0].value}`); // Log the received varbinds for debugging
resolve(varbinds); resolve(varbinds);
} }
}); });
}); });
console.log("Received varbinds:", varbinds); // Log the received varbinds for debugging if (varbinds.length === 0 || getKey(snmp.ObjectType, varbinds[0].type) === 'NoSuchInstance') {
throw new Error(`No varbinds returned from SNMP session (OID: ${monitor.snmpOid})`);
if (varbinds && varbinds.length > 0) { } else {
const value = varbinds[0].value; const value = varbinds[0].value;
const numericValue = parseInt(value); const numericValue = parseInt(value);
const stringValue = value.toString(); const stringValue = value.toString('ascii');
switch (monitor.snmpCondition) { switch (monitor.snmpCondition) {
case '>': case '>':
heartbeat.status = numericValue > monitor._snmpControlValue ? UP : DOWN; heartbeat.status = numericValue > monitor.snmpControlValue ? UP : DOWN;
break; break;
case '>=': case '>=':
heartbeat.status = numericValue >= monitor._snmpControlValue ? UP : DOWN; heartbeat.status = numericValue >= monitor.snmpControlValue ? UP : DOWN;
break; break;
case '<': case '<':
heartbeat.status = numericValue < monitor._snmpControlValue ? UP : DOWN; heartbeat.status = numericValue < monitor.snmpControlValue ? UP : DOWN;
break; break;
case '<=': case '<=':
heartbeat.status = numericValue <= monitor._snmpControlValue ? UP : DOWN; heartbeat.status = numericValue <= monitor.snmpControlValue ? UP : DOWN;
break; break;
case '==': case '==':
heartbeat.status = value === monitor._snmpControlValue ? UP : DOWN; if (!isNaN(value) && !isNaN(monitor.snmpControlValue)) {
// Both values are numeric, parse them as numbers
heartbeat.status = parseFloat(value) === parseFloat(monitor.snmpControlValue) ? UP : DOWN;
} else {
// At least one of the values is not numeric, compare them as strings
heartbeat.status = value.toString() === monitor.snmpControlValue.toString() ? UP : DOWN;
}
break; break;
case 'contains': case 'contains':
heartbeat.status = stringValue.includes(monitor._snmpControlValue) ? UP : DOWN; heartbeat.status = stringValue.includes(monitor.snmpControlValue) ? UP : DOWN;
break; break;
default: default:
heartbeat.status = DOWN; heartbeat.status = DOWN;
heartbeat.msg = `Invalid condition: ${monitor._snmpCondition}`; heartbeat.msg = `Invalid condition: ${monitor.snmpCondition}`;
break;
} }
} else { heartbeat.msg = `SNMP value ` + (heartbeat.status ? `passes` : `does not pass`) + ` comparison: ${value.toString('ascii')} ${monitor.snmpCondition} ${monitor.snmpControlValue}`;
heartbeat.status = DOWN;
heartbeat.msg = 'No varbinds returned from SNMP session';
}
}
session.close(); // Close the session after use session.close(); // Close the session after use
} catch (err) { } catch (err) {
console.error("Error in SNMP check:", err); // Log any errors
heartbeat.status = DOWN; heartbeat.status = DOWN;
heartbeat.msg = `Error: ${err.message}`; heartbeat.msg = `SNMP Error: ${err.message}`;
log.debug("monitor", `SNMP: ${heartbeat.msg}`);
} }
} }