dedupe hardware stat definitions, fix tests, remove misleading null return types
This commit is contained in:
1 parent
c021d04f53
commit
ed36db172a
43 files changed
+148
-165
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { Monitor, MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { UserRole } from "@/domain/users/user.type.js";
|
||||
import sslChecker, { SSLDetails } from "ssl-checker";
|
||||
type SSLCheckerType = typeof sslChecker;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from "zod";
|
||||
import { booleanCoercion } from "./shared.js";
|
||||
import { GeoContinents } from "@/domain/geo-checks/geo-check.type.js";
|
||||
import { MonitorTypes } from "@/domain/monitors/monitor.types.js";
|
||||
import { MonitorTypes } from "@/domain/monitors/monitor.type.js";
|
||||
import { CheckFilters, DateRanges, SortOrders } from "@/types/query.js";
|
||||
|
||||
//****************************************
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
MonitorStatuses,
|
||||
MonitorTypes,
|
||||
PageSpeedStrategies,
|
||||
} from "@/domain/monitors/monitor.types.js";
|
||||
} from "@/domain/monitors/monitor.type.js";
|
||||
import { DateRanges, SortOrders } from "@/types/query.js";
|
||||
|
||||
const httpStatusCode = z.number().refine((code) => HttpStatusCodeSet.has(code), { message: "Must be a valid HTTP status code" });
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
import { CheckModel } from "@/domain/checks/check.model.js";
|
||||
import mongoose from "mongoose";
|
||||
import type { HardwareDiskStats, HardwareNetStats } from "@/domain/checks/check.type.js";
|
||||
|
||||
type DateRange = { start: Date; end: Date };
|
||||
type HardwareUpChecks = { totalChecks: number };
|
||||
|
||||
// $avg yields null when no values are present, so metrics are nullable until the repository applies fallbacks
|
||||
type NullableValues<T> = { [K in keyof T]: T[K] | null };
|
||||
|
||||
export type HardwareStatsBucket = {
|
||||
_id: string;
|
||||
avgCpuUsage: number | null;
|
||||
avgMemoryUsage: number | null;
|
||||
avgTemperature: number[];
|
||||
disks: NullableValues<HardwareDiskStats>[];
|
||||
net: NullableValues<HardwareNetStats>[];
|
||||
};
|
||||
|
||||
const NET_RATE_FIELDS = [
|
||||
["bytesSentPerSecond", "bytes_sent"],
|
||||
["deltaBytesRecv", "bytes_recv"],
|
||||
@@ -70,13 +83,13 @@ export const getHardwareUpChecks = async (monitorId: string, dates: DateRange):
|
||||
return { totalChecks: count };
|
||||
};
|
||||
|
||||
export const getHardwareStats = async (monitorId: string, dates: DateRange, dateString: string) => {
|
||||
export const getHardwareStats = async (monitorId: string, dates: DateRange, dateString: string): Promise<HardwareStatsBucket[]> => {
|
||||
const netProjection = {
|
||||
name: { $arrayElemAt: ["$sampleDoc.net.name", "$$nIdx"] },
|
||||
...Object.fromEntries(NET_RATE_FIELDS.map(([outputKey, sourceField]) => [outputKey, netRatePerSecond(sourceField)])),
|
||||
};
|
||||
|
||||
return await CheckModel.aggregate([
|
||||
return await CheckModel.aggregate<HardwareStatsBucket>([
|
||||
{
|
||||
$match: {
|
||||
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Schema, model, Types } from "mongoose";
|
||||
import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import type {
|
||||
Check,
|
||||
CheckAudits,
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
PageSpeedChecksResult,
|
||||
UptimeChecksResult,
|
||||
} from "@/domain/checks/check.type.js";
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import type { LatestChecksMap } from "@/domain/checks/check.repository.mongo.js";
|
||||
import { CheckFilter, DateRange } from "@/types/query.js";
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ import type {
|
||||
CheckMetadata,
|
||||
CheckNetworkInterfaceInfo,
|
||||
GotTimings,
|
||||
HardwareCheckStats,
|
||||
} from "@/domain/checks/check.type.js";
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { CheckModel, type CheckDocument } from "@/domain/checks/check.model.js";
|
||||
import mongoose from "mongoose";
|
||||
import { getDateFormat, getDateForRange } from "@/utils/dataUtils.js";
|
||||
@@ -512,33 +513,35 @@ class MongoChecksRepository implements IChecksRepository {
|
||||
totalChecks: upChecksDoc?.totalChecks ?? 0,
|
||||
};
|
||||
|
||||
const checks = (hardwareMetrics ?? []).map((metric) => ({
|
||||
bucketDate: metric._id,
|
||||
avgCpuUsage: metric.avgCpuUsage ?? 0,
|
||||
avgMemoryUsage: metric.avgMemoryUsage ?? 0,
|
||||
avgTemperature: metric.avgTemperature ?? [],
|
||||
disks: (metric.disks ?? []).map((disk: { [key: string]: number | string | undefined }) => ({
|
||||
name: disk?.name ?? "",
|
||||
readSpeed: disk?.readSpeed ?? 0,
|
||||
writeSpeed: disk?.writeSpeed ?? 0,
|
||||
totalBytes: disk?.totalBytes ?? 0,
|
||||
freeBytes: disk?.freeBytes ?? 0,
|
||||
usagePercent: disk?.usagePercent ?? 0,
|
||||
})),
|
||||
net: (metric.net ?? []).map((iface: { [key: string]: number | string | undefined }) => ({
|
||||
name: iface?.name ?? "",
|
||||
bytesSentPerSecond: iface?.bytesSentPerSecond ?? 0,
|
||||
deltaBytesRecv: iface?.deltaBytesRecv ?? 0,
|
||||
deltaPacketsSent: iface?.deltaPacketsSent ?? 0,
|
||||
deltaPacketsRecv: iface?.deltaPacketsRecv ?? 0,
|
||||
deltaErrIn: iface?.deltaErrIn ?? 0,
|
||||
deltaErrOut: iface?.deltaErrOut ?? 0,
|
||||
deltaDropIn: iface?.deltaDropIn ?? 0,
|
||||
deltaDropOut: iface?.deltaDropOut ?? 0,
|
||||
deltaFifoIn: iface?.deltaFifoIn ?? 0,
|
||||
deltaFifoOut: iface?.deltaFifoOut ?? 0,
|
||||
})),
|
||||
}));
|
||||
const checks = (hardwareMetrics ?? []).map(
|
||||
(metric): HardwareCheckStats => ({
|
||||
bucketDate: metric._id,
|
||||
avgCpuUsage: metric.avgCpuUsage ?? 0,
|
||||
avgMemoryUsage: metric.avgMemoryUsage ?? 0,
|
||||
avgTemperature: metric.avgTemperature ?? [],
|
||||
disks: (metric.disks ?? []).map((disk) => ({
|
||||
name: disk?.name ?? "",
|
||||
readSpeed: disk?.readSpeed ?? 0,
|
||||
writeSpeed: disk?.writeSpeed ?? 0,
|
||||
totalBytes: disk?.totalBytes ?? 0,
|
||||
freeBytes: disk?.freeBytes ?? 0,
|
||||
usagePercent: disk?.usagePercent ?? 0,
|
||||
})),
|
||||
net: (metric.net ?? []).map((iface) => ({
|
||||
name: iface?.name ?? "",
|
||||
bytesSentPerSecond: iface?.bytesSentPerSecond ?? 0,
|
||||
deltaBytesRecv: iface?.deltaBytesRecv ?? 0,
|
||||
deltaPacketsSent: iface?.deltaPacketsSent ?? 0,
|
||||
deltaPacketsRecv: iface?.deltaPacketsRecv ?? 0,
|
||||
deltaErrIn: iface?.deltaErrIn ?? 0,
|
||||
deltaErrOut: iface?.deltaErrOut ?? 0,
|
||||
deltaDropIn: iface?.deltaDropIn ?? 0,
|
||||
deltaDropOut: iface?.deltaDropOut ?? 0,
|
||||
deltaFifoIn: iface?.deltaFifoIn ?? 0,
|
||||
deltaFifoOut: iface?.deltaFifoOut ?? 0,
|
||||
})),
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
monitorType: "hardware" as const,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import type { Response } from "got";
|
||||
|
||||
export const CHECK_TTL_SENTINEL = 366;
|
||||
@@ -126,43 +126,6 @@ export interface PageSpeedChecksResult {
|
||||
groupedChecks: PageSpeedGroupedCheck[];
|
||||
}
|
||||
|
||||
export interface HardwareChecksResult {
|
||||
monitorType: "hardware";
|
||||
aggregateData: {
|
||||
totalChecks: number;
|
||||
};
|
||||
upChecks: {
|
||||
totalChecks: number;
|
||||
};
|
||||
checks: Array<{
|
||||
bucketDate: string;
|
||||
avgCpuUsage: number;
|
||||
avgMemoryUsage: number;
|
||||
avgTemperature: number[];
|
||||
disks: Array<{
|
||||
name: string;
|
||||
readSpeed: number;
|
||||
writeSpeed: number;
|
||||
totalBytes: number;
|
||||
freeBytes: number;
|
||||
usagePercent: number;
|
||||
}>;
|
||||
net: Array<{
|
||||
name: string;
|
||||
bytesSentPerSecond: number;
|
||||
deltaBytesRecv: number;
|
||||
deltaPacketsSent: number;
|
||||
deltaPacketsRecv: number;
|
||||
deltaErrIn: number;
|
||||
deltaErrOut: number;
|
||||
deltaDropIn: number;
|
||||
deltaDropOut: number;
|
||||
deltaFifoIn: number;
|
||||
deltaFifoOut: number;
|
||||
}>;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface GroupedCheck {
|
||||
bucketDate: string;
|
||||
avgResponseTime: number;
|
||||
@@ -205,3 +168,49 @@ export type NormalizedUptimeCheck<T extends GroupedCheck = GroupedCheck> = T & {
|
||||
};
|
||||
|
||||
export type CheckSnapshot = Omit<Check, "metadata" | "updatedAt">;
|
||||
|
||||
export interface HardwareDiskStats {
|
||||
name: string;
|
||||
readSpeed: number;
|
||||
writeSpeed: number;
|
||||
totalBytes: number;
|
||||
freeBytes: number;
|
||||
usagePercent: number;
|
||||
}
|
||||
|
||||
export interface HardwareNetStats {
|
||||
name: string;
|
||||
bytesSentPerSecond: number;
|
||||
deltaBytesRecv: number;
|
||||
deltaPacketsSent: number;
|
||||
deltaPacketsRecv: number;
|
||||
deltaErrIn: number;
|
||||
deltaErrOut: number;
|
||||
deltaDropIn: number;
|
||||
deltaDropOut: number;
|
||||
deltaFifoIn: number;
|
||||
deltaFifoOut: number;
|
||||
}
|
||||
|
||||
export interface HardwareCheckStats {
|
||||
bucketDate: string;
|
||||
avgCpuUsage: number;
|
||||
avgMemoryUsage: number;
|
||||
avgTemperature: number[];
|
||||
disks: HardwareDiskStats[];
|
||||
net: HardwareNetStats[];
|
||||
}
|
||||
|
||||
export interface HardwareStats {
|
||||
aggregateData: {
|
||||
totalChecks: number;
|
||||
};
|
||||
upChecks: {
|
||||
totalChecks: number;
|
||||
};
|
||||
checks: HardwareCheckStats[];
|
||||
}
|
||||
|
||||
export interface HardwareChecksResult extends HardwareStats {
|
||||
monitorType: "hardware";
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Schema, model, Types } from "mongoose";
|
||||
import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import type { GeoCheck, GeoCheckLocation, GeoCheckMetadata, GeoCheckResult, GeoCheckTimings } from "@/domain/geo-checks/geo-check.type.js";
|
||||
|
||||
type GeoCheckMetadataDocument = Omit<GeoCheckMetadata, "monitorId" | "teamId"> & {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { GeoCheck } from "@/domain/geo-checks/geo-check.type.js";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import type { GeoCheckResult, GeoContinent } from "@/domain/geo-checks/geo-check.type.js";
|
||||
import { Types } from "mongoose";
|
||||
import type { FlatGeoChecksQueryResult, IGeoChecksRepository } from "@/domain/geo-checks/geo-check.repository.interface.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import type { MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
|
||||
export const GeoContinents = ["EU", "NA", "AS", "SA", "AF", "OC"] as const;
|
||||
export type GeoContinent = (typeof GeoContinents)[number];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const SERVICE_NAME = "incidentService";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import type { MonitorStatusResponse } from "@/types/network.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { getDateForRange } from "@/utils/dataUtils.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Schema, model, Types } from "mongoose";
|
||||
import type { Monitor, MonitorMatchMethod, CheckSnapshot } from "@/domain/monitors/monitor.types.js";
|
||||
import { DnsRecordTypes, MonitorTypes, MonitorStatuses, PageSpeedStrategies, HttpMethods } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor, MonitorMatchMethod, CheckSnapshot } from "@/domain/monitors/monitor.type.js";
|
||||
import { DnsRecordTypes, MonitorTypes, MonitorStatuses, PageSpeedStrategies, HttpMethods } from "@/domain/monitors/monitor.type.js";
|
||||
import type {
|
||||
CheckAudits,
|
||||
CheckCaptureInfo,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MonitorType, Monitor, MonitorStatus, MonitorsSummary, CheckSnapshot } from "@/domain/monitors/monitor.types.js";
|
||||
import type { MonitorType, Monitor, MonitorStatus, MonitorsSummary, CheckSnapshot } from "@/domain/monitors/monitor.type.js";
|
||||
|
||||
export interface TeamQueryConfig {
|
||||
limit?: number;
|
||||
@@ -26,9 +26,9 @@ export interface IMonitorsRepository {
|
||||
findByIdLean(monitorId: string): Promise<Monitor | null>;
|
||||
|
||||
// collection fetch
|
||||
findAll(): Promise<Monitor[] | null>;
|
||||
findByTeamId(teamId: string, config: TeamQueryConfig): Promise<Monitor[] | null>;
|
||||
findByTeamIdWithStats(teamId: string, config: TeamQueryConfig): Promise<Monitor[] | null>;
|
||||
findAll(): Promise<Monitor[]>;
|
||||
findByTeamId(teamId: string, config: TeamQueryConfig): Promise<Monitor[]>;
|
||||
findByTeamIdWithStats(teamId: string, config: TeamQueryConfig): Promise<Monitor[]>;
|
||||
findByIds(monitorIds: string[]): Promise<Monitor[]>;
|
||||
findByIdsWithChecks(monitorIds: string[], checksCount?: number): Promise<Monitor[]>;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MonitorModel } from "@/domain/monitors/monitor.model.js";
|
||||
import type { MonitorDocument, CheckSnapshotDocument } from "@/domain/monitors/monitor.model.js";
|
||||
import type { CheckSnapshot } from "@/domain/checks/check.type.js";
|
||||
import type { Monitor, MonitorStatus, MonitorsSummary } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor, MonitorStatus, MonitorsSummary } from "@/domain/monitors/monitor.type.js";
|
||||
import mongoose, { type FilterQuery, type PipelineStage } from "mongoose";
|
||||
import { MongoBulkWriteError } from "mongodb";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
@@ -96,14 +96,14 @@ class MongoMonitorsRepository implements IMonitorsRepository {
|
||||
return { sort: { [field]: order === "asc" ? 1 : -1 } as const, skip: Math.max(page, 0) * rowsPerPage, limit: rowsPerPage };
|
||||
};
|
||||
|
||||
findByTeamId = async (teamId: string, config: TeamQueryConfig): Promise<Monitor[] | null> => {
|
||||
findByTeamId = async (teamId: string, config: TeamQueryConfig): Promise<Monitor[]> => {
|
||||
const query = this.queryBuilder(config, teamId);
|
||||
const { sort, skip, limit } = this.pageOptions(config);
|
||||
const documents = await MonitorModel.find(query).sort(sort).skip(skip).limit(limit);
|
||||
return this.mapDocuments(documents);
|
||||
};
|
||||
|
||||
findByTeamIdWithStats = async (teamId: string, config: TeamQueryConfig): Promise<Monitor[] | null> => {
|
||||
findByTeamIdWithStats = async (teamId: string, config: TeamQueryConfig): Promise<Monitor[]> => {
|
||||
const { sort, skip, limit } = this.pageOptions(config);
|
||||
const query = this.queryBuilder(config, teamId);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NormalizeData, NormalizeDataUptimeDetails } from "@/utils/dataUtils.js";
|
||||
import { type Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { type Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import type {
|
||||
MonitorType,
|
||||
MonitorsWithChecksByTeamIdResult,
|
||||
@@ -8,8 +8,8 @@ import type {
|
||||
PageSpeedDetailsResult,
|
||||
GamesMap,
|
||||
GroupedGeoCheckResult,
|
||||
} from "@/domain/monitors/monitor.types.js";
|
||||
import { supportsGeoCheck, supportsUptimeDetails } from "@/domain/monitors/monitor.types.js";
|
||||
} from "@/domain/monitors/monitor.type.js";
|
||||
import { supportsGeoCheck, supportsUptimeDetails } from "@/domain/monitors/monitor.type.js";
|
||||
import type { UptimeChecksResult, HardwareChecksResult, PageSpeedChecksResult } from "@/domain/checks/check.type.js";
|
||||
import type { GeoContinent } from "@/domain/geo-checks/geo-check.type.js";
|
||||
import type { IChecksRepository } from "@/domain/checks/check.repository.interface.js";
|
||||
@@ -318,7 +318,7 @@ export class MonitorService implements IMonitorService {
|
||||
type?: MonitorType | MonitorType[];
|
||||
tags?: string | string[];
|
||||
filter?: string;
|
||||
}): Promise<Monitor[] | null> => {
|
||||
}): Promise<Monitor[]> => {
|
||||
return await this.monitorsRepository.findByTeamId(teamId, { type, tags, filter });
|
||||
};
|
||||
|
||||
@@ -356,13 +356,12 @@ export class MonitorService implements IMonitorService {
|
||||
order,
|
||||
});
|
||||
|
||||
const monitorsList = (monitors ?? []) as Monitor[];
|
||||
const snapshotTypes: MonitorType[] = ["hardware"];
|
||||
const requestedTypes = Array.isArray(type) ? type : type ? [type] : [];
|
||||
const snapshotOnlyRequest =
|
||||
requestedTypes.length > 0 && requestedTypes.every((requestedType) => snapshotTypes.includes(requestedType as MonitorType));
|
||||
|
||||
const monitorsWithChecks = monitorsList.map((monitor: Monitor) => {
|
||||
const monitorsWithChecks = monitors.map((monitor: Monitor) => {
|
||||
const rawChecks = monitor.recentChecks ?? [];
|
||||
const isSnapshotType = snapshotOnlyRequest || snapshotTypes.includes(monitor.type);
|
||||
const checks = isSnapshotType ? rawChecks.slice(0, 1) : NormalizeData(rawChecks, 10, 100);
|
||||
@@ -523,7 +522,7 @@ export class MonitorService implements IMonitorService {
|
||||
exportMonitorsToJSON = async ({ teamId }: { teamId: string }): Promise<Monitor[]> => {
|
||||
const monitors = await this.monitorsRepository.findByTeamId(teamId, {});
|
||||
|
||||
if (!monitors || monitors.length === 0) {
|
||||
if (monitors.length === 0) {
|
||||
throw new AppError({ message: "No monitors found to export.", service: SERVICE_NAME, method: "exportMonitorsToJSON", status: 400 });
|
||||
}
|
||||
|
||||
|
||||
+1
-42
@@ -3,6 +3,7 @@ export type { CheckSnapshot } from "@/domain/checks/check.type.js";
|
||||
import type { GeoContinent, GroupedGeoCheck } from "@/domain/geo-checks/geo-check.type.js";
|
||||
export type { GeoContinent } from "@/domain/geo-checks/geo-check.type.js";
|
||||
import http from "node:http";
|
||||
import { HardwareStats } from "@/domain/checks/check.type.js";
|
||||
|
||||
export const HttpStatusCodes = [
|
||||
...Object.keys(http.STATUS_CODES).map(Number),
|
||||
@@ -149,48 +150,6 @@ export interface UptimeDetailsResult {
|
||||
monitorStats: import("../monitor-stats/monitor-stats.type.js").MonitorStats | null;
|
||||
}
|
||||
|
||||
export interface HardwareDiskStats {
|
||||
name: string;
|
||||
readSpeed: number;
|
||||
writeSpeed: number;
|
||||
totalBytes: number;
|
||||
freeBytes: number;
|
||||
usagePercent: number;
|
||||
}
|
||||
|
||||
export interface HardwareNetStats {
|
||||
name: string;
|
||||
bytesSentPerSecond: number;
|
||||
deltaBytesRecv: number;
|
||||
deltaPacketsSent: number;
|
||||
deltaPacketsRecv: number;
|
||||
deltaErrIn: number;
|
||||
deltaErrOut: number;
|
||||
deltaDropIn: number;
|
||||
deltaDropOut: number;
|
||||
deltaFifoIn: number;
|
||||
deltaFifoOut: number;
|
||||
}
|
||||
|
||||
export interface HardwareCheckStats {
|
||||
bucketDate: string;
|
||||
avgCpuUsage: number;
|
||||
avgMemoryUsage: number;
|
||||
avgTemperature: number[];
|
||||
disks: HardwareDiskStats[];
|
||||
net: HardwareNetStats[];
|
||||
}
|
||||
|
||||
export interface HardwareStats {
|
||||
aggregateData: {
|
||||
totalChecks: number;
|
||||
};
|
||||
upChecks: {
|
||||
totalChecks: number;
|
||||
};
|
||||
checks: HardwareCheckStats[];
|
||||
}
|
||||
|
||||
export interface HardwareDetailsResult {
|
||||
monitor: Monitor;
|
||||
stats: HardwareStats;
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import type { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import type { MonitorActionDecision } from "@/worker/worker.helper.js";
|
||||
import type {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import type { Notification } from "@/domain/notifications/notification.type.js";
|
||||
import type { MonitorStatusResponse } from "@/types/network.js";
|
||||
import type { NotificationMessage } from "@/domain/notifications/notification.type.js";
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from "@/domain/status-pages/status-page.type.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import { NormalizeData } from "@/utils/dataUtils.js";
|
||||
|
||||
export interface IStatusPageService {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import type { NormalizedCheck, CheckSnapshot } from "@/domain/checks/check.type.js";
|
||||
export const StatusPageTypes = ["uptime", "infrastructure"] as const;
|
||||
export type StatusPageType = (typeof StatusPageTypes)[number];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { GeoContinent, GeoCheckResult, GeoCheckTimings, GeoCheckLocation } from "@/domain/geo-checks/geo-check.type.js";
|
||||
import { supportsGeoCheck, type HttpStatusCode } from "@/domain/monitors/monitor.types.js";
|
||||
import { MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { supportsGeoCheck, type HttpStatusCode } from "@/domain/monitors/monitor.type.js";
|
||||
import { MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import type { ILogger } from "@/utils/logger.js";
|
||||
import got from "got";
|
||||
import { isStatusUp } from "@/service/network/utils.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import jmespath from "jmespath";
|
||||
import RE2 from "re2";
|
||||
type JmesPath = typeof jmespath;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DNSStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import type { Resolver } from "dns/promises";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { timeRequest } from "@/service/network/utils.js";
|
||||
import { NETWORK_ERROR } from "@/types/network.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { DockerStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { ILogger } from "@/utils/logger.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import Dockerode from "dockerode";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { GameStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { GameDig } from "gamedig";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { NETWORK_ERROR } from "@/types/network.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { GrpcStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { timeRequest } from "@/service/network/utils.js";
|
||||
import * as grpc from "@grpc/grpc-js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { HttpProvider } from "@/service/network/HttpProvider.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { HttpStatusPayload } from "@/types/network.js";
|
||||
import { MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Agent as HttpsAgent } from "https";
|
||||
import { Agent as HttpAgent } from "http";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { isStatusUp } from "@/service/network/utils.js";
|
||||
import { NETWORK_ERROR } from "@/types/network.js";
|
||||
import CacheableLookup from "cacheable-lookup";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { MonitorStatusResponse } from "@/types/network.js";
|
||||
|
||||
export interface IStatusProvider<T> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { MonitorStatusResponse, PageSpeedStatusPayload } from "@/types/network.js";
|
||||
import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/domain/monitors/monitor.type.js";
|
||||
import { HttpProvider } from "@/service/network/HttpProvider.js";
|
||||
import { ISettingsService } from "@/domain/app-settings/app-settings.service.js";
|
||||
import { ILogger } from "@/utils/logger.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PingStatusPayload } from "@/types/network.js";
|
||||
import { IStatusProvider } from "./IStatusProvider.js";
|
||||
import { MonitorType, Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { MonitorType, Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import { MonitorStatusResponse } from "@/types/network.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import ping from "ping";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { PortStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { timeRequest } from "@/service/network/utils.js";
|
||||
import { NETWORK_ERROR } from "@/types/network.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IStatusProvider } from "@/service/network/IStatusProvider.js";
|
||||
import { WebSocketStatusPayload, MonitorStatusResponse } from "@/types/network.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { timeRequest } from "@/service/network/utils.js";
|
||||
import { NETWORK_ERROR } from "@/types/network.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { HttpStatusCode } from "@/domain/monitors/monitor.types.js";
|
||||
import type { HttpStatusCode } from "@/domain/monitors/monitor.type.js";
|
||||
|
||||
export const timeRequest = async <T>(operation: () => Promise<T>): Promise<{ response: T | null; responseTime: number; error: unknown }> => {
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
import type { MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.js";
|
||||
import type { AxiosStatic } from "axios";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js";
|
||||
import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js";
|
||||
import type { Check, CheckDiskInfo, CheckSnapshot } from "@/domain/checks/check.type.js";
|
||||
import type { Monitor, MonitorStatus } from "@/domain/monitors/monitor.types.js";
|
||||
import type { Monitor, MonitorStatus } from "@/domain/monitors/monitor.type.js";
|
||||
import type {
|
||||
DockerStatusPayload,
|
||||
GameStatusPayload,
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { ILogger } from "@/utils/logger.js";
|
||||
import type { HardwareStatusMetrics } from "@/types/network.js";
|
||||
import { MAX_RECENT_CHECKS } from "@/domain/monitors/monitor.types.js";
|
||||
import { MAX_RECENT_CHECKS } from "@/domain/monitors/monitor.type.js";
|
||||
|
||||
const SERVICE_NAME = "StatusService";
|
||||
const HARDWARE_ALERT_COUNTER_START = 5;
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {
|
||||
GotTimings,
|
||||
ILighthouseAudit,
|
||||
} from "@/domain/checks/check.type.js";
|
||||
import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.types.js";
|
||||
import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.type.js";
|
||||
|
||||
import type { QueryResult } from "gamedig";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MonitorStatusResponse } from "@/types/network.js";
|
||||
import { MonitorEvaluation } from "@/worker/worker.interface.js";
|
||||
import { Check } from "@/domain/checks/check.type.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import { IMonitorStatusPolicy } from "@/worker/worker.monitor-status-policy.js";
|
||||
import { IStatusService } from "@/service/statusService.js";
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import { MonitorEvaluation } from "@/worker/worker.interface.js";
|
||||
import { IMaintenanceWindowsRepository } from "@/domain/maintenance-windows/maintenance-window.repository.interface.js";
|
||||
import { isWindowActive } from "@/utils/maintenanceWindow.js";
|
||||
import { ILogger } from "@/utils/logger.js";
|
||||
import { IBufferService } from "@/service/bufferService.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { supportsGeoCheck } from "@/domain/monitors/monitor.types.js";
|
||||
import { supportsGeoCheck } from "@/domain/monitors/monitor.type.js";
|
||||
import { IGeoChecksService } from "@/domain/geo-checks/geo-check.service.js";
|
||||
|
||||
const SERVICE_NAME = "CheckPipeline";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import { Check } from "@/domain/checks/check.type.js";
|
||||
import { MonitorStatusResponse } from "@/types/network.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Monitor } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor } from "@/domain/monitors/monitor.type.js";
|
||||
import { Check } from "@/domain/checks/check.type.js";
|
||||
import { JobType } from "@/domain/jobs/job.type.js";
|
||||
import { MonitorPayloadMap, MonitorStatusResponse, StatusChangeResult } from "@/types/network.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IJobScheduler } from "@/worker/worker.interface.js";
|
||||
import { IJobsRepository } from "@/domain/jobs/job.repository.interface.js";
|
||||
import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js";
|
||||
import { Monitor, supportsGeoCheck } from "@/domain/monitors/monitor.types.js";
|
||||
import { Monitor, supportsGeoCheck } from "@/domain/monitors/monitor.type.js";
|
||||
import { type Job, type JobSeed, type JobType, jobId } from "@/domain/jobs/job.type.js";
|
||||
import { IQueueWorkersRepository } from "@/domain/queue-workers/queue-worker.repository.interface.js";
|
||||
import { WorkerJobsPagination, WorkerJobSummary, WorkerMetrics } from "@/worker/worker.interface.js";
|
||||
@@ -187,7 +187,7 @@ export class JobScheduler implements IJobScheduler {
|
||||
// Seed queue
|
||||
protected reconcile = async () => {
|
||||
const now = Date.now();
|
||||
const monitors = (await this.monitorsRepository.findAll()) ?? [];
|
||||
const monitors = await this.monitorsRepository.findAll();
|
||||
for (const monitor of monitors) {
|
||||
await this.jobsRepository.upsertJob(this.toCheckJob(monitor, now));
|
||||
if (supportsGeoCheck(monitor.type) && monitor.geoCheckEnabled) {
|
||||
|
||||
Reference in new issue
Block a user