UNPKG

@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
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