@inso_web/els-mcp
Version:
MCP-сервер поверх INSO Error Logs Service. Read-only tools (search, analytics, fingerprinting, correlations) для подключения Claude Desktop/Code и ChatGPT к логам ошибок. Streamable HTTP transport + stdio для npx-запуска.
73 lines • 2.93 kB
JavaScript
import { Router } from 'express';
import os from 'node:os';
import { checkLiveness, checkReadiness, } from '../../observability/health.js';
export function createHealthRouter(opts = {}) {
const router = Router();
router.get('/health', insoHealthHandler()); // INSO Uptime contract
router.get('/healthz', livenessHandler()); // legacy
router.get('/ready', readinessHandler(opts)); // INSO Uptime contract
router.get('/readyz', readinessHandler(opts)); // legacy
return router;
}
function livenessHandler() {
return function handler(_req, res) {
const liv = checkLiveness();
res.status(200).json({ status: liv.status, uptimeSec: liv.uptimeSec, version: liv.version });
};
}
/**
* INSO Uptime contract — формат идентичный другим микросервисам платформы
* (см. error-logs-service/src/routes/health.routes.ts). LK health-monitor
* парсит поле `version` (`BUILD_VERSION` из CI build timestamp).
*/
function insoHealthHandler() {
return function handler(_req, res) {
const liv = checkLiveness();
res.status(200).json({
status: liv.status,
uptime: liv.uptimeSec,
hostname: os.hostname(),
version: process.env.BUILD_VERSION || liv.version,
});
};
}
function readinessHandler(opts) {
return async function handler(_req, res) {
// checks: { els: 'ok' | 'fail' | 'skip', redis: ... }
// Используем общий checkReadiness с тем же контрактом.
const checks = {};
let allOk = true;
if (opts.elsClient || opts.redis) {
const result = await checkReadiness({
...(opts.elsClient ? { elsClient: opts.elsClient } : {}),
...(opts.redis ? { redis: opts.redis } : {}),
...(opts.log ? { log: opts.log } : {}),
timeoutMs: 2000,
});
checks.els = opts.elsClient ? (result.checks.upstream.ok ? 'ok' : 'fail') : 'skip';
checks.redis = opts.redis ? (result.checks.redis.ok ? 'ok' : 'fail') : 'skip';
if (result.status !== 'ready')
allOk = false;
}
else {
checks.els = 'skip';
checks.redis = 'skip';
}
for (const probe of opts.probes ?? []) {
try {
await probe.check();
checks[probe.name] = 'ok';
}
catch (err) {
opts.log?.warn?.({ err: errMsg(err), probe: probe.name }, 'readyz: probe failed');
checks[probe.name] = 'fail';
allOk = false;
}
}
res.status(allOk ? 200 : 503).json({ status: allOk ? 'ok' : 'degraded', checks });
};
}
function errMsg(err) {
return err instanceof Error ? err.message : String(err);
}
//# sourceMappingURL=health.js.map