CheckService
This commit is contained in:
1 parent
74f22a3e70
commit
81d6c4651f
7 files changed
+249
-125
No files matched your search
@@ -38,13 +38,14 @@ import {
|
||||
MongoChecksRepository,
|
||||
MongoMonitorStatsRepository,
|
||||
} from "@/repositories/index.js";
|
||||
import type { CheckEntity } from "@/types/domain/index.js";
|
||||
|
||||
export const initServices = async () => {
|
||||
const monitorRepository = new MongoMonitorRepository();
|
||||
const checksRepository = new MongoChecksRepository();
|
||||
const monitorStatsRepository = new MongoMonitorStatsRepository();
|
||||
|
||||
const checkService = new CheckService();
|
||||
const checkService = new CheckService(checksRepository, monitorRepository);
|
||||
const inviteService = new InviteService();
|
||||
const maintenanceService = new MaintenanceService();
|
||||
const monitorStatsService = new MonitorStatsService(
|
||||
|
||||
@@ -2,12 +2,37 @@ import type {
|
||||
AggregateCheck,
|
||||
CheckEntity,
|
||||
Monitor,
|
||||
MonitorStatus,
|
||||
} from "@/types/domain/index.js";
|
||||
import type { LatestChecksByMonitor } from "@/repositories/checks/MongoCheckRepository.js";
|
||||
export interface IChecksRepository {
|
||||
// Create
|
||||
create(checkData: Partial<CheckEntity>): Promise<CheckEntity>;
|
||||
// Single fetch
|
||||
findById(checkId: string, teamId: string): Promise<CheckEntity | null>;
|
||||
// Collection fetch
|
||||
findByTeamIdAndStatus(
|
||||
status: MonitorStatus,
|
||||
teamId: string,
|
||||
startDate: Date,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
): Promise<CheckEntity[]>;
|
||||
findByMonitorIdAndStatus(
|
||||
status: MonitorStatus,
|
||||
teamId: string,
|
||||
monitorId: string,
|
||||
startDate: Date,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
): Promise<CheckEntity[]>;
|
||||
findCountByMonitorId(monitorId: string): Promise<number>;
|
||||
findPageByMonitorId(
|
||||
monitorId: string,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
): Promise<CheckEntity[]>;
|
||||
|
||||
findLatestChecksByMonitorIds(
|
||||
monitorIds: string[]
|
||||
): Promise<LatestChecksByMonitor>;
|
||||
@@ -22,6 +47,7 @@ export interface IChecksRepository {
|
||||
): Promise<AggregateCheck[]>;
|
||||
// Update
|
||||
// Delete
|
||||
deleteManyExcludedByMonitorIds(monitorIds: string[]): Promise<number>;
|
||||
}
|
||||
|
||||
export default IChecksRepository;
|
||||
@@ -1,5 +1,10 @@
|
||||
import type { IChecksRepository } from "@/repositories/index.js";
|
||||
import { CheckEntity, AggregateCheck, Monitor } from "@/types/domain/index.js";
|
||||
import type {
|
||||
CheckEntity,
|
||||
AggregateCheck,
|
||||
Monitor,
|
||||
MonitorStatus,
|
||||
} from "@/types/domain/index.js";
|
||||
import type { ICheck } from "@/db/models/index.js";
|
||||
import { Check } from "@/db/models/index.js";
|
||||
import mongoose from "mongoose";
|
||||
@@ -66,11 +71,11 @@ class MongoCheckRepository implements IChecksRepository {
|
||||
};
|
||||
|
||||
if (doc.cpu || doc.memory || doc.disk || doc.host || doc.net) {
|
||||
if (doc.cpu) agg.cpu = doc.cpu;
|
||||
if (doc.memory) agg.memory = doc.memory;
|
||||
if (Array.isArray(doc.disk)) agg.disk = doc.disk;
|
||||
if (doc.host) agg.host = doc.host;
|
||||
if (Array.isArray(doc.net)) agg.net = doc.net;
|
||||
if (doc.cpu) (agg as any).cpu = doc.cpu;
|
||||
if (doc.memory) (agg as any).memory = doc.memory;
|
||||
if (Array.isArray(doc.disk)) (agg as any).disk = doc.disk;
|
||||
if (doc.host) (agg as any).host = doc.host;
|
||||
if (Array.isArray(doc.net)) (agg as any).net = doc.net;
|
||||
}
|
||||
return agg;
|
||||
};
|
||||
@@ -438,6 +443,111 @@ class MongoCheckRepository implements IChecksRepository {
|
||||
return {};
|
||||
};
|
||||
|
||||
create = async (checkData: Partial<CheckEntity>) => {
|
||||
const check = new Check({ ...checkData });
|
||||
check.metadata.monitorId = new mongoose.Types.ObjectId(checkData.monitorId);
|
||||
check.metadata.teamId = new mongoose.Types.ObjectId(checkData.teamId);
|
||||
check.metadata.type = checkData.type || "http";
|
||||
const inserted = await check.save();
|
||||
return this.toEntity(inserted);
|
||||
};
|
||||
|
||||
findById = async (checkId: string, teamId: string) => {
|
||||
const check = await Check.findOne({
|
||||
_id: new mongoose.Types.ObjectId(checkId),
|
||||
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
|
||||
});
|
||||
|
||||
if (!check) {
|
||||
return null;
|
||||
}
|
||||
return this.toEntity(check);
|
||||
};
|
||||
|
||||
findCountByMonitorId = async (monitorId: string) => {
|
||||
return await Check.countDocuments({
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
});
|
||||
};
|
||||
|
||||
findByTeamIdAndStatus = async (
|
||||
status: MonitorStatus,
|
||||
teamId: string,
|
||||
startDate: Date,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
) => {
|
||||
const pageSizePlusOne = rowsPerPage + 1;
|
||||
|
||||
const checks = await Check.find({
|
||||
status,
|
||||
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
|
||||
createdAt: { $gte: new Date(startDate), $lte: new Date() },
|
||||
})
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(page * rowsPerPage)
|
||||
.limit(pageSizePlusOne)
|
||||
.select({
|
||||
_id: 1,
|
||||
status: 1,
|
||||
httpStatusCode: 1,
|
||||
message: 1,
|
||||
responseTime: 1,
|
||||
createdAt: 1,
|
||||
"metadata.monitorId": 1,
|
||||
"metadata.teamId": 1,
|
||||
"metadata.type": 1,
|
||||
});
|
||||
return checks.map(this.toEntity);
|
||||
};
|
||||
|
||||
findByMonitorIdAndStatus = async (
|
||||
status: MonitorStatus,
|
||||
teamId: string,
|
||||
monitorId: string,
|
||||
startDate: Date,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
) => {
|
||||
const pageSizePlusOne = rowsPerPage + 1;
|
||||
|
||||
const checks = await Check.find({
|
||||
status,
|
||||
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
createdAt: { $gte: startDate, $lte: new Date() },
|
||||
})
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(page * rowsPerPage)
|
||||
.limit(pageSizePlusOne)
|
||||
.select({
|
||||
_id: 1,
|
||||
status: 1,
|
||||
httpStatusCode: 1,
|
||||
message: 1,
|
||||
responseTime: 1,
|
||||
createdAt: 1,
|
||||
"metadata.monitorId": 1,
|
||||
"metadata.teamId": 1,
|
||||
"metadata.type": 1,
|
||||
});
|
||||
return checks.map(this.toEntity);
|
||||
};
|
||||
|
||||
findPageByMonitorId = async (
|
||||
monitorId: string,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
) => {
|
||||
const checks = await Check.find({
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
})
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(page * rowsPerPage)
|
||||
.limit(rowsPerPage);
|
||||
return checks.map(this.toEntity);
|
||||
};
|
||||
|
||||
findLatestChecksByMonitorIds = async (monitorIds: string[]) => {
|
||||
const mongoIds = monitorIds.map((id) => new mongoose.Types.ObjectId(id));
|
||||
const checkMap = await Check.aggregate([
|
||||
@@ -562,7 +672,6 @@ class MongoCheckRepository implements IChecksRepository {
|
||||
.allowDiskUse(true)
|
||||
.hint({ "metadata.monitorId": 1, createdAt: 1 });
|
||||
|
||||
console.log(checks);
|
||||
return checks.map(this.toAggregateCheck);
|
||||
};
|
||||
|
||||
@@ -633,6 +742,15 @@ class MongoCheckRepository implements IChecksRepository {
|
||||
|
||||
return checks.map(this.toAggregateCheck);
|
||||
};
|
||||
|
||||
deleteManyExcludedByMonitorIds = async (monitorIds: string[]) => {
|
||||
const result = await Check.deleteMany({
|
||||
"metadata.monitorId": {
|
||||
$nin: monitorIds.map((id) => new mongoose.Types.ObjectId(id)),
|
||||
},
|
||||
});
|
||||
return result.deletedCount ?? 0;
|
||||
};
|
||||
}
|
||||
|
||||
export default MongoCheckRepository;
|
||||
@@ -1,29 +1,35 @@
|
||||
import { ICheck, Check, Monitor, ISystemInfo } from "@/db/models/index.js";
|
||||
import { ISystemInfo } from "@/types/domain/index.js";
|
||||
import type { IDockerPayload } from "@/services/infrastructure/NetworkService.js";
|
||||
import { MonitorStatus, MonitorType } from "@/types/domain/index.js";
|
||||
import { StatusResponse } from "../infrastructure/NetworkService.js";
|
||||
import { StatusResponse } from "@/services/infrastructure/NetworkService.js";
|
||||
import type {
|
||||
ICapturePayload,
|
||||
ILighthousePayload,
|
||||
} from "../infrastructure/NetworkService.js";
|
||||
import mongoose from "mongoose";
|
||||
} from "@/services/infrastructure/NetworkService.js";
|
||||
import ApiError from "@/utils/ApiError.js";
|
||||
import { getChildLogger } from "@/logger/Logger.js";
|
||||
import { getStartDate } from "@/utils/TimeUtils.js";
|
||||
|
||||
import type { CheckEntity } from "@/types/domain/index.js";
|
||||
import type {
|
||||
IChecksRepository,
|
||||
IMonitorRepository,
|
||||
} from "@/repositories/index.js";
|
||||
|
||||
const SERVICE_NAME = "CheckService";
|
||||
const logger = getChildLogger(SERVICE_NAME);
|
||||
|
||||
export interface ICheckService {
|
||||
createCheck: (checkData: Partial<CheckEntity>) => Promise<CheckEntity>;
|
||||
buildCheck: (
|
||||
statusResponse: StatusResponse,
|
||||
type: MonitorType
|
||||
) => Promise<ICheck>;
|
||||
) => Promise<Partial<CheckEntity>>;
|
||||
getMonitorChecks: (
|
||||
monitorId: string,
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
) => Promise<{ checks: ICheck[]; count: number }>;
|
||||
) => Promise<{ checks: CheckEntity[]; count: number }>;
|
||||
getChecksByStatus: (
|
||||
status: MonitorStatus,
|
||||
teamId: string,
|
||||
@@ -31,17 +37,27 @@ export interface ICheckService {
|
||||
page: number,
|
||||
rowsPerPage: number,
|
||||
range: string
|
||||
) => Promise<{ checks: ICheck[]; hasMore: boolean }>;
|
||||
) => Promise<{ checks: CheckEntity[]; hasMore: boolean }>;
|
||||
|
||||
getCheckById: (checkId: string, teamId: string) => Promise<ICheck | null>;
|
||||
getCheckById: (
|
||||
checkId: string,
|
||||
teamId: string
|
||||
) => Promise<CheckEntity | null>;
|
||||
|
||||
cleanupOrphanedChecks: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
class CheckService implements ICheckService {
|
||||
public SERVICE_NAME: string;
|
||||
constructor() {
|
||||
private checksRepository: IChecksRepository;
|
||||
private monitorRepository: IMonitorRepository;
|
||||
constructor(
|
||||
checksRepository: IChecksRepository,
|
||||
monitorRepository: IMonitorRepository
|
||||
) {
|
||||
this.SERVICE_NAME = SERVICE_NAME;
|
||||
this.checksRepository = checksRepository;
|
||||
this.monitorRepository = monitorRepository;
|
||||
}
|
||||
|
||||
private isCapturePayload = (payload: any): payload is ICapturePayload => {
|
||||
@@ -118,14 +134,10 @@ class CheckService implements ICheckService {
|
||||
};
|
||||
|
||||
private buildBaseCheck = (statusResponse: StatusResponse) => {
|
||||
const monitorId = new mongoose.Types.ObjectId(statusResponse.monitorId);
|
||||
const teamId = new mongoose.Types.ObjectId(statusResponse.teamId);
|
||||
const checkData: Partial<ICheck> = {
|
||||
metadata: {
|
||||
monitorId: monitorId,
|
||||
teamId: teamId,
|
||||
type: statusResponse?.type,
|
||||
},
|
||||
const check: Partial<CheckEntity> = {
|
||||
monitorId: statusResponse.monitorId,
|
||||
teamId: statusResponse.teamId,
|
||||
type: statusResponse?.type,
|
||||
status: statusResponse?.status,
|
||||
httpStatusCode: statusResponse?.code,
|
||||
message: statusResponse?.message,
|
||||
@@ -133,7 +145,6 @@ class CheckService implements ICheckService {
|
||||
timings: statusResponse?.timings,
|
||||
};
|
||||
|
||||
const check: ICheck = new Check(checkData);
|
||||
return check;
|
||||
};
|
||||
|
||||
@@ -194,10 +205,15 @@ class CheckService implements ICheckService {
|
||||
return check;
|
||||
};
|
||||
|
||||
createCheck = async (checkData: Partial<CheckEntity>) => {
|
||||
const check = await this.checksRepository.create(checkData);
|
||||
return check;
|
||||
};
|
||||
|
||||
buildCheck = async (
|
||||
statusResponse: StatusResponse,
|
||||
type: MonitorType
|
||||
): Promise<ICheck> => {
|
||||
): Promise<Partial<CheckEntity>> => {
|
||||
switch (type) {
|
||||
case "infrastructure":
|
||||
return this.buildInfrastructureCheck(
|
||||
@@ -227,11 +243,12 @@ class CheckService implements ICheckService {
|
||||
|
||||
cleanupOrphanedChecks = async () => {
|
||||
try {
|
||||
const monitorIds = await Monitor.find().distinct("_id");
|
||||
const result = await Check.deleteMany({
|
||||
"metadata.monitorId": { $nin: monitorIds },
|
||||
});
|
||||
logger.info(`Deleted ${result.deletedCount} orphaned Checks.`);
|
||||
const monitorIds = (await this.monitorRepository.findAll()).map(
|
||||
(m) => m.id
|
||||
);
|
||||
const deletedCount =
|
||||
await this.checksRepository.deleteManyExcludedByMonitorIds(monitorIds);
|
||||
logger.info(`Deleted ${deletedCount} orphaned Checks.`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error("Error cleaning up orphaned Checks:", error);
|
||||
@@ -244,16 +261,13 @@ class CheckService implements ICheckService {
|
||||
page: number,
|
||||
rowsPerPage: number
|
||||
) => {
|
||||
const count = await Check.countDocuments({
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
});
|
||||
const count = await this.checksRepository.findCountByMonitorId(monitorId);
|
||||
|
||||
const checks = await Check.find({
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
})
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(page * rowsPerPage)
|
||||
.limit(rowsPerPage);
|
||||
const checks = await this.checksRepository.findPageByMonitorId(
|
||||
monitorId,
|
||||
page,
|
||||
rowsPerPage
|
||||
);
|
||||
return { checks, count };
|
||||
};
|
||||
|
||||
@@ -265,89 +279,43 @@ class CheckService implements ICheckService {
|
||||
rowsPerPage: number,
|
||||
range: string
|
||||
) => {
|
||||
let match;
|
||||
const startDate = getStartDate(range);
|
||||
|
||||
let checks: CheckEntity[] = [];
|
||||
if (monitorId) {
|
||||
const authorized = await Monitor.exists({
|
||||
_id: monitorId,
|
||||
teamId,
|
||||
});
|
||||
const authorized = await this.monitorRepository.findById(
|
||||
monitorId,
|
||||
teamId
|
||||
);
|
||||
|
||||
if (!authorized) {
|
||||
throw new ApiError("Not authorized", 403);
|
||||
}
|
||||
|
||||
match = {
|
||||
checks = await this.checksRepository.findByMonitorIdAndStatus(
|
||||
status,
|
||||
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
createdAt: { $gte: startDate, $lte: new Date() },
|
||||
};
|
||||
teamId,
|
||||
monitorId,
|
||||
startDate,
|
||||
page,
|
||||
rowsPerPage
|
||||
);
|
||||
} else {
|
||||
match = {
|
||||
checks = await this.checksRepository.findByTeamIdAndStatus(
|
||||
status,
|
||||
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
|
||||
createdAt: { $gte: startDate, $lte: new Date() },
|
||||
};
|
||||
teamId,
|
||||
startDate,
|
||||
page,
|
||||
rowsPerPage
|
||||
);
|
||||
}
|
||||
|
||||
const pageSizePlusOne = rowsPerPage + 1;
|
||||
const docs = await Check.find(match)
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(page * rowsPerPage)
|
||||
.limit(pageSizePlusOne)
|
||||
.select({
|
||||
_id: 1,
|
||||
status: 1,
|
||||
httpStatusCode: 1,
|
||||
message: 1,
|
||||
responseTime: 1,
|
||||
createdAt: 1,
|
||||
"metadata.monitorId": 1,
|
||||
"metadata.teamId": 1,
|
||||
"metadata.type": 1,
|
||||
});
|
||||
|
||||
const hasMore = docs.length > rowsPerPage;
|
||||
const limited = hasMore ? docs.slice(0, rowsPerPage) : docs;
|
||||
|
||||
const monitorIds = Array.from(
|
||||
new Set(
|
||||
limited
|
||||
.map((d) => d?.metadata?.monitorId)
|
||||
.filter((v): v is mongoose.Types.ObjectId => !!v)
|
||||
.map((v) => v.toString())
|
||||
)
|
||||
);
|
||||
|
||||
let nameById = new Map<string, string>();
|
||||
if (monitorIds.length > 0) {
|
||||
const monitors = await Monitor.find({ _id: { $in: monitorIds } }).select({
|
||||
_id: 1,
|
||||
name: 1,
|
||||
});
|
||||
nameById = new Map(monitors.map((m) => [m._id.toString(), m.name]));
|
||||
}
|
||||
|
||||
const checks = limited.map((doc) => {
|
||||
const asObj = doc.toObject();
|
||||
const idStr = asObj?.metadata?.monitorId?.toString?.() ?? "";
|
||||
const name = idStr ? nameById.get(idStr) : undefined;
|
||||
if (name) {
|
||||
asObj.metadata = asObj.metadata || {};
|
||||
(asObj.metadata as any).monitorId = { name } as any;
|
||||
}
|
||||
return asObj as ICheck;
|
||||
});
|
||||
const hasMore = checks.length > rowsPerPage;
|
||||
|
||||
return { checks, hasMore };
|
||||
};
|
||||
|
||||
getCheckById = async (checkId: string, teamId: string) => {
|
||||
return await Check.findOne({
|
||||
_id: new mongoose.Types.ObjectId(checkId),
|
||||
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
|
||||
});
|
||||
return await this.checksRepository.findById(checkId, teamId);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
Incident,
|
||||
IMonitor,
|
||||
Monitor,
|
||||
ICheck,
|
||||
IUser,
|
||||
} from "@/db/models/index.js";
|
||||
import type { ResolutionType } from "@/db/models/index.js";
|
||||
@@ -11,7 +10,10 @@ 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";
|
||||
import type {
|
||||
Monitor as MonitorEntity,
|
||||
CheckEntity,
|
||||
} from "@/types/domain/index.js";
|
||||
|
||||
type IncidentPopulated = Omit<IIncident, "monitorId" | "resolvedBy"> & {
|
||||
monitorId: IMonitor;
|
||||
@@ -21,11 +23,11 @@ type IncidentPopulated = Omit<IIncident, "monitorId" | "resolvedBy"> & {
|
||||
export interface IIncidentService {
|
||||
handleStatusChange: (
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck
|
||||
lastCheck: CheckEntity
|
||||
) => Promise<IIncident | null>;
|
||||
handleThresholdBreach: (
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck,
|
||||
lastCheck: CheckEntity,
|
||||
evalResult: ThresholdEvaluationResult
|
||||
) => Promise<IIncident | null>;
|
||||
create: (
|
||||
@@ -47,7 +49,7 @@ export interface IIncidentService {
|
||||
teamId: string,
|
||||
incidentId: string,
|
||||
resolutionType: ResolutionType,
|
||||
lastCheck?: ICheck,
|
||||
lastCheck?: CheckEntity,
|
||||
resolvedBy?: string,
|
||||
resolutionNote?: string
|
||||
) => Promise<IIncident | null>;
|
||||
@@ -69,13 +71,13 @@ class IncidentService implements IIncidentService {
|
||||
|
||||
handleStatusChange = async (
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck
|
||||
lastCheck: CheckEntity
|
||||
) => {
|
||||
if (updatedMonitor.status === "down") {
|
||||
const incident = await this.create(
|
||||
new mongoose.Types.ObjectId(updatedMonitor.teamId),
|
||||
new mongoose.Types.ObjectId(updatedMonitor.id),
|
||||
lastCheck._id
|
||||
new mongoose.Types.ObjectId(lastCheck.id)
|
||||
);
|
||||
return incident;
|
||||
} else if (updatedMonitor.status === "up") {
|
||||
@@ -102,7 +104,7 @@ class IncidentService implements IIncidentService {
|
||||
|
||||
handleThresholdBreach = async (
|
||||
updatedMonitor: MonitorEntity,
|
||||
lastCheck: ICheck,
|
||||
lastCheck: CheckEntity,
|
||||
evalResult: ThresholdEvaluationResult
|
||||
) => {
|
||||
const existing = await Incident.findOne({
|
||||
@@ -116,7 +118,7 @@ class IncidentService implements IIncidentService {
|
||||
const incident = await this.create(
|
||||
new mongoose.Types.ObjectId(updatedMonitor.teamId),
|
||||
new mongoose.Types.ObjectId(updatedMonitor.id),
|
||||
lastCheck._id
|
||||
new mongoose.Types.ObjectId(lastCheck.id)
|
||||
);
|
||||
if (evalResult.notes.length) {
|
||||
await Incident.updateOne(
|
||||
@@ -147,7 +149,7 @@ class IncidentService implements IIncidentService {
|
||||
return existing;
|
||||
} else if (existing) {
|
||||
const resolved = await this.resolve(
|
||||
updatedMonitor.teamId.toString(),
|
||||
updatedMonitor.teamId,
|
||||
existing._id.toString(),
|
||||
"auto",
|
||||
lastCheck
|
||||
@@ -227,7 +229,7 @@ class IncidentService implements IIncidentService {
|
||||
teamId: string,
|
||||
incidentId: string,
|
||||
resolutionType: ResolutionType,
|
||||
lastCheck?: ICheck,
|
||||
lastCheck?: CheckEntity,
|
||||
resolvedBy?: string,
|
||||
resolutionNote?: string
|
||||
) => {
|
||||
@@ -237,7 +239,9 @@ class IncidentService implements IIncidentService {
|
||||
$set: {
|
||||
resolved: true,
|
||||
endedAt: new Date(),
|
||||
endCheck: lastCheck ? lastCheck._id : undefined,
|
||||
endCheck: lastCheck
|
||||
? new mongoose.Types.ObjectId(lastCheck.id)
|
||||
: undefined,
|
||||
resolvedBy: resolvedBy ? resolvedBy : undefined,
|
||||
resolutionType,
|
||||
resolutionNote: resolutionNote ? resolutionNote : undefined,
|
||||
|
||||
@@ -69,8 +69,11 @@ class JobGenerator implements IJobGenerator {
|
||||
const status = await this.networkService.requestStatus(monitor);
|
||||
|
||||
// Step 3. Build check
|
||||
const check = await this.checkService.buildCheck(status, monitor.type);
|
||||
await check.save();
|
||||
const checkToInsert = await this.checkService.buildCheck(
|
||||
status,
|
||||
monitor.type
|
||||
);
|
||||
const check = await this.checkService.createCheck(checkToInsert);
|
||||
|
||||
// Step 4. Update monitor's status
|
||||
const [updatedMonitor, statusChanged] =
|
||||
|
||||
@@ -4,7 +4,11 @@ import {
|
||||
IMonitorRepository,
|
||||
IMonitorStatsRepository,
|
||||
} from "@/repositories/index.js";
|
||||
import type { Monitor, MonitorStats } from "@/types/domain/index.js";
|
||||
import type {
|
||||
Monitor,
|
||||
MonitorStats,
|
||||
CheckEntity,
|
||||
} from "@/types/domain/index.js";
|
||||
import ApiError from "@/utils/ApiError.js";
|
||||
|
||||
const emptyMetrics = (): ThresholdEvaluationResult["metrics"] => ({
|
||||
@@ -52,7 +56,7 @@ export interface IStatusService {
|
||||
) => Promise<MonitorStats | null>;
|
||||
evaluateThresholds: (
|
||||
monitor: Monitor,
|
||||
check: ICheck
|
||||
check: CheckEntity
|
||||
) => Promise<ThresholdEvaluationResult>;
|
||||
}
|
||||
|
||||
@@ -211,7 +215,7 @@ class StatusService implements IStatusService {
|
||||
|
||||
evaluateThresholds = async (
|
||||
monitor: Monitor,
|
||||
check: ICheck
|
||||
check: CheckEntity
|
||||
): Promise<ThresholdEvaluationResult> => {
|
||||
try {
|
||||
if (monitor.type !== "infrastructure" || monitor.status !== "up")
|
||||
|
||||
Reference in new issue
Block a user