mirror of https://github.com/louislam/uptime-kuma
removed ping_timeout field in favor of common timeout field
parent
e8207fed97
commit
a769a2d0e0
|
@ -2,7 +2,6 @@
|
|||
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_timeout INTEGER default 2 not null;
|
||||
*/
|
||||
exports.up = function (knex) {
|
||||
// Add new columns to table monitor
|
||||
|
@ -11,7 +10,6 @@ exports.up = function (knex) {
|
|||
table.integer("ping_count").defaultTo(1).notNullable();
|
||||
table.boolean("ping_numeric").defaultTo(true).notNullable();
|
||||
table.integer("ping_deadline").defaultTo(10).notNullable();
|
||||
table.integer("ping_timeout").defaultTo(2).notNullable();
|
||||
});
|
||||
|
||||
};
|
||||
|
@ -22,6 +20,5 @@ exports.down = function (knex) {
|
|||
table.dropColumn("ping_count");
|
||||
table.dropColumn("ping_numeric");
|
||||
table.dropColumn("ping_deadline");
|
||||
table.dropColumn("ping_timeout");
|
||||
});
|
||||
};
|
||||
|
|
|
@ -164,7 +164,6 @@ class Monitor extends BeanModel {
|
|||
ping_numeric: this.isPingNumeric(),
|
||||
ping_count: this.ping_count,
|
||||
ping_deadline: this.ping_deadline,
|
||||
ping_timeout: this.ping_timeout,
|
||||
};
|
||||
|
||||
if (includeSensitiveData) {
|
||||
|
@ -635,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.ping_timeout);
|
||||
bean.ping = await ping(this.hostname, this.ping_count, "", this.ping_numeric, this.packetSize, this.ping_deadline, this.timeout);
|
||||
bean.msg = "";
|
||||
bean.status = UP;
|
||||
} else if (this.type === "push") { // Type: Push
|
||||
|
@ -1523,16 +1522,25 @@ class Monitor extends BeanModel {
|
|||
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_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.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.ping_count && (this.ping_count < PING_COUNT_MIN || this.ping_count > PING_COUNT_MAX)) {
|
||||
throw new Error(`Echo requests count must be between ${PING_COUNT_MIN} and ${PING_COUNT_MAX} (default: ${PING_COUNT_DEFAULT})`);
|
||||
}
|
||||
if (this.ping_count && (this.ping_count < PING_COUNT_MIN || this.ping_count > PING_COUNT_MAX)) {
|
||||
throw new Error(`Echo requests count must be between ${PING_COUNT_MIN} and ${PING_COUNT_MAX} (default: ${PING_COUNT_DEFAULT})`);
|
||||
}
|
||||
|
||||
if (this.ping_timeout && (this.ping_timeout < PING_TIMEOUT_MIN || this.ping_timeout > PING_TIMEOUT_MAX)) {
|
||||
throw new Error(`Timeout must be between ${PING_TIMEOUT_MIN} and ${PING_TIMEOUT_MAX} seconds (default: ${PING_TIMEOUT_DEFAULT})`);
|
||||
if (this.timeout) {
|
||||
const pingTimeout = 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})`);
|
||||
}
|
||||
|
||||
this.timeout = pingTimeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -879,7 +879,6 @@ let needSetup = false;
|
|||
bean.ping_numeric = monitor.ping_numeric;
|
||||
bean.ping_count = monitor.ping_count;
|
||||
bean.ping_deadline = monitor.ping_deadline;
|
||||
bean.ping_timeout = monitor.ping_timeout;
|
||||
|
||||
bean.validate();
|
||||
|
||||
|
|
|
@ -1059,5 +1059,6 @@
|
|||
"pingDeadlineLabel": "Max Duration",
|
||||
"pingDeadlineDescription": "Total time in seconds before ping stops, regardless of packets sent",
|
||||
"pingTimeoutLabel": "Response Timeout",
|
||||
"pingTimeoutDescription": "Maximum time in seconds to wait for each response"
|
||||
"pingTimeoutDescription": "Maximum time in seconds to wait for each response",
|
||||
"pingIntervalAdjusted": "Interval has been adjusted according to deadline, timeout and packet count"
|
||||
}
|
||||
|
|
|
@ -597,8 +597,11 @@
|
|||
|
||||
<!-- Timeout: HTTP / JSON query / Keyword / Ping / RabbitMQ / SNMP only -->
|
||||
<div v-if="monitor.type === 'http' || monitor.type === 'json-query' || monitor.type === 'keyword' || monitor.type === 'ping' || monitor.type === 'rabbitmq' || monitor.type === 'snmp'" class="my-3">
|
||||
<label for="timeout" class="form-label">{{ $t("Request Timeout") }} ({{ $t("timeoutAfter", [ monitor.timeout || clampTimeout(monitor.interval) ]) }})</label>
|
||||
<input id="timeout" v-model="monitor.timeout" type="number" class="form-control" required min="0" step="0.1">
|
||||
<label for="timeout" class="form-label">
|
||||
{{ timeoutLabel }} ({{ monitor.type === 'ping' ? $t("timeoutAfter", [monitor.timeout]) : $t("timeoutAfter", [monitor.timeout || clampTimeout(monitor.interval)]) }})
|
||||
</label>
|
||||
<input id="timeout" v-model="monitor.timeout" type="number" class="form-control" :min="timeoutMin" :max="timeoutMax" :step="timeoutStep" required>
|
||||
<div class="form-text">{{ timeoutDescription }}</div>
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
|
@ -695,15 +698,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Response Timeout -->
|
||||
<div v-if="monitor.type === 'ping'" class="my-3">
|
||||
<label for="ping_timeout" class="form-label">{{ $t("pingTimeoutLabel") }}</label>
|
||||
<input id="ping_timeout" v-model="monitor.ping_timeout" type="number" class="form-control" required min="1" max="60" step="1">
|
||||
<div class="form-text">
|
||||
{{ $t("pingTimeoutDescription") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- HTTP / Keyword only -->
|
||||
<template v-if="monitor.type === 'http' || monitor.type === 'keyword' || monitor.type === 'json-query' || monitor.type === 'grpc-keyword' ">
|
||||
<div class="my-3">
|
||||
|
@ -1200,6 +1194,29 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
timeoutStep() {
|
||||
return this.monitor.type === "ping" ? 1 : 0.1;
|
||||
},
|
||||
|
||||
timeoutMin() {
|
||||
return this.monitor.type === "ping" ? 1 : 0;
|
||||
},
|
||||
|
||||
timeoutMax() {
|
||||
return this.monitor.type === "ping" ? 60 : undefined;
|
||||
},
|
||||
|
||||
timeoutLabel() {
|
||||
return this.monitor.type === "ping" ? this.$t("pingTimeoutLabel") : this.$t("Request Timeout");
|
||||
},
|
||||
|
||||
timeoutDescription() {
|
||||
if (this.monitor.type === "ping") {
|
||||
return this.$t("pingTimeoutDescription");
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
ipRegex() {
|
||||
|
||||
// Allow to test with simple dns server with port (127.0.0.1:5300)
|
||||
|
@ -1458,9 +1475,25 @@ message HealthCheckResponse {
|
|||
},
|
||||
|
||||
"monitor.timeout"(value, oldValue) {
|
||||
// keep timeout within 80% range
|
||||
if (value && value !== oldValue) {
|
||||
this.monitor.timeout = this.clampTimeout(value);
|
||||
if (this.monitor.type === "ping") {
|
||||
this.finishUpdateInterval();
|
||||
} else {
|
||||
// keep timeout within 80% range
|
||||
if (value && value !== oldValue) {
|
||||
this.monitor.timeout = this.clampTimeout(value);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"monitor.ping_count"() {
|
||||
if (this.monitor.type === "ping") {
|
||||
this.finishUpdateInterval();
|
||||
}
|
||||
},
|
||||
|
||||
"monitor.ping_deadline"() {
|
||||
if (this.monitor.type === "ping") {
|
||||
this.finishUpdateInterval();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1489,8 +1522,10 @@ message HealthCheckResponse {
|
|||
// Set a default timeout if the monitor type has changed or if it's a new monitor
|
||||
if (oldType || this.isAdd) {
|
||||
if (this.monitor.type === "snmp") {
|
||||
// snmp is not expected to be executed via the internet => we can choose a lower default timeout
|
||||
// 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;
|
||||
} else {
|
||||
this.monitor.timeout = 48;
|
||||
}
|
||||
|
@ -1612,7 +1647,6 @@ message HealthCheckResponse {
|
|||
ping_numeric: true,
|
||||
packetSize: 56,
|
||||
ping_deadline: 10,
|
||||
ping_timeout: 2,
|
||||
};
|
||||
|
||||
if (this.$root.proxyList && !this.monitor.proxyId) {
|
||||
|
@ -1675,7 +1709,12 @@ message HealthCheckResponse {
|
|||
}
|
||||
// Handling for monitors that are missing/zeroed timeout
|
||||
if (!this.monitor.timeout) {
|
||||
this.monitor.timeout = ~~(this.monitor.interval * 8) / 10;
|
||||
if (this.monitor.type === "ping") {
|
||||
// set to default
|
||||
this.monitor.timeout = 2;
|
||||
} else {
|
||||
this.monitor.timeout = ~~(this.monitor.interval * 8) / 10;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.$root.toastError(res.msg);
|
||||
|
@ -1888,11 +1927,49 @@ message HealthCheckResponse {
|
|||
return Number.isFinite(clamped) ? clamped : maxTimeout;
|
||||
},
|
||||
|
||||
calculatePingInterval() {
|
||||
// If monitor.type is not "ping", simply return the configured interval
|
||||
if (this.monitor.type !== "ping") {
|
||||
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;
|
||||
|
||||
// The 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);
|
||||
|
||||
// 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 (adjustedLimit < this.minInterval) {
|
||||
return this.minInterval;
|
||||
}
|
||||
|
||||
return adjustedLimit;
|
||||
},
|
||||
|
||||
finishUpdateInterval() {
|
||||
// Update timeout if it is greater than the clamp timeout
|
||||
let clampedValue = this.clampTimeout(this.monitor.interval);
|
||||
if (this.monitor.timeout > clampedValue) {
|
||||
this.monitor.timeout = clampedValue;
|
||||
if (this.monitor.type === "ping") {
|
||||
// Calculate the minimum required interval based on ping configuration
|
||||
const calculatedPingInterval = this.calculatePingInterval();
|
||||
|
||||
// If the configured interval is too small, adjust it to the minimum required value
|
||||
if (this.monitor.interval < calculatedPingInterval) {
|
||||
this.monitor.interval = calculatedPingInterval;
|
||||
|
||||
// Notify the user that the interval has been automatically adjusted
|
||||
toast.info(this.$t("pingIntervalAdjusted"));
|
||||
}
|
||||
} else {
|
||||
// Update timeout if it is greater than the clamp timeout
|
||||
let clampedValue = this.clampTimeout(this.monitor.interval);
|
||||
if (this.monitor.timeout > clampedValue) {
|
||||
this.monitor.timeout = clampedValue;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue