feat(phase7): grow corpus, MCP write-tools+auth, /metrics observability
CI / typecheck + build (turbo) (push) Canceled after 0s
CI / typecheck + build (turbo) (push) Canceled after 0s
- content/: +5 real docs (caddy, bullmq, mcp-streamable-http, postgres-fts, cloudflare-525 writeup) across docs/writeups/notes. Reindexed: 9 docs, 17 chunks, 5 revisions (was 4 docs). - apps/mcp: add write-tools index_document/reindex_all/restore_revision (require x-webhook-secret) + queue_status (public). createMcpServer(authSecret?) threads the HTTP header; stdio keeps writes open (trusted local). - apps/api: GET /metrics (Prometheus text: uptime + queue job gauges). - Caddy: expose /metrics on wiki. domain -> :4020. Verified live: /metrics 200; MCP tools/list -> 10; index_document unauth -> error, auth -> enqueues + worker drains; typecheck green.
This commit is contained in:
+29
-1
@@ -6,7 +6,7 @@ import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
|
||||
import { db } from "@mcpedia/db";
|
||||
import { appRouter } from "./router";
|
||||
import type { Context } from "./trpc";
|
||||
import { enqueueIndexDoc, enqueueFullIndex } from "@mcpedia/queue";
|
||||
import { enqueueIndexDoc, enqueueFullIndex, getQueue, INDEX_QUEUE } from "@mcpedia/queue";
|
||||
import { WEBHOOK_SECRET } from "@mcpedia/config";
|
||||
|
||||
// Fail fast: never expose an open git-sync endpoint. If the operator hasn't
|
||||
@@ -22,6 +22,34 @@ const app = new Hono();
|
||||
// Health check (no auth — safe to expose).
|
||||
app.get("/health", (c) => c.json({ ok: true }));
|
||||
|
||||
// --- Phase 7: Prometheus metrics (public, safe to scrape) ---
|
||||
const startedAt = Date.now();
|
||||
app.get("/metrics", async (c) => {
|
||||
const queue = getQueue();
|
||||
const [waiting, active, completed, failed, delayed] = await Promise.all([
|
||||
queue.getWaitingCount(),
|
||||
queue.getActiveCount(),
|
||||
queue.getCompletedCount(),
|
||||
queue.getFailedCount(),
|
||||
queue.getDelayedCount(),
|
||||
]);
|
||||
const lines = [
|
||||
"# HELP mcpedia_uptime_seconds seconds since process start",
|
||||
"# TYPE mcpedia_uptime_seconds gauge",
|
||||
`mcpedia_uptime_seconds ${((Date.now() - startedAt) / 1000).toFixed(1)}`,
|
||||
`# HELP mcpedia_queue_jobs queue job counts for "${INDEX_QUEUE}"`,
|
||||
"# TYPE mcpedia_queue_jobs gauge",
|
||||
`mcpedia_queue_jobs{state="waiting"} ${waiting}`,
|
||||
`mcpedia_queue_jobs{state="active"} ${active}`,
|
||||
`mcpedia_queue_jobs{state="completed"} ${completed}`,
|
||||
`mcpedia_queue_jobs{state="failed"} ${failed}`,
|
||||
`mcpedia_queue_jobs{state="delayed"} ${delayed}`,
|
||||
];
|
||||
return c.text(lines.join("\n") + "\n", 200, {
|
||||
"Content-Type": "text/plain; version=0.0.4; charset=utf-8",
|
||||
});
|
||||
});
|
||||
|
||||
// Shared guard for the git-sync webhooks: require `x-webhook-secret` header to
|
||||
// match the configured secret. Reject anything else with 401.
|
||||
// Verify a git-provider webhook. Supports GitHub's native HMAC signature
|
||||
|
||||
Reference in New Issue
Block a user