diff --git a/server/model/monitor.js b/server/model/monitor.js
index 55ccfd587..85db89222 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -2,7 +2,7 @@ const dayjs = require("dayjs");
const axios = require("axios");
const { Prometheus } = require("../prometheus");
const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND,
- SQL_DATETIME_FORMAT
+ SQL_DATETIME_FORMAT, evaluateJsonQuery
} = require("../../src/util");
const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, setSetting, httpNtlm, radius, grpcQuery,
redisPingAsync, mongodbPing, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal
@@ -17,7 +17,6 @@ const apicache = require("../modules/apicache");
const { UptimeKumaServer } = require("../uptime-kuma-server");
const { DockerHost } = require("../docker");
const Gamedig = require("gamedig");
-const jsonata = require("jsonata");
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const { UptimeCalculator } = require("../uptime-calculator");
@@ -610,15 +609,13 @@ class Monitor extends BeanModel {
}
}
- let expression = jsonata(this.jsonPath);
+ const result = await evaluateJsonQuery(data, this.jsonPath, this.jsonPathOperator, this.expectedValue);
- let result = await expression.evaluate(data);
-
- if (result.toString() === this.expectedValue) {
+ if (result) {
bean.msg += ", expected value is found";
bean.status = UP;
} else {
- throw new Error(bean.msg + ", but value is not equal to expected value, value was: [" + result + "]");
+ throw new Error(`${bean.msg}, but value is not equal to expected value, value was: [${result}]`);
}
}
diff --git a/server/monitor-types/snmp.js b/server/monitor-types/snmp.js
index 2ca81ff71..1cad575d8 100644
--- a/server/monitor-types/snmp.js
+++ b/server/monitor-types/snmp.js
@@ -1,7 +1,6 @@
const { MonitorType } = require("./monitor-type");
-const { UP, DOWN, log } = require("../../src/util");
+const { UP, DOWN, log, evaluateJsonQuery } = require("../../src/util");
const snmp = require("net-snmp");
-const jsonata = require("jsonata");
class SNMPMonitorType extends MonitorType {
name = "snmp";
@@ -45,46 +44,23 @@ class SNMPMonitorType extends MonitorType {
// We restrict querying to one OID per monitor, therefore `varbinds[0]` will always contain the value we're interested in.
const value = varbinds[0].value;
- // Check if inputs are numeric. If not, re-parse as strings. This ensures comparisons are handled correctly.
- const expectedValue = isNaN(monitor.expectedValue) ? monitor.expectedValue.toString() : parseFloat(monitor.expectedValue);
- let snmpResponse = isNaN(value) ? value.toString() : parseFloat(value);
+ const result = await evaluateJsonQuery(value, monitor.jsonPath, monitor.jsonPathOperator, monitor.expectedValue);
- let jsonQueryExpression;
- switch (monitor.jsonPathOperator) {
- case ">":
- case ">=":
- case "<":
- case "<=":
- jsonQueryExpression = `$.value ${monitor.jsonPathOperator} $.control`;
- break;
- case "==":
- jsonQueryExpression = "$string($.value) = $string($.control)";
- break;
- case "contains":
- jsonQueryExpression = "$contains($string($.value), $string($.control))";
- break;
- default:
- throw new Error(`Invalid condition ${monitor.jsonPathOperator}`);
- }
-
- const expression = jsonata(jsonQueryExpression);
- const evaluation = await expression.evaluate({
- value: snmpResponse,
- control: expectedValue
- });
heartbeat.status = result ? UP : DOWN;
- heartbeat.msg = `SNMP value ${result ? "passes" : "does not pass"} comparison: ${snmpValue} ${monitor.snmpCondition} ${snmpControlValue}`;
+ heartbeat.msg = `SNMP value ${result ? "passes" : "does not pass"} `;
+ heartbeat.msg += (monitor.jsonPathOperator === "custom")
+ ? `custom query. Query result: ${result}. Expected Value: ${monitor.expectedValue}.`
+ : `comparison: ${value.toString()} ${monitor.jsonPathOperator} ${monitor.expectedValue}.`;
} catch (err) {
heartbeat.status = DOWN;
- heartbeat.msg = `SNMP Error: ${err.message}`;
+ heartbeat.msg = `Error: ${err.message}`;
} finally {
if (session) {
session.close();
}
}
}
-
}
module.exports = {
diff --git a/src/lang/en.json b/src/lang/en.json
index 184ae3c51..d95c3dd4e 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -59,10 +59,10 @@
"Keyword": "Keyword",
"Invert Keyword": "Invert Keyword",
"Expected Value": "Expected Value",
- "Json Query": "Json Query",
+ "Custom Json Query Expression": "Custom Json Query Expression",
"Friendly Name": "Friendly Name",
"URL": "URL",
- "Hostname": "Hostname",
+ "Hostname or IP Address": "Hostname or IP Address",
"Host URL": "Host URL",
"locally configured mail transfer agent": "locally configured mail transfer agent",
"Either enter the hostname of the server you want to connect to or localhost if you intend to use a locally configured mail transfer agent": "Either enter the hostname of the server you want to connect to or {localhost} if you intend to use a {local_mta}",
@@ -577,7 +577,7 @@
"notificationDescription": "Notifications must be assigned to a monitor to function.",
"keywordDescription": "Search keyword in plain HTML or JSON response. The search is case-sensitive.",
"invertKeywordDescription": "Look for the keyword to be absent rather than present.",
- "jsonQueryDescription": "Do a json Query against the response and check for expected value (Return value will get converted into string for comparison). Check out {0} for the documentation about the query language. A playground can be found {1}.",
+ "jsonQueryDescription": "Use JSON query to parse and extract specific data from the server's JSON response. Compare the evaluated query against the expected value after converting it into a string. Access the response value using $.value and the expected value using $.control. Refer to {0} for detailed documentation on the query language or experiment with queries using the {1}.",
"backupDescription": "You can backup all monitors and notifications into a JSON file.",
"backupDescription2": "Note: history and event data is not included.",
"backupDescription3": "Sensitive data such as notification tokens are included in the export file; please store export securely.",
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue
index fa49d8579..6db318bd7 100644
--- a/src/pages/EditMonitor.vue
+++ b/src/pages/EditMonitor.vue
@@ -171,21 +171,6 @@
-
-