mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-05-20 06:02:33 +02:00
feat: filter which event (UP/DOWN/CERT-EXPIRY) triggers alerts
This commit is contained in:
parent
cd6dc144a7
commit
3e54c3ef8c
6 changed files with 119 additions and 3 deletions
|
@ -0,0 +1,25 @@
|
|||
exports.up = async function (knex) {
|
||||
await knex.schema.alterTable("notification", function (table) {
|
||||
table.text("trigger").notNullable().defaultTo("up,down,certificate");
|
||||
});
|
||||
|
||||
await knex("notification").whereNull("trigger").update({
|
||||
trigger: "up,down,certificate",
|
||||
});
|
||||
|
||||
const notifications = await knex("notification").select("*");
|
||||
for (let n of notifications) {
|
||||
await knex("notification").where("id", n.id).update({
|
||||
config: JSON.stringify({
|
||||
...JSON.parse(n.config),
|
||||
trigger: "up,down,certificate",
|
||||
}),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema.alterTable("notification", function (table) {
|
||||
table.dropColumn("trigger");
|
||||
});
|
||||
};
|
|
@ -1292,6 +1292,7 @@ class Monitor extends BeanModel {
|
|||
|
||||
for (let notification of notificationList) {
|
||||
try {
|
||||
const triggers = notification.trigger.split(",");
|
||||
const heartbeatJSON = bean.toJSON();
|
||||
const monitorData = [{ id: monitor.id,
|
||||
active: monitor.active,
|
||||
|
@ -1308,7 +1309,9 @@ class Monitor extends BeanModel {
|
|||
heartbeatJSON["timezoneOffset"] = UptimeKumaServer.getInstance().getTimezoneOffset();
|
||||
heartbeatJSON["localDateTime"] = dayjs.utc(heartbeatJSON["time"]).tz(heartbeatJSON["timezone"]).format(SQL_DATETIME_FORMAT);
|
||||
|
||||
await Notification.send(JSON.parse(notification.config), msg, monitor.toJSON(preloadData, false), heartbeatJSON);
|
||||
if ((bean.status === UP && triggers.includes("up")) || (bean.status === DOWN && triggers.includes("down"))) {
|
||||
await Notification.send(JSON.parse(notification.config), msg, monitor.toJSON(preloadData, false), heartbeatJSON);
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("monitor", "Cannot send notification to " + notification.name);
|
||||
log.error("monitor", e);
|
||||
|
@ -1400,6 +1403,11 @@ class Monitor extends BeanModel {
|
|||
log.debug("monitor", "Send certificate notification");
|
||||
|
||||
for (let notification of notificationList) {
|
||||
const triggers = notification.trigger.split(",");
|
||||
if (!triggers.includes("certificate")) {
|
||||
log.debug("monitor", "Notification does not trigger on certificate");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
log.debug("monitor", "Sending to " + notification.name);
|
||||
await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] ${certType} certificate ${certCN} will expire in ${daysRemaining} days`);
|
||||
|
|
|
@ -229,6 +229,7 @@ class Notification {
|
|||
bean.user_id = userID;
|
||||
bean.config = JSON.stringify(notification);
|
||||
bean.is_default = notification.isDefault || false;
|
||||
bean.trigger = notification.trigger;
|
||||
await R.store(bean);
|
||||
|
||||
if (notification.applyExisting) {
|
||||
|
|
|
@ -39,6 +39,56 @@
|
|||
{{ $t("enableDefaultNotificationDescription") }}
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<MonitorListFilterDropdown :filter-active="false" style="margin-left: -5px;">
|
||||
<template #status>
|
||||
<span>{{ notification.trigger?.split(',')
|
||||
?.map(tt => $t(String(tt).charAt(0).toUpperCase() + String(tt).slice(1)))
|
||||
?.join(", ") || $t("Default") }}</span>
|
||||
</template>
|
||||
<template #dropdown>
|
||||
<li>
|
||||
<div class="dropdown-item" tabindex="0" @click.stop="updateTriggers('up')">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<span>{{ $t("UpTrigger") }}</span>
|
||||
<span class="ps-3">
|
||||
<span v-if="notification.trigger?.split(',').includes('up')" class="px-1 filter-active">
|
||||
<font-awesome-icon icon="check" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-item" tabindex="0" @click.stop="updateTriggers('down')">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<span>{{ $t("DownTrigger") }}</span>
|
||||
<span class="ps-3">
|
||||
<span v-if="notification.trigger?.split(',').includes('down')" class="px-1 filter-active">
|
||||
<font-awesome-icon icon="check" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-item" tabindex="0" @click.stop="updateTriggers('certificate')">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<span>{{ $t("CertificateTrigger") }}</span>
|
||||
<span class="ps-3">
|
||||
<span v-if="notification.trigger?.split(',').includes('certificate')" class="px-1 filter-active">
|
||||
<font-awesome-icon icon="check" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
</MonitorListFilterDropdown>
|
||||
|
||||
<div class="form-text">
|
||||
{{ $t("NotificationTriggerDescription") }}
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="form-check form-switch">
|
||||
|
@ -75,10 +125,12 @@ import { Modal } from "bootstrap";
|
|||
|
||||
import Confirm from "./Confirm.vue";
|
||||
import NotificationFormList from "./notifications";
|
||||
import MonitorListFilterDropdown from "./MonitorListFilterDropdown.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Confirm,
|
||||
MonitorListFilterDropdown,
|
||||
},
|
||||
props: {},
|
||||
emits: [ "added" ],
|
||||
|
@ -275,6 +327,7 @@ export default {
|
|||
name: "",
|
||||
type: "telegram",
|
||||
isDefault: false,
|
||||
trigger: "up,down,certificate",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -287,6 +340,9 @@ export default {
|
|||
*/
|
||||
submit() {
|
||||
this.processing = true;
|
||||
if (!this.notification.trigger) {
|
||||
this.notification.trigger = "up,down,certificate";
|
||||
}
|
||||
this.$root.getSocket().emit("addNotification", this.notification, this.id, (res) => {
|
||||
this.$root.toastRes(res);
|
||||
this.processing = false;
|
||||
|
@ -361,6 +417,21 @@ export default {
|
|||
console.warn("Modal hide failed:", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateTriggers(trigger) {
|
||||
let triggers;
|
||||
if (!this.notification.trigger) {
|
||||
triggers = [];
|
||||
} else {
|
||||
triggers = this.notification.trigger.split(",");
|
||||
}
|
||||
if (triggers.includes(trigger)) {
|
||||
triggers = triggers.filter(t => t !== trigger);
|
||||
} else {
|
||||
triggers.push(trigger);
|
||||
}
|
||||
this.notification.trigger = triggers.join(",");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1097,5 +1097,11 @@
|
|||
"Phone numbers": "Phone numbers",
|
||||
"Sender name": "Sender name",
|
||||
"smsplanetNeedToApproveName": "Needs to be approved in the client panel",
|
||||
"Disable URL in Notification": "Disable URL in Notification"
|
||||
"Disable URL in Notification": "Disable URL in Notification",
|
||||
"UpTrigger": "Notify on up status",
|
||||
"DownTrigger": "Notify on down status",
|
||||
"Certificate": "Certificate",
|
||||
"CertificateTrigger": "Notify on certificate expiration",
|
||||
"NotificationTriggerDescription": "Customise which alerts trigger this notification provider",
|
||||
"MonitorNotification": "Notification will be sent on {0} status changes"
|
||||
}
|
||||
|
|
|
@ -733,7 +733,12 @@
|
|||
{{ $t("Not available, please setup.") }}
|
||||
</p>
|
||||
|
||||
<div v-for="notification in $root.notificationList" :key="notification.id" class="form-check form-switch my-3">
|
||||
<div
|
||||
v-for="notification in $root.notificationList" :key="notification.id" class="form-check form-switch my-3"
|
||||
:title="`${$t('MonitorNotification', [notification.trigger.split(',')
|
||||
.map(tt => $t(String(tt).charAt(0).toUpperCase() + String(tt).slice(1)))
|
||||
.join(', ')])}`"
|
||||
>
|
||||
<input :id=" 'notification' + notification.id" v-model="monitor.notificationIDList[notification.id]" class="form-check-input" type="checkbox">
|
||||
|
||||
<label class="form-check-label" :for=" 'notification' + notification.id">
|
||||
|
|
Loading…
Add table
Reference in a new issue