diff --git a/db/knex_migrations/2025-03-04-0000-ping-advanced-options.js b/db/knex_migrations/2025-03-04-0000-ping-advanced-options.js
index 58b86036a..e8bd03e53 100644
--- a/db/knex_migrations/2025-03-04-0000-ping-advanced-options.js
+++ b/db/knex_migrations/2025-03-04-0000-ping-advanced-options.js
@@ -1,7 +1,7 @@
/* SQL:
ALTER TABLE monitor ADD ping_count INTEGER default 1 not null;
ALTER TABLE monitor ADD ping_numeric BOOLEAN default true not null;
-ALTER TABLE monitor ADD ping_deadline INTEGER default 10 not null;
+ALTER TABLE monitor ADD ping_per_request_timeout INTEGER default 2 not null;
*/
exports.up = function (knex) {
// Add new columns to table monitor
@@ -9,7 +9,7 @@ exports.up = function (knex) {
.alterTable("monitor", function (table) {
table.integer("ping_count").defaultTo(1).notNullable();
table.boolean("ping_numeric").defaultTo(true).notNullable();
- table.integer("ping_deadline").defaultTo(10).notNullable();
+ table.integer("ping_per_request_timeout").defaultTo(2).notNullable();
});
};
@@ -19,6 +19,6 @@ exports.down = function (knex) {
.alterTable("monitor", function (table) {
table.dropColumn("ping_count");
table.dropColumn("ping_numeric");
- table.dropColumn("ping_deadline");
+ table.dropColumn("ping_per_request_timeout");
});
};
diff --git a/server/model/monitor.js b/server/model/monitor.js
index bb303cbec..b9cceaa87 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -4,9 +4,9 @@ const { Prometheus } = require("../prometheus");
const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND,
SQL_DATETIME_FORMAT, evaluateJsonQuery,
PING_PACKET_SIZE_MIN, PING_PACKET_SIZE_MAX, PING_PACKET_SIZE_DEFAULT,
- PING_DEADLINE_MIN, PING_DEADLINE_MAX, PING_DEADLINE_DEFAULT,
+ PING_GLOBAL_TIMEOUT_MIN, PING_GLOBAL_TIMEOUT_MAX, PING_GLOBAL_TIMEOUT_DEFAULT,
PING_COUNT_MIN, PING_COUNT_MAX, PING_COUNT_DEFAULT,
- PING_TIMEOUT_MIN, PING_TIMEOUT_MAX, PING_TIMEOUT_DEFAULT
+ PING_PER_REQUEST_TIMEOUT_MIN, PING_PER_REQUEST_TIMEOUT_MAX, PING_PER_REQUEST_TIMEOUT_DEFAULT
} = require("../../src/util");
const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, setSetting, httpNtlm, radius, grpcQuery,
redisPingAsync, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal
@@ -163,7 +163,7 @@ class Monitor extends BeanModel {
// ping advanced options
ping_numeric: this.isPingNumeric(),
ping_count: this.ping_count,
- ping_deadline: this.ping_deadline,
+ ping_per_request_timeout: this.ping_per_request_timeout,
};
if (includeSensitiveData) {
@@ -634,7 +634,7 @@ class Monitor extends BeanModel {
bean.status = UP;
} else if (this.type === "ping") {
- bean.ping = await ping(this.hostname, this.ping_count, "", this.ping_numeric, this.packetSize, this.ping_deadline, this.timeout);
+ bean.ping = await ping(this.hostname, this.ping_count, "", this.ping_numeric, this.packetSize, this.timeout, this.ping_per_request_timeout);
bean.msg = "";
bean.status = UP;
} else if (this.type === "push") { // Type: Push
@@ -706,7 +706,7 @@ class Monitor extends BeanModel {
bean.msg = res.data.response.servers[0].name;
try {
- bean.ping = await ping(this.hostname, PING_COUNT_DEFAULT, "", true, this.packetSize, PING_DEADLINE_DEFAULT, PING_TIMEOUT_DEFAULT);
+ bean.ping = await ping(this.hostname, PING_COUNT_DEFAULT, "", true, this.packetSize, PING_GLOBAL_TIMEOUT_DEFAULT, PING_PER_REQUEST_TIMEOUT_DEFAULT);
} catch (_) { }
} else {
throw new Error("Server not found on Steam");
@@ -1518,14 +1518,14 @@ class Monitor extends BeanModel {
throw new Error(`Interval cannot be less than ${MIN_INTERVAL_SECOND} seconds`);
}
- if (this.packetSize && (this.packetSize < PING_PACKET_SIZE_MIN || this.packetSize > PING_PACKET_SIZE_MAX)) {
- throw new Error(`Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PING_PACKET_SIZE_MAX} (default: ${PING_PACKET_SIZE_DEFAULT})`);
- }
-
if (this.type === "ping") {
// ping parameters validation
- if (this.ping_deadline && (this.ping_deadline < PING_DEADLINE_MIN || this.ping_deadline > PING_DEADLINE_MAX)) {
- throw new Error(`Deadline must be between ${PING_DEADLINE_MIN} and ${PING_DEADLINE_MAX} seconds (default: ${PING_DEADLINE_DEFAULT})`);
+ if (this.packetSize && (this.packetSize < PING_PACKET_SIZE_MIN || this.packetSize > PING_PACKET_SIZE_MAX)) {
+ throw new Error(`Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PING_PACKET_SIZE_MAX} (default: ${PING_PACKET_SIZE_DEFAULT})`);
+ }
+
+ if (this.ping_per_request_timeout && (this.ping_per_request_timeout < PING_PER_REQUEST_TIMEOUT_MIN || this.ping_per_request_timeout > PING_PER_REQUEST_TIMEOUT_MAX)) {
+ throw new Error(`Per-ping timeout must be between ${PING_PER_REQUEST_TIMEOUT_MIN} and ${PING_PER_REQUEST_TIMEOUT_MAX} seconds (default: ${PING_PER_REQUEST_TIMEOUT_DEFAULT})`);
}
if (this.ping_count && (this.ping_count < PING_COUNT_MIN || this.ping_count > PING_COUNT_MAX)) {
@@ -1533,13 +1533,13 @@ class Monitor extends BeanModel {
}
if (this.timeout) {
- const pingTimeout = Math.round(Number(this.timeout));
+ const pingGlobalTimeout = Math.round(Number(this.timeout));
- if (pingTimeout < PING_TIMEOUT_MIN || pingTimeout > PING_TIMEOUT_MAX) {
- throw new Error(`Timeout must be between ${PING_TIMEOUT_MIN} and ${PING_TIMEOUT_MAX} seconds (default: ${PING_TIMEOUT_DEFAULT})`);
+ if (pingGlobalTimeout < this.ping_per_request_timeout || pingGlobalTimeout < PING_GLOBAL_TIMEOUT_MIN || pingGlobalTimeout > PING_GLOBAL_TIMEOUT_MAX) {
+ throw new Error(`Timeout must be between ${PING_GLOBAL_TIMEOUT_MIN} and ${PING_GLOBAL_TIMEOUT_MAX} seconds (default: ${PING_GLOBAL_TIMEOUT_DEFAULT})`);
}
- this.timeout = pingTimeout;
+ this.timeout = pingGlobalTimeout;
}
}
}
diff --git a/server/server.js b/server/server.js
index 41a730b68..e1a877fa9 100644
--- a/server/server.js
+++ b/server/server.js
@@ -878,7 +878,7 @@ let needSetup = false;
// ping advanced options
bean.ping_numeric = monitor.ping_numeric;
bean.ping_count = monitor.ping_count;
- bean.ping_deadline = monitor.ping_deadline;
+ bean.ping_per_request_timeout = monitor.ping_per_request_timeout;
bean.validate();
diff --git a/server/util-server.js b/server/util-server.js
index 5efe9116a..08df728ed 100644
--- a/server/util-server.js
+++ b/server/util-server.js
@@ -3,8 +3,8 @@ const ping = require("@louislam/ping");
const { R } = require("redbean-node");
const {
log, genSecret, badgeConstants,
- PING_PACKET_SIZE_DEFAULT, PING_DEADLINE_DEFAULT,
- PING_COUNT_DEFAULT, PING_TIMEOUT_DEFAULT
+ PING_PACKET_SIZE_DEFAULT, PING_GLOBAL_TIMEOUT_DEFAULT,
+ PING_COUNT_DEFAULT, PING_PER_REQUEST_TIMEOUT_DEFAULT
} = require("../src/util");
const passwordHash = require("./password-hash");
const { Resolver } = require("dns");
@@ -137,8 +137,8 @@ exports.ping = async (
sourceAddr = "",
numeric = true,
size = PING_PACKET_SIZE_DEFAULT,
- deadline = PING_DEADLINE_DEFAULT,
- timeout = PING_TIMEOUT_DEFAULT,
+ deadline = PING_GLOBAL_TIMEOUT_DEFAULT,
+ timeout = PING_PER_REQUEST_TIMEOUT_DEFAULT,
) => {
try {
return await exports.pingAsync(destAddr, false, count, sourceAddr, numeric, size, deadline, timeout);
@@ -174,8 +174,8 @@ exports.pingAsync = function (
sourceAddr = "",
numeric = true,
size = PING_PACKET_SIZE_DEFAULT,
- deadline = PING_DEADLINE_DEFAULT,
- timeout = PING_TIMEOUT_DEFAULT,
+ deadline = PING_GLOBAL_TIMEOUT_DEFAULT,
+ timeout = PING_PER_REQUEST_TIMEOUT_DEFAULT,
) {
return new Promise((resolve, reject) => {
ping.promise.probe(destAddr, {
diff --git a/src/lang/en.json b/src/lang/en.json
index ce21769e6..2000d4e99 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -1059,12 +1059,11 @@
"pingCountDescription": "Number of packets to send before stopping",
"pingNumericLabel": "Numeric Output",
"pingNumericDescription": "If checked, IP addresses will be output instead of symbolic hostnames",
- "pingDeadlineLabel": "Max Duration",
- "pingDeadlineDescription": "Total time in seconds before ping stops, regardless of packets sent",
- "pingTimeoutLabel": "Per-Ping Timeout",
- "pingTimeoutDescription": "applies to each individual ping packet sent",
- "pingTimeoutHelp": "This is the maximum waiting time (in seconds) before considering a single ping packet lost",
- "pingIntervalAdjusted": "Interval has been adjusted according to deadline, timeout and packet count",
+ "pingGlobalTimeoutLabel": "Global Timeout",
+ "pingGlobalTimeoutDescription": "Total time in seconds before ping stops, regardless of packets sent",
+ "pingPerRequestTimeoutLabel": "Per-Ping Timeout",
+ "pingPerRequestTimeoutDescription": "This is the maximum waiting time (in seconds) before considering a single ping packet lost",
+ "pingIntervalAdjustedInfo": "Interval adjusted based on packet count, global timeout and per-ping timeout",
"YZJ Webhook URL": "YZJ Webhook URL",
"YZJ Robot Token": "YZJ Robot token",
"Plain Text": "Plain Text",
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue
index 30ce5459b..63225ee6f 100644
--- a/src/pages/EditMonitor.vue
+++ b/src/pages/EditMonitor.vue
@@ -598,11 +598,11 @@
-
{{ $t("pingTimeoutHelp") }}
+
{{ $t("pingGlobalTimeoutDescription") }}
@@ -690,12 +690,12 @@
-
+
@@ -1492,7 +1492,7 @@ message HealthCheckResponse {
}
},
- "monitor.ping_deadline"() {
+ "monitor.ping_per_request_timeout"() {
if (this.monitor.type === "ping") {
this.finishUpdateInterval();
}
@@ -1526,7 +1526,7 @@ message HealthCheckResponse {
// snmp is not expected to be executed via the internet => we can choose a lower default timeout
this.monitor.timeout = 5;
} else if (this.monitor.type === "ping") {
- this.monitor.timeout = 2;
+ this.monitor.timeout = 10;
} else {
this.monitor.timeout = 48;
}
@@ -1647,7 +1647,7 @@ message HealthCheckResponse {
ping_count: 3,
ping_numeric: true,
packetSize: 56,
- ping_deadline: 10,
+ ping_per_request_timeout: 2,
};
if (this.$root.proxyList && !this.monitor.proxyId) {
@@ -1712,7 +1712,7 @@ message HealthCheckResponse {
if (!this.monitor.timeout) {
if (this.monitor.type === "ping") {
// set to default
- this.monitor.timeout = 2;
+ this.monitor.timeout = 10;
} else {
this.monitor.timeout = ~~(this.monitor.interval * 8) / 10;
}
@@ -1934,18 +1934,17 @@ message HealthCheckResponse {
return this.monitor.interval;
}
- // Calculate the maximum theoretical time needed if all ping requests time out
- const theoreticalTotal = this.monitor.ping_count * this.monitor.timeout;
+ // Calculate the maximum theoretical time needed if every ping request times out
+ const theoreticalTotal = this.monitor.ping_count * this.monitor.ping_per_request_timeout;
- // The deadline forces ping to terminate, so the effective limit
+ // The global timeout (aka deadline) forces ping to terminate, so the effective limit
// is the smaller value between deadline and theoreticalTotal
- const effectiveLimit = Math.min(this.monitor.ping_deadline, theoreticalTotal);
+ const effectiveLimit = Math.min(this.monitor.timeout, theoreticalTotal);
// Add a 10% margin to the effective limit to ensure proper handling
const adjustedLimit = Math.ceil(effectiveLimit * 1.1);
- // If the calculated limit is less than the minimum allowed interval,
- // use the minimum interval to ensure stability
+ // If the calculated limit is lower than the minimum allowed interval, use the minimum interval
if (adjustedLimit < this.minInterval) {
return this.minInterval;
}
@@ -1963,7 +1962,7 @@ message HealthCheckResponse {
this.monitor.interval = calculatedPingInterval;
// Notify the user that the interval has been automatically adjusted
- toast.info(this.$t("pingIntervalAdjusted"));
+ toast.info(this.$t("pingIntervalAdjustedInfo"));
}
} else {
// Update timeout if it is greater than the clamp timeout
diff --git a/src/util.js b/src/util.js
index 62ebba01c..f094cdd63 100644
--- a/src/util.js
+++ b/src/util.js
@@ -32,7 +32,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
-exports.CONSOLE_STYLE_FgPink = exports.CONSOLE_STYLE_FgBrown = exports.CONSOLE_STYLE_FgViolet = exports.CONSOLE_STYLE_FgLightBlue = exports.CONSOLE_STYLE_FgLightGreen = exports.CONSOLE_STYLE_FgOrange = exports.CONSOLE_STYLE_FgGray = exports.CONSOLE_STYLE_FgWhite = exports.CONSOLE_STYLE_FgCyan = exports.CONSOLE_STYLE_FgMagenta = exports.CONSOLE_STYLE_FgBlue = exports.CONSOLE_STYLE_FgYellow = exports.CONSOLE_STYLE_FgGreen = exports.CONSOLE_STYLE_FgRed = exports.CONSOLE_STYLE_FgBlack = exports.CONSOLE_STYLE_Hidden = exports.CONSOLE_STYLE_Reverse = exports.CONSOLE_STYLE_Blink = exports.CONSOLE_STYLE_Underscore = exports.CONSOLE_STYLE_Dim = exports.CONSOLE_STYLE_Bright = exports.CONSOLE_STYLE_Reset = exports.PING_TIMEOUT_DEFAULT = exports.PING_TIMEOUT_MAX = exports.PING_TIMEOUT_MIN = exports.PING_COUNT_DEFAULT = exports.PING_COUNT_MAX = exports.PING_COUNT_MIN = exports.PING_DEADLINE_DEFAULT = exports.PING_DEADLINE_MAX = exports.PING_DEADLINE_MIN = exports.PING_PACKET_SIZE_DEFAULT = exports.PING_PACKET_SIZE_MAX = exports.PING_PACKET_SIZE_MIN = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isNode = exports.isDev = void 0;
+exports.CONSOLE_STYLE_FgPink = exports.CONSOLE_STYLE_FgBrown = exports.CONSOLE_STYLE_FgViolet = exports.CONSOLE_STYLE_FgLightBlue = exports.CONSOLE_STYLE_FgLightGreen = exports.CONSOLE_STYLE_FgOrange = exports.CONSOLE_STYLE_FgGray = exports.CONSOLE_STYLE_FgWhite = exports.CONSOLE_STYLE_FgCyan = exports.CONSOLE_STYLE_FgMagenta = exports.CONSOLE_STYLE_FgBlue = exports.CONSOLE_STYLE_FgYellow = exports.CONSOLE_STYLE_FgGreen = exports.CONSOLE_STYLE_FgRed = exports.CONSOLE_STYLE_FgBlack = exports.CONSOLE_STYLE_Hidden = exports.CONSOLE_STYLE_Reverse = exports.CONSOLE_STYLE_Blink = exports.CONSOLE_STYLE_Underscore = exports.CONSOLE_STYLE_Dim = exports.CONSOLE_STYLE_Bright = exports.CONSOLE_STYLE_Reset = exports.PING_PER_REQUEST_TIMEOUT_DEFAULT = exports.PING_PER_REQUEST_TIMEOUT_MAX = exports.PING_PER_REQUEST_TIMEOUT_MIN = exports.PING_COUNT_DEFAULT = exports.PING_COUNT_MAX = exports.PING_COUNT_MIN = exports.PING_GLOBAL_TIMEOUT_DEFAULT = exports.PING_GLOBAL_TIMEOUT_MAX = exports.PING_GLOBAL_TIMEOUT_MIN = exports.PING_PACKET_SIZE_DEFAULT = exports.PING_PACKET_SIZE_MAX = exports.PING_PACKET_SIZE_MIN = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isNode = exports.isDev = void 0;
exports.evaluateJsonQuery = exports.intHash = exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMaintenanceRelativeURL = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.badgeConstants = exports.CONSOLE_STYLE_BgGray = exports.CONSOLE_STYLE_BgWhite = exports.CONSOLE_STYLE_BgCyan = exports.CONSOLE_STYLE_BgMagenta = exports.CONSOLE_STYLE_BgBlue = exports.CONSOLE_STYLE_BgYellow = exports.CONSOLE_STYLE_BgGreen = exports.CONSOLE_STYLE_BgRed = exports.CONSOLE_STYLE_BgBlack = void 0;
const dayjs_1 = __importDefault(require("dayjs"));
const jsonata = __importStar(require("jsonata"));
@@ -55,15 +55,15 @@ exports.MIN_INTERVAL_SECOND = 20;
exports.PING_PACKET_SIZE_MIN = 1;
exports.PING_PACKET_SIZE_MAX = 65500;
exports.PING_PACKET_SIZE_DEFAULT = 56;
-exports.PING_DEADLINE_MIN = 1;
-exports.PING_DEADLINE_MAX = 300;
-exports.PING_DEADLINE_DEFAULT = 10;
+exports.PING_GLOBAL_TIMEOUT_MIN = 1;
+exports.PING_GLOBAL_TIMEOUT_MAX = 300;
+exports.PING_GLOBAL_TIMEOUT_DEFAULT = 10;
exports.PING_COUNT_MIN = 1;
exports.PING_COUNT_MAX = 100;
exports.PING_COUNT_DEFAULT = 1;
-exports.PING_TIMEOUT_MIN = 1;
-exports.PING_TIMEOUT_MAX = 60;
-exports.PING_TIMEOUT_DEFAULT = 2;
+exports.PING_PER_REQUEST_TIMEOUT_MIN = 1;
+exports.PING_PER_REQUEST_TIMEOUT_MAX = 60;
+exports.PING_PER_REQUEST_TIMEOUT_DEFAULT = 2;
exports.CONSOLE_STYLE_Reset = "\x1b[0m";
exports.CONSOLE_STYLE_Bright = "\x1b[1m";
exports.CONSOLE_STYLE_Dim = "\x1b[2m";
diff --git a/src/util.ts b/src/util.ts
index 4d215e94e..277d860f4 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -44,20 +44,20 @@ export const PING_PACKET_SIZE_MIN = 1;
export const PING_PACKET_SIZE_MAX = 65500;
export const PING_PACKET_SIZE_DEFAULT = 56;
-// Deadline limits (in seconds)
-export const PING_DEADLINE_MIN = 1;
-export const PING_DEADLINE_MAX = 300;
-export const PING_DEADLINE_DEFAULT = 10;
+// Global timeout (aka deadline) limits in seconds
+export const PING_GLOBAL_TIMEOUT_MIN = 1;
+export const PING_GLOBAL_TIMEOUT_MAX = 300;
+export const PING_GLOBAL_TIMEOUT_DEFAULT = 10;
// Ping count limits
export const PING_COUNT_MIN = 1;
export const PING_COUNT_MAX = 100;
export const PING_COUNT_DEFAULT = 1;
-// Timeout limits (in seconds)
-export const PING_TIMEOUT_MIN = 1;
-export const PING_TIMEOUT_MAX = 60;
-export const PING_TIMEOUT_DEFAULT = 2;
+// per-request timeout (aka timeout) limits in seconds
+export const PING_PER_REQUEST_TIMEOUT_MIN = 1;
+export const PING_PER_REQUEST_TIMEOUT_MAX = 60;
+export const PING_PER_REQUEST_TIMEOUT_DEFAULT = 2;
// Console colors
// https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color