diff --git a/src/config.ts b/src/config.ts index ce2cdc5..eac226b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -28,7 +28,8 @@ const configSchema = z.object({ name: z.string(), interval: z.number().default(60), notifyInterval: z.number().default(300), - alertEndpoints: z.array(z.string()) + alertEndpoints: z.array(z.string()), + retries: z.number().int().min(0).default(1) }).and(z.union([ z.object({ type: z.literal("fetch"), diff --git a/src/handler.ts b/src/handler.ts index 8605d86..079af14 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -8,20 +8,28 @@ type EndpointState = State extends Map ? L : never export const handleDown = (endpointState: EndpointState, curTime: number, endpoint: Config["pollEndpoints"][number]) => { const prevDown = endpointState.isDown endpointState.isDown = true + + endpointState.attemptsFailed++ + console.log(`Endpoint ${endpoint.name} has failed ${endpointState.attemptsFailed} times`) + if (!prevDown) endpointState.downStart = curTime if (curTime - endpointState.lastDownAlert < (endpoint.notifyInterval) * 1000) return - const message = prevDown ? + + if (endpointState.attemptsFailed > endpoint.retries) { + const message = prevDown ? `[${formatTS(curTime)}] ${endpoint.name} is still down and initially went down at ${formatTS(endpointState.downStart)}` : `[${formatTS(curTime)}] ${endpoint.name} went down` - notify(message, endpoint) - endpointState.lastDownAlert = curTime + notify(message, endpoint) + endpointState.lastDownAlert = curTime + } } export const handleUp = (endpointState: EndpointState, curTime: number, endpoint: Config["pollEndpoints"][number]) => { if (endpointState.isDown) { endpointState.isDown = false + endpointState.attemptsFailed = 0 const message = `[${formatTS(curTime)}] ${endpoint.name} is back up` notify(message, endpoint) } diff --git a/src/index.ts b/src/index.ts index 6cacbfb..033e4e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,13 +9,14 @@ let state = new Map(config.pollEndpoints.map(x => [x.name, { lastExec: 0, downStart: 0, lastDownAlert: 0, + attemptsFailed: 0, isDown: false }])) export type State = typeof state const isEndpointUp = async (endpoint: Config["pollEndpoints"][number]) => { if (endpoint.type === "fetch" ) { - const r = await fetch(endpoint.url, {method: "GET"}) + const r = await fetch(endpoint.url, {method: "GET"}).catch(e => ({ok: false})) return r.ok } else if (endpoint.type === "tcp-ping" ) {