related serverices to TS
This commit is contained in:
1 parent
cf67c82f5e
commit
ed80837810
6 files changed
+162
-114
No files matched your search
+6
-10
@@ -1,14 +1,5 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { pathsToModuleNameMapper } from "ts-jest";
|
||||
import type { Config } from "jest";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const tsconfigPath = path.resolve(__dirname, "./tsconfig.json");
|
||||
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, "utf-8"));
|
||||
|
||||
const config: Config = {
|
||||
rootDir: ".",
|
||||
testEnvironment: "node",
|
||||
@@ -17,7 +8,12 @@ const config: Config = {
|
||||
"^.+\\.(t|j)sx?$": ["ts-jest", { useESM: true, tsconfig: "./tsconfig.jest.json" }],
|
||||
},
|
||||
moduleNameMapper: {
|
||||
...pathsToModuleNameMapper(tsconfig.compilerOptions.paths || {}, { prefix: "<rootDir>/" }),
|
||||
"^@/validation/(.*)\\.js$": "<rootDir>/src/validation/$1.js",
|
||||
"^@/utils/(AppError)\\.js$": "<rootDir>/src/utils/$1.ts",
|
||||
"^@/utils/(.*)\\.js$": "<rootDir>/src/utils/$1.js",
|
||||
"^@/(.*)\\.ts$": "<rootDir>/src/$1.ts",
|
||||
"^@/(.*)\\.js$": "<rootDir>/src/$1.ts",
|
||||
"^@/(.*)$": "<rootDir>/src/$1",
|
||||
},
|
||||
testMatch: ["<rootDir>/test/**/*.test.ts"],
|
||||
setupFilesAfterEnv: [],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { IMonitorsRepository } from "@/repositories/index.js";
|
||||
import type { MonitorType } from "@/types/index.js";
|
||||
|
||||
const SERVICE_NAME = "checkService";
|
||||
|
||||
@@ -35,6 +36,8 @@ class CheckService {
|
||||
return CheckService.SERVICE_NAME;
|
||||
}
|
||||
|
||||
buildCheck = async (statusResponse: any, type: MonitorType) => {};
|
||||
|
||||
getChecksByMonitor = async ({ monitorId, query, teamId }: { monitorId: string; query: any; teamId: string }) => {
|
||||
if (!monitorId) {
|
||||
throw this.errorService.createBadRequestError("No monitor ID in request");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const SERVICE_NAME = "JobQueueHelper";
|
||||
import type { Monitor } from "@/types/monitor.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
import { error } from "winston";
|
||||
|
||||
class SuperSimpleQueueHelper {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
|
||||
+103
-38
@@ -1,10 +1,63 @@
|
||||
import { Got } from "got";
|
||||
import type { Monitor } from "@/types/index.js";
|
||||
|
||||
import CacheableLookup from "cacheable-lookup";
|
||||
const SERVICE_NAME = "NetworkService";
|
||||
|
||||
class NetworkService {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
|
||||
constructor({ axios, got, https, jmespath, GameDig, ping, logger, http, Docker, net, stringService, settingsService }) {
|
||||
private TYPE_PING: string;
|
||||
private TYPE_HTTP: string;
|
||||
private TYPE_PAGESPEED: string;
|
||||
private TYPE_HARDWARE: string;
|
||||
private TYPE_DOCKER: string;
|
||||
private TYPE_PORT: string;
|
||||
private TYPE_GAME: string;
|
||||
private SERVICE_NAME: string;
|
||||
private NETWORK_ERROR: number;
|
||||
private PING_ERROR: number;
|
||||
|
||||
private axios: any;
|
||||
private got: Got;
|
||||
private https: any;
|
||||
private jmespath: any;
|
||||
private GameDig: any;
|
||||
private ping: any;
|
||||
private logger: any;
|
||||
private http: any;
|
||||
private Docker: any;
|
||||
private net: any;
|
||||
private stringService: any;
|
||||
private settingsService: any;
|
||||
|
||||
constructor({
|
||||
axios,
|
||||
got,
|
||||
https,
|
||||
jmespath,
|
||||
GameDig,
|
||||
ping,
|
||||
logger,
|
||||
http,
|
||||
Docker,
|
||||
net,
|
||||
stringService,
|
||||
settingsService,
|
||||
}: {
|
||||
axios: any;
|
||||
got: Got;
|
||||
https: any;
|
||||
jmespath: any;
|
||||
GameDig: any;
|
||||
ping: any;
|
||||
logger: any;
|
||||
http: any;
|
||||
Docker: any;
|
||||
net: any;
|
||||
stringService: any;
|
||||
settingsService: any;
|
||||
}) {
|
||||
this.TYPE_PING = "ping";
|
||||
this.TYPE_HTTP = "http";
|
||||
this.TYPE_PAGESPEED = "pagespeed";
|
||||
@@ -17,11 +70,11 @@ class NetworkService {
|
||||
this.PING_ERROR = 5001;
|
||||
this.axios = axios;
|
||||
this.https = https;
|
||||
this.http = http;
|
||||
this.jmespath = jmespath;
|
||||
this.GameDig = GameDig;
|
||||
this.ping = ping;
|
||||
this.logger = logger;
|
||||
this.http = http;
|
||||
this.Docker = Docker;
|
||||
this.net = net;
|
||||
this.stringService = stringService;
|
||||
@@ -39,7 +92,7 @@ class NetworkService {
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
async timeRequest(operation) {
|
||||
async timeRequest(operation: any) {
|
||||
const start = process.hrtime.bigint();
|
||||
try {
|
||||
const response = await operation();
|
||||
@@ -52,7 +105,7 @@ class NetworkService {
|
||||
}
|
||||
|
||||
// Main entry point
|
||||
async requestStatus(monitor) {
|
||||
async requestStatus(monitor: Monitor) {
|
||||
const type = monitor?.type || "unknown";
|
||||
switch (type) {
|
||||
case this.TYPE_PING:
|
||||
@@ -74,7 +127,7 @@ class NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
async requestPing(monitor) {
|
||||
async requestPing(monitor: Monitor) {
|
||||
try {
|
||||
if (!monitor?.url) {
|
||||
throw new Error("Monitor URL is required");
|
||||
@@ -112,16 +165,16 @@ class NetworkService {
|
||||
}
|
||||
|
||||
return pingResponse;
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestPing";
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async requestHttp(monitor) {
|
||||
async requestHttp(monitor: Monitor) {
|
||||
const { url, secret, id, teamId, type, ignoreTlsErrors, jsonPath, matchMethod, expectedValue } = monitor;
|
||||
const httpResponse = {
|
||||
const httpResponse: Record<string, any> = {
|
||||
monitorId: id,
|
||||
teamId: teamId,
|
||||
type,
|
||||
@@ -131,7 +184,7 @@ class NetworkService {
|
||||
if (!url) {
|
||||
throw new Error("Monitor URL is required");
|
||||
}
|
||||
const config = {
|
||||
const config: Record<string, any> = {
|
||||
headers: secret ? { Authorization: `Bearer ${secret}` } : undefined,
|
||||
};
|
||||
|
||||
@@ -145,7 +198,7 @@ class NetworkService {
|
||||
|
||||
const response = await this.got(url, config);
|
||||
|
||||
let payload;
|
||||
let payload: any;
|
||||
const contentType = response.headers["content-type"];
|
||||
|
||||
if (contentType && contentType.includes("application/json")) {
|
||||
@@ -231,7 +284,7 @@ class NetworkService {
|
||||
}
|
||||
}
|
||||
return httpResponse;
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.name === "HTTPError" || err.name === "RequestError") {
|
||||
httpResponse.code = err?.response?.statusCode || this.NETWORK_ERROR;
|
||||
httpResponse.status = false;
|
||||
@@ -247,7 +300,7 @@ class NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
async requestPageSpeed(monitor) {
|
||||
async requestPageSpeed(monitor: Monitor) {
|
||||
try {
|
||||
const url = monitor.url;
|
||||
if (!url) {
|
||||
@@ -269,24 +322,24 @@ class NetworkService {
|
||||
...monitor,
|
||||
url: pageSpeedUrl,
|
||||
});
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestPageSpeed";
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async requestHardware(monitor) {
|
||||
async requestHardware(monitor: Monitor) {
|
||||
try {
|
||||
return await this.requestHttp(monitor);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestHardware";
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async requestDocker(monitor) {
|
||||
async requestDocker(monitor: Monitor) {
|
||||
try {
|
||||
if (!monitor.url) {
|
||||
throw new Error("Monitor URL is required");
|
||||
@@ -297,7 +350,7 @@ class NetworkService {
|
||||
handleError: true, // Enable error handling
|
||||
});
|
||||
|
||||
const dockerResponse = {
|
||||
const dockerResponse: Record<string, any> = {
|
||||
monitorId: monitor.id,
|
||||
type: monitor.type,
|
||||
};
|
||||
@@ -309,18 +362,18 @@ class NetworkService {
|
||||
|
||||
// Priority-based matching to avoid ambiguity:
|
||||
// 1. Exact full ID match (64-char)
|
||||
let exactIdMatch = containers.find((c) => c.Id.toLowerCase() === normalizedInput);
|
||||
let exactIdMatch = containers.find((c: any) => c.Id.toLowerCase() === normalizedInput);
|
||||
|
||||
// 2. Exact container name match (case-insensitive)
|
||||
let exactNameMatch = containers.find((c) =>
|
||||
c.Names.some((name) => {
|
||||
let exactNameMatch = containers.find((c: any) =>
|
||||
c.Names.some((name: string) => {
|
||||
const cleanName = name.replace(/^\/+/, "").toLowerCase();
|
||||
return cleanName === normalizedInput;
|
||||
})
|
||||
);
|
||||
|
||||
// 3. Partial ID match (fallback for backwards compatibility)
|
||||
let partialIdMatch = containers.find((c) => c.Id.toLowerCase().startsWith(normalizedInput));
|
||||
let partialIdMatch = containers.find((c: any) => c.Id.toLowerCase().startsWith(normalizedInput));
|
||||
|
||||
// Select container based on priority
|
||||
let targetContainer = exactIdMatch || exactNameMatch || partialIdMatch;
|
||||
@@ -360,7 +413,9 @@ class NetworkService {
|
||||
}
|
||||
|
||||
const container = docker.getContainer(targetContainer.Id);
|
||||
const { response, responseTime, error } = await this.timeRequest(() => container.inspect());
|
||||
const { response, responseTime, error }: { response?: any; responseTime?: number; error?: any } = await this.timeRequest(() =>
|
||||
container.inspect()
|
||||
);
|
||||
|
||||
dockerResponse.responseTime = responseTime;
|
||||
dockerResponse.status = response?.State?.Status === "running" ? true : false;
|
||||
@@ -375,14 +430,14 @@ class NetworkService {
|
||||
}
|
||||
|
||||
return dockerResponse;
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "requestDocker";
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async requestPort(monitor) {
|
||||
async requestPort(monitor: Monitor) {
|
||||
try {
|
||||
const { url, port } = monitor;
|
||||
const { response, responseTime, error } = await this.timeRequest(async () => {
|
||||
@@ -405,7 +460,7 @@ class NetworkService {
|
||||
reject(new Error("Connection timeout"));
|
||||
});
|
||||
|
||||
socket.on("error", (err) => {
|
||||
socket.on("error", (err: any) => {
|
||||
socket.destroy();
|
||||
reject(err);
|
||||
});
|
||||
@@ -429,18 +484,18 @@ class NetworkService {
|
||||
}
|
||||
|
||||
return portResponse;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestTCP";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async requestGame(monitor) {
|
||||
async requestGame(monitor: Monitor) {
|
||||
try {
|
||||
const { url, port, gameId } = monitor;
|
||||
|
||||
const gameResponse = {
|
||||
const gameResponse: Record<string, any> = {
|
||||
code: 200,
|
||||
status: true,
|
||||
message: "Success",
|
||||
@@ -452,7 +507,7 @@ class NetworkService {
|
||||
type: gameId,
|
||||
host: url,
|
||||
port: port,
|
||||
}).catch((error) => {
|
||||
}).catch((error: any) => {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: this.SERVICE_NAME,
|
||||
@@ -471,21 +526,21 @@ class NetworkService {
|
||||
gameResponse.responseTime = state.ping;
|
||||
gameResponse.payload = state;
|
||||
return gameResponse;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestPing";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async handleUnsupportedType(type) {
|
||||
const err = new Error(`Unsupported type: ${type}`);
|
||||
async handleUnsupportedType(type: string) {
|
||||
const err: any = new Error(`Unsupported type: ${type}`);
|
||||
err.service = this.SERVICE_NAME;
|
||||
err.method = "getStatus";
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Other network requests unrelated to monitoring:
|
||||
async requestWebhook(type, url, body) {
|
||||
async requestWebhook(type: string, url: string, body: any) {
|
||||
try {
|
||||
const response = await this.axios.post(url, body, {
|
||||
headers: {
|
||||
@@ -500,7 +555,7 @@ class NetworkService {
|
||||
message: `Successfully sent ${type} notification`,
|
||||
payload: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: this.SERVICE_NAME,
|
||||
@@ -517,7 +572,7 @@ class NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
async requestPagerDuty({ message, routingKey, monitorUrl }) {
|
||||
async requestPagerDuty({ message, routingKey, monitorUrl }: { message: string; routingKey: string; monitorUrl: string }) {
|
||||
try {
|
||||
const response = await this.axios.post(`https://events.pagerduty.com/v2/enqueue`, {
|
||||
routing_key: routingKey,
|
||||
@@ -532,7 +587,7 @@ class NetworkService {
|
||||
|
||||
if (response?.data?.status !== "success") return false;
|
||||
return true;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
error.details = error.response?.data;
|
||||
error.service = this.SERVICE_NAME;
|
||||
error.method = "requestPagerDuty";
|
||||
@@ -540,7 +595,17 @@ class NetworkService {
|
||||
}
|
||||
}
|
||||
|
||||
async requestMatrix({ homeserverUrl, accessToken, roomId, message }) {
|
||||
async requestMatrix({
|
||||
homeserverUrl,
|
||||
accessToken,
|
||||
roomId,
|
||||
message,
|
||||
}: {
|
||||
homeserverUrl: string;
|
||||
accessToken: string;
|
||||
roomId: string;
|
||||
message: string;
|
||||
}) {
|
||||
try {
|
||||
const url = `${homeserverUrl}/_matrix/client/v3/rooms/${roomId}/send/m.room.message?access_token=${accessToken}`;
|
||||
const body = {
|
||||
@@ -560,7 +625,7 @@ class NetworkService {
|
||||
code: response.status,
|
||||
message: "Successfully sent Matrix notification",
|
||||
};
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: this.SERVICE_NAME,
|
||||
+48
-63
@@ -1,11 +1,30 @@
|
||||
import { IMonitorsRepository } from "@/repositories/index.js";
|
||||
import MonitorStats from "../../db/models/MonitorStats.js";
|
||||
import { CheckModel } from "@/db/models/index.js";
|
||||
import type { Monitor } from "@/types/index.js";
|
||||
const SERVICE_NAME = "StatusService";
|
||||
|
||||
class StatusService {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
private db: any;
|
||||
private logger: any;
|
||||
private buffer: any;
|
||||
private incidentService: any;
|
||||
private monitorsRepository: IMonitorsRepository;
|
||||
|
||||
constructor({ db, logger, buffer, incidentService, monitorsRepository }) {
|
||||
constructor({
|
||||
db,
|
||||
logger,
|
||||
buffer,
|
||||
incidentService,
|
||||
monitorsRepository,
|
||||
}: {
|
||||
db: any;
|
||||
logger: any;
|
||||
buffer: any;
|
||||
incidentService: any;
|
||||
monitorsRepository: IMonitorsRepository;
|
||||
}) {
|
||||
this.db = db;
|
||||
this.logger = logger;
|
||||
this.buffer = buffer;
|
||||
@@ -17,7 +36,7 @@ class StatusService {
|
||||
return StatusService.SERVICE_NAME;
|
||||
}
|
||||
|
||||
async updateRunningStats({ monitor, networkResponse }) {
|
||||
async updateRunningStats({ monitor, networkResponse }: { monitor: Monitor; networkResponse: any }) {
|
||||
try {
|
||||
const monitorId = monitor.id;
|
||||
const { responseTime, status } = networkResponse;
|
||||
@@ -78,9 +97,9 @@ class StatusService {
|
||||
|
||||
await stats.save();
|
||||
return true;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
this.logger.error({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
message: error.message,
|
||||
method: "updateRunningStats",
|
||||
stack: error.stack,
|
||||
@@ -89,23 +108,13 @@ class StatusService {
|
||||
}
|
||||
}
|
||||
|
||||
getStatusString = (status) => {
|
||||
getStatusString = (status: boolean | undefined) => {
|
||||
if (status === true) return "up";
|
||||
if (status === false) return "down";
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves check if needed and adds to incident buffer
|
||||
* Removes check from checks buffer if it was saved immediately
|
||||
*
|
||||
* @param {Object} check - The check object
|
||||
* @param {Object} monitor - The monitor object
|
||||
* @param {string} action - The incident action ("create" or "resolve")
|
||||
* @param {string} errorContext - Context for error messages
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
handleIncidentForCheck = async (check, monitor, action, errorContext = "incident handling") => {
|
||||
handleIncidentForCheck = async (check: any, monitor: Monitor, action: any, errorContext = "incident handling") => {
|
||||
try {
|
||||
let savedCheck = check;
|
||||
|
||||
@@ -115,9 +124,9 @@ class StatusService {
|
||||
savedCheck = await checkModel.save();
|
||||
|
||||
this.buffer.removeCheckFromBuffer(check);
|
||||
} catch (checkError) {
|
||||
} catch (checkError: any) {
|
||||
this.logger.error({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "handleIncidentForCheck",
|
||||
message: `Failed to save check immediately for ${errorContext}: ${checkError.message}`,
|
||||
monitorId: monitor.id,
|
||||
@@ -130,9 +139,9 @@ class StatusService {
|
||||
if (savedCheck && savedCheck._id) {
|
||||
try {
|
||||
this.buffer.addIncidentToBuffer({ monitor, check: savedCheck, action });
|
||||
} catch (incidentError) {
|
||||
} catch (incidentError: any) {
|
||||
this.logger.error({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "handleIncidentForCheck",
|
||||
message: `Failed to add incident to buffer for ${errorContext}: ${incidentError.message}`,
|
||||
monitorId: monitor.id,
|
||||
@@ -141,9 +150,9 @@ class StatusService {
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
this.logger.error({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "handleIncidentForCheck",
|
||||
message: `Error in ${errorContext}: ${error.message}`,
|
||||
monitorId: monitor?.id,
|
||||
@@ -151,19 +160,8 @@ class StatusService {
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Updates the status of a monitor based on the network response.
|
||||
*
|
||||
* @param {Object} networkResponse - The network response containing monitorId and status.
|
||||
* @param {string} networkResponse.monitorId - The ID of the monitor.
|
||||
* @param {string} networkResponse.status - The new status of the monitor.
|
||||
* @returns {Promise<Object>} - A promise that resolves to an object containinfg the monitor, statusChanged flag, and previous status if the status changed, or false if an error occurred.
|
||||
* @returns {Promise<Object>} returnObject - The object returned by the function.
|
||||
* @returns {Object} returnObject.monitor - The monitor object.
|
||||
* @returns {boolean} returnObject.statusChanged - Flag indicating if the status has changed.
|
||||
* @returns {boolean} returnObject.prevStatus - The previous status of the monitor
|
||||
*/
|
||||
updateStatus = async (networkResponse) => {
|
||||
|
||||
updateStatus = async (networkResponse: any) => {
|
||||
const check = this.buildCheck(networkResponse);
|
||||
await this.insertCheck(check);
|
||||
try {
|
||||
@@ -221,7 +219,7 @@ class StatusService {
|
||||
|
||||
if (statusChanged) {
|
||||
this.logger.info({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
message: `${monitor.name} went from ${this.getStatusString(prevStatus)} to ${this.getStatusString(newStatus)}`,
|
||||
prevStatus,
|
||||
newStatus,
|
||||
@@ -242,7 +240,7 @@ class StatusService {
|
||||
|
||||
if (lastManuallyResolvedIncident && lastManuallyResolvedIncident.endTime) {
|
||||
try {
|
||||
const checksAfterResolution = await Check.find({
|
||||
const checksAfterResolution = await CheckModel.find({
|
||||
monitorId: monitor.id,
|
||||
createdAt: { $gt: lastManuallyResolvedIncident.endTime },
|
||||
})
|
||||
@@ -258,9 +256,9 @@ class StatusService {
|
||||
} else {
|
||||
calculatedFailureRate = 0;
|
||||
}
|
||||
} catch (checkQueryError) {
|
||||
} catch (checkQueryError: any) {
|
||||
this.logger.error({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "updateStatus",
|
||||
message: `Failed to query checks after manual resolution: ${checkQueryError.message}`,
|
||||
monitorId: monitor.id,
|
||||
@@ -272,9 +270,9 @@ class StatusService {
|
||||
if (calculatedFailureRate >= monitor.statusWindowThreshold) {
|
||||
await this.handleIncidentForCheck(check, monitor, "create", "threshold check without status change");
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
this.logger.error({
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "updateStatus",
|
||||
message: `Error handling threshold check without status change: ${error.message}`,
|
||||
monitorId: monitor.id,
|
||||
@@ -293,27 +291,14 @@ class StatusService {
|
||||
code,
|
||||
timestamp: new Date().getTime(),
|
||||
};
|
||||
} catch (error) {
|
||||
error.service = this.SERVICE_NAME;
|
||||
} catch (error: any) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "updateStatus";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds a check object from the network response.
|
||||
*
|
||||
* @param {Object} networkResponse - The network response object.
|
||||
* @param {string} networkResponse.monitorId - The monitor ID.
|
||||
* @param {string} networkResponse.type - The type of the response.
|
||||
* @param {string} networkResponse.status - The status of the response.
|
||||
* @param {number} networkResponse.responseTime - The response time.
|
||||
* @param {number} networkResponse.code - The status code.
|
||||
* @param {string} networkResponse.message - The message.
|
||||
* @param {Object} networkResponse.payload - The payload of the response.
|
||||
* @returns {Object} The check object.
|
||||
*/
|
||||
buildCheck = (networkResponse) => {
|
||||
buildCheck = (networkResponse: any) => {
|
||||
const {
|
||||
monitorId,
|
||||
teamId,
|
||||
@@ -355,7 +340,7 @@ class StatusService {
|
||||
if (typeof payload === "undefined") {
|
||||
this.logger.warn({
|
||||
message: "Failed to build check",
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "buildCheck",
|
||||
details: "empty payload",
|
||||
});
|
||||
@@ -363,7 +348,7 @@ class StatusService {
|
||||
}
|
||||
const categories = payload?.lighthouseResult?.categories ?? {};
|
||||
const audits = payload?.lighthouseResult?.audits ?? {};
|
||||
const mapAudit = (audit) => {
|
||||
const mapAudit = (audit: any) => {
|
||||
if (!audit || typeof audit !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -416,22 +401,22 @@ class StatusService {
|
||||
* @param {Object} networkResponse.payload - The payload of the response.
|
||||
* @returns {Promise<void>} A promise that resolves when the check is inserted.
|
||||
*/
|
||||
insertCheck = async (check) => {
|
||||
insertCheck = async (check: any) => {
|
||||
try {
|
||||
if (typeof check === "undefined") {
|
||||
this.logger.warn({
|
||||
message: "Failed to build check",
|
||||
service: this.SERVICE_NAME,
|
||||
service: SERVICE_NAME,
|
||||
method: "insertCheck",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.buffer.addToBuffer({ check });
|
||||
return true;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: error.service || this.SERVICE_NAME,
|
||||
service: error.service || SERVICE_NAME,
|
||||
method: error.method || "insertCheck",
|
||||
details: error.details || `Error inserting check for monitor: ${check?.monitorId}`,
|
||||
stack: error.stack,
|
||||
@@ -2,7 +2,7 @@ import { describe, expect, it, jest } from "@jest/globals";
|
||||
import SuperSimpleQueueHelper from "../src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.ts";
|
||||
import type { Monitor } from "../src/types/monitor.ts";
|
||||
|
||||
const createLogger = () => ({ info: jest.fn(), error: jest.fn(), warn: jest.fn() });
|
||||
const createLogger = () => ({ info: jest.fn(), error: jest.fn(), warn: jest.fn(), debug: jest.fn() });
|
||||
|
||||
const createHelper = (overrides?: Partial<ConstructorParameters<typeof SuperSimpleQueueHelper>[0]>) => {
|
||||
const maintenanceWindowModule = {
|
||||
@@ -27,7 +27,7 @@ describe("SuperSimpleQueueHelper", () => {
|
||||
const job = helper.getMonitorJob();
|
||||
await job({ id: "m1", teamId: "team", interval: 60000 } as Monitor);
|
||||
expect(helper["networkService"].requestStatus).not.toHaveBeenCalled();
|
||||
expect(helper["logger"].info).toHaveBeenCalledWith(
|
||||
expect(helper["logger"].debug).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ message: expect.stringContaining("Monitor m1 is in maintenance window") })
|
||||
);
|
||||
spy.mockRestore();
|
||||
|
||||
Reference in new issue
Block a user