From cd65488cbd138521d856fa4510e693aa37afff75 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 23 Sep 2026 10:57:49 -0700 Subject: [PATCH] add docker branch to incident service, update providers --- server/src/domain/incidents/incident.service.ts | 9 ++++++++- server/src/domain/notifications/providers/email.ts | 4 ++++ server/src/domain/notifications/providers/pagerduty.ts | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/server/src/domain/incidents/incident.service.ts b/server/src/domain/incidents/incident.service.ts index f8c79cb80..138a3fcac 100644 --- a/server/src/domain/incidents/incident.service.ts +++ b/server/src/domain/incidents/incident.service.ts @@ -1,6 +1,6 @@ const SERVICE_NAME = "incidentService"; import type { Monitor } from "@/domain/monitors/monitor.type.js"; -import type { MonitorStatusResponse } from "@/types/network.js"; +import type { DockerStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import { getDateForRange } from "@/utils/dataUtils.js"; import type { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js"; @@ -12,6 +12,7 @@ import type { MonitorActionDecision } from "@/worker/worker.interface.js"; import type { INotificationMessageBuilder } from "@/domain/notifications/notification.message-builder.js"; import type { ILogger } from "@/utils/logger.js"; import { DateRange } from "@/types/query.js"; +import { describeContainerBreach, findContainerBreaches } from "@/domain/docker/docker-alert.js"; export interface IIncidentService { handleIncident( @@ -110,6 +111,12 @@ export class IncidentService implements IIncidentService { return "Threshold breach detected"; } + if (monitor.type === "docker") { + const containers = (monitorStatusResponse?.payload as DockerStatusPayload | undefined)?.containers ?? []; + const breaches = findContainerBreaches(monitor, containers); + return breaches.length > 0 ? breaches.map(describeContainerBreach).join(", ") : "Container alert"; + } + const breaches = this.notificationMessageBuilder.extractThresholdBreaches(monitor, monitorStatusResponse); if (breaches.length === 0) { diff --git a/server/src/domain/notifications/providers/email.ts b/server/src/domain/notifications/providers/email.ts index 2b5cde245..01bbaa6be 100644 --- a/server/src/domain/notifications/providers/email.ts +++ b/server/src/domain/notifications/providers/email.ts @@ -92,6 +92,10 @@ export class EmailProvider extends NotificationProvider { return `Monitor ${message.monitor.name} threshold exceeded`; case "threshold_resolved": return `Monitor ${message.monitor.name} thresholds resolved`; + case "container_breach": + return `Monitor ${message.monitor.name} container alert`; + case "container_resolved": + return `Monitor ${message.monitor.name} containers recovered`; default: return `Alert: ${message.monitor.name}`; } diff --git a/server/src/domain/notifications/providers/pagerduty.ts b/server/src/domain/notifications/providers/pagerduty.ts index 6cb264c1d..c20fbc85f 100644 --- a/server/src/domain/notifications/providers/pagerduty.ts +++ b/server/src/domain/notifications/providers/pagerduty.ts @@ -75,7 +75,8 @@ export class PagerDutyProvider extends NotificationProvider { private buildPagerDutyPayload(notification: Notification, message: NotificationMessage): AlertPagerDutyPayload { // Map our notification type to PagerDuty event_action - const eventAction = message.type === "monitor_up" || message.type === "threshold_resolved" ? "resolve" : "trigger"; + const eventAction = + message.type === "monitor_up" || message.type === "threshold_resolved" || message.type === "container_resolved" ? "resolve" : "trigger"; // Map severity to PagerDuty severity levels const severityMap: Record = {