quality / changes (push) Successful in 9s
quality / commitlint (push) Skipped
quality / docker-check (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / web (push) Successful in 1m4s
quality / api (push) Successful in 54s
CD / quality (push) Successful in 2m17s
CD / publish (push) Successful in 2m21s
Worker сам ходит на origin по Cron Trigger; CFDM кладёт цели в KV и забирает результаты без POST /probe. Co-authored-by: Cursor <cursoragent@cursor.com>
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import type { FastifyInstance } from "fastify";
|
|
import { healthStatusQuerySchema } from "@cfdm/shared";
|
|
import { getAppSettings, repos } from "@cfdm/db";
|
|
import * as healthCheckService from "../services/health-check-service.js";
|
|
import * as serviceConfigService from "../services/service-config-service.js";
|
|
import {
|
|
healthEngineFallbacksFromConfig,
|
|
} from "../services/health-check-scheduler.js";
|
|
import { mailboxFromSettings } from "../services/health/health-worker-deploy.js";
|
|
import { cronStaleAfterMs } from "../services/health/mailbox.js";
|
|
|
|
export async function healthCheckRoutes(app: FastifyInstance) {
|
|
app.get("/health-status", async (request) => {
|
|
const query = healthStatusQuerySchema.parse(request.query);
|
|
return healthCheckService.listStatus(
|
|
request.server.db,
|
|
query.scope,
|
|
query.ref_id,
|
|
);
|
|
});
|
|
|
|
app.post("/health-check/run", async (request) => {
|
|
const config = request.server.config;
|
|
const fallbacks = healthEngineFallbacksFromConfig(config);
|
|
const settings = getAppSettings(
|
|
request.server.db,
|
|
fallbacks,
|
|
);
|
|
const thresholds = {
|
|
degradedFailures: settings.healthDegradedFailures,
|
|
downFailures: settings.healthDownFailures,
|
|
latencyWarnMs: settings.healthLatencyWarnMs,
|
|
successRecoveries: settings.healthSuccessRecoveries,
|
|
};
|
|
const checked = await healthCheckService.runAllChecks(request.server.db, {
|
|
thresholds,
|
|
probeGapMs: config.healthProbeGapMs,
|
|
mailbox: mailboxFromSettings(request.server.db, request.server.cf, fallbacks),
|
|
staleAfterMs: cronStaleAfterMs(settings.healthCheckCron),
|
|
onStatusChange: async (target, prev, next) => {
|
|
try {
|
|
const label =
|
|
next === "up"
|
|
? "OK"
|
|
: next === "degraded"
|
|
? "Slow"
|
|
: next === "down"
|
|
? "Down"
|
|
: "—";
|
|
repos.insertNotificationLog(
|
|
request.server.db,
|
|
"ip_health",
|
|
target.scope,
|
|
target.ref_id,
|
|
`${target.hostname || target.ip}: ${label}`,
|
|
`IP ${target.ip}: ${prev ?? "—"} → ${label}`,
|
|
);
|
|
await serviceConfigService.reconcileDnsForTarget(
|
|
request.server.db,
|
|
request.server.cf,
|
|
target.scope,
|
|
target.ref_id,
|
|
);
|
|
} catch {
|
|
// best-effort
|
|
}
|
|
},
|
|
});
|
|
const monitors = await healthCheckService.runDomainMonitors(
|
|
request.server.db,
|
|
thresholds,
|
|
);
|
|
return { checked, monitors };
|
|
});
|
|
}
|