notificaitons
This commit is contained in:
1 parent
3182141d0a
commit
e62e4898b9
8 files changed
+39
-45
No files matched your search
@@ -11,6 +11,7 @@ import mongoose from "mongoose";
|
||||
import { getChildLogger } from "@/logger/Logger.js";
|
||||
import { ThresholdEvaluationResult } from "@/services/infrastructure/StatusService.js";
|
||||
import { getStartDate } from "@/utils/TimeUtils.js";
|
||||
import type { Monitor as MonitorEntity } from "@/types/domain/monitor.js";
|
||||
|
||||
type IncidentPopulated = Omit<IIncident, "monitorId" | "resolvedBy"> & {
|
||||
monitorId: IMonitor;
|
||||
@@ -19,11 +20,11 @@ type IncidentPopulated = Omit<IIncident, "monitorId" | "resolvedBy"> & {
|
||||
|
||||
export interface IIncidentService {
|
||||
handleStatusChange: (
|
||||
updatedMonitor: IMonitor,
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck
|
||||
) => Promise<IIncident | null>;
|
||||
handleThresholdBreach: (
|
||||
updatedMonitor: IMonitor,
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck,
|
||||
evalResult: ThresholdEvaluationResult
|
||||
) => Promise<IIncident | null>;
|
||||
@@ -66,17 +67,20 @@ class IncidentService implements IIncidentService {
|
||||
this.SERVICE_NAME = SERVICE_NAME;
|
||||
}
|
||||
|
||||
handleStatusChange = async (updatedMonitor: IMonitor, lastCheck: ICheck) => {
|
||||
handleStatusChange = async (
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck
|
||||
) => {
|
||||
if (updatedMonitor.status === "down") {
|
||||
const incident = await this.create(
|
||||
updatedMonitor.teamId,
|
||||
updatedMonitor._id,
|
||||
new mongoose.Types.ObjectId(updatedMonitor.teamId),
|
||||
new mongoose.Types.ObjectId(updatedMonitor.id),
|
||||
lastCheck._id
|
||||
);
|
||||
return incident;
|
||||
} else if (updatedMonitor.status === "up") {
|
||||
const incident = await Incident.findOne({
|
||||
monitorId: updatedMonitor._id,
|
||||
monitorId: updatedMonitor.id,
|
||||
teamId: updatedMonitor.teamId,
|
||||
resolved: false,
|
||||
});
|
||||
@@ -97,12 +101,12 @@ class IncidentService implements IIncidentService {
|
||||
};
|
||||
|
||||
handleThresholdBreach = async (
|
||||
updatedMonitor: IMonitor,
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck,
|
||||
evalResult: ThresholdEvaluationResult
|
||||
) => {
|
||||
const existing = await Incident.findOne({
|
||||
monitorId: updatedMonitor._id,
|
||||
monitorId: updatedMonitor.id,
|
||||
teamId: updatedMonitor.teamId,
|
||||
resolved: false,
|
||||
});
|
||||
@@ -110,8 +114,8 @@ class IncidentService implements IIncidentService {
|
||||
if (evalResult.hasBreach) {
|
||||
if (!existing) {
|
||||
const incident = await this.create(
|
||||
updatedMonitor.teamId,
|
||||
updatedMonitor._id,
|
||||
new mongoose.Types.ObjectId(updatedMonitor.teamId),
|
||||
new mongoose.Types.ObjectId(updatedMonitor.id),
|
||||
lastCheck._id
|
||||
);
|
||||
if (evalResult.notes.length) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import SettingsService from "@/services/system/SettingsService.js";
|
||||
import ApiError from "@/utils/ApiError.js";
|
||||
import { getChildLogger } from "@/logger/Logger.js";
|
||||
import type { IEmailTransport } from "./NotificationServices/Email.js";
|
||||
import type { Monitor as MonitorEntity } from "@/types/domain/index.js";
|
||||
|
||||
const SERVICE_NAME = "NotificationService";
|
||||
const logger = getChildLogger(SERVICE_NAME);
|
||||
@@ -28,7 +29,7 @@ export interface ITestResult {
|
||||
}
|
||||
export interface INotificationService {
|
||||
handleNotifications: (
|
||||
monitor: IMonitor,
|
||||
monitor: MonitorEntity,
|
||||
incident: IIncident
|
||||
) => Promise<void>;
|
||||
testNotificationChannels: (
|
||||
@@ -58,7 +59,7 @@ class NotificationService implements INotificationService {
|
||||
this.webhookService = new WebhookService();
|
||||
}
|
||||
|
||||
handleNotifications = async (monitor: IMonitor, incident: IIncident) => {
|
||||
handleNotifications = async (monitor: MonitorEntity, incident: IIncident) => {
|
||||
const notificationIds = monitor.notificationChannels || [];
|
||||
|
||||
if (notificationIds.length === 0) {
|
||||
@@ -88,7 +89,7 @@ class NotificationService implements INotificationService {
|
||||
|
||||
private sendForChannel = async (
|
||||
channel: INotificationChannel,
|
||||
monitor: IMonitor,
|
||||
monitor: MonitorEntity,
|
||||
incident: IIncident
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import {
|
||||
IMonitor,
|
||||
INotificationChannel,
|
||||
IIncident,
|
||||
} from "@/db/models/index.js";
|
||||
import { INotificationChannel, IIncident } from "@/db/models/index.js";
|
||||
import type { Monitor } from "@/types/domain/index.js";
|
||||
import { IAlert, IMessageService } from "./IMessageService.js";
|
||||
import got from "got";
|
||||
import ApiError from "@/utils/ApiError.js";
|
||||
@@ -52,7 +49,7 @@ class DiscordService implements IMessageService {
|
||||
};
|
||||
};
|
||||
|
||||
buildAlert = (monitor: IMonitor, incident: IIncident) => {
|
||||
buildAlert = (monitor: Monitor, incident: IIncident) => {
|
||||
const name = monitor?.name || "Unnamed monitor";
|
||||
const monitorStatus = monitor?.status || "unknown status";
|
||||
const url = monitor?.url || "no URL";
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import {
|
||||
IMonitor,
|
||||
INotificationChannel,
|
||||
IIncident,
|
||||
} from "@/db/models/index.js";
|
||||
import { INotificationChannel, IIncident } from "@/db/models/index.js";
|
||||
import type { Monitor } from "@/types/domain/index.js";
|
||||
|
||||
import { IMessageService, IAlert } from "./IMessageService.js";
|
||||
import nodemailer, { Transporter } from "nodemailer";
|
||||
import { config } from "@/config/index.js";
|
||||
@@ -123,7 +121,7 @@ class EmailService implements IEmailService {
|
||||
}
|
||||
};
|
||||
|
||||
buildAlert = (monitor: IMonitor, incident: IIncident) => {
|
||||
buildAlert = (monitor: Monitor, incident: IIncident) => {
|
||||
const name = monitor?.name || "Unnamed monitor";
|
||||
const monitorStatus = monitor?.status || "unknown status";
|
||||
const url = monitor?.url || "no URL";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
IMonitor,
|
||||
INotificationChannel,
|
||||
IIncident,
|
||||
ResolutionType,
|
||||
} from "@/db/models/index.js";
|
||||
import type { Monitor } from "@/types/domain/index.js";
|
||||
|
||||
export interface IAlert {
|
||||
name: string;
|
||||
@@ -18,7 +18,7 @@ export interface IAlert {
|
||||
alertTime: Date;
|
||||
}
|
||||
export interface IMessageService {
|
||||
buildAlert: (monitor: IMonitor, incident: IIncident) => IAlert;
|
||||
buildAlert: (monitor: Monitor, incident: IIncident) => IAlert;
|
||||
sendMessage: (
|
||||
alert: IAlert,
|
||||
channel: INotificationChannel
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import {
|
||||
IMonitor,
|
||||
INotificationChannel,
|
||||
IIncident,
|
||||
} from "@/db/models/index.js";
|
||||
import { INotificationChannel, IIncident } from "@/db/models/index.js";
|
||||
import { IAlert, IMessageService } from "./IMessageService.js";
|
||||
import got from "got";
|
||||
import { Monitor } from "@/types/domain/index.js";
|
||||
|
||||
import { getChildLogger } from "@/logger/Logger.js";
|
||||
const SERVICE_NAME = "SlackService";
|
||||
@@ -113,7 +110,7 @@ class SlackService implements IMessageService {
|
||||
];
|
||||
};
|
||||
|
||||
buildAlert = (monitor: IMonitor, incident: IIncident) => {
|
||||
buildAlert = (monitor: Monitor, incident: IIncident) => {
|
||||
const name = monitor?.name || "Unnamed monitor";
|
||||
const monitorStatus = monitor?.status || "unknown status";
|
||||
const url = monitor?.url || "no URL";
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import {
|
||||
IMonitor,
|
||||
INotificationChannel,
|
||||
IIncident,
|
||||
} from "@/db/models/index.js";
|
||||
import { INotificationChannel, IIncident } from "@/db/models/index.js";
|
||||
import { IAlert, IMessageService } from "./IMessageService.js";
|
||||
import ApiError from "@/utils/ApiError.js";
|
||||
import got from "got";
|
||||
import { getChildLogger } from "@/logger/Logger.js";
|
||||
import type { Monitor } from "@/types/domain/index.js";
|
||||
|
||||
const SERVICE_NAME = "WebhookService";
|
||||
const logger = getChildLogger(SERVICE_NAME);
|
||||
@@ -17,7 +14,7 @@ class WebhookService implements IMessageService {
|
||||
this.SERVICE_NAME = SERVICE_NAME;
|
||||
}
|
||||
|
||||
buildAlert = (monitor: IMonitor, incident: IIncident) => {
|
||||
buildAlert = (monitor: Monitor, incident: IIncident) => {
|
||||
const name = monitor?.name || "Unnamed monitor";
|
||||
const monitorStatus = monitor?.status || "unknown status";
|
||||
const url = monitor?.url || "no URL";
|
||||
|
||||
@@ -49,12 +49,12 @@ export interface IStatusService {
|
||||
) => number;
|
||||
|
||||
updateMonitorStats: (
|
||||
monitor: IMonitor,
|
||||
monitor: MonitorEntity,
|
||||
status: StatusResponse,
|
||||
statusChanged: boolean
|
||||
) => Promise<IMonitorStats | null>;
|
||||
evaluateThresholds: (
|
||||
monitor: IMonitor,
|
||||
monitor: MonitorEntity,
|
||||
check: ICheck
|
||||
) => Promise<ThresholdEvaluationResult>;
|
||||
}
|
||||
@@ -151,14 +151,14 @@ class StatusService implements IStatusService {
|
||||
};
|
||||
|
||||
updateMonitorStats = async (
|
||||
monitor: IMonitor,
|
||||
monitor: MonitorEntity,
|
||||
statusResponse: StatusResponse,
|
||||
statusChanged: boolean
|
||||
) => {
|
||||
let stats = await MonitorStats.findOne({ monitorId: monitor._id });
|
||||
let stats = await MonitorStats.findOne({ monitorId: monitor.id });
|
||||
if (!stats) {
|
||||
stats = await MonitorStats.create({
|
||||
monitorId: monitor._id,
|
||||
monitorId: monitor.id,
|
||||
currentStreakStartedAt: Date.now(),
|
||||
});
|
||||
}
|
||||
@@ -203,7 +203,7 @@ class StatusService implements IStatusService {
|
||||
};
|
||||
|
||||
evaluateThresholds = async (
|
||||
monitor: IMonitor,
|
||||
monitor: MonitorEntity,
|
||||
check: ICheck
|
||||
): Promise<ThresholdEvaluationResult> => {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user