|
| 1 | +/** |
| 2 | + * One-off: scrape Fireworks metrics for each configured deployment and print |
| 3 | + * the same health summary the admission gate would see. |
| 4 | + * |
| 5 | + * Usage: |
| 6 | + * bun run web/scripts/scrape-check.ts |
| 7 | + */ |
| 8 | + |
| 9 | +import { env } from '@codebuff/internal/env' |
| 10 | + |
| 11 | +import { computeSnapshot, DEFAULT_HEALTH_THRESHOLDS } from '@/server/fireworks-monitor/compute-health' |
| 12 | +import { scrapeFireworksMetrics } from '@/server/fireworks-monitor/monitor' |
| 13 | +import { FIREWORKS_ACCOUNT_ID, FIREWORKS_DEPLOYMENT_MAP } from '@/llm-api/fireworks-config' |
| 14 | + |
| 15 | +async function main() { |
| 16 | + const deployments = Object.values(FIREWORKS_DEPLOYMENT_MAP) |
| 17 | + const metrics = await scrapeFireworksMetrics({ |
| 18 | + apiKey: env.FIREWORKS_API_KEY, |
| 19 | + accountId: FIREWORKS_ACCOUNT_ID, |
| 20 | + }) |
| 21 | + const snapshot = computeSnapshot({ |
| 22 | + metrics, |
| 23 | + deployments, |
| 24 | + thresholds: DEFAULT_HEALTH_THRESHOLDS, |
| 25 | + }) |
| 26 | + |
| 27 | + console.log(`scrapedAt: ${new Date(snapshot.scrapedAt ?? 0).toISOString()}`) |
| 28 | + console.log(`overall: ${snapshot.overall}\n`) |
| 29 | + |
| 30 | + for (const [deployment, health] of Object.entries(snapshot.deployments)) { |
| 31 | + console.log(`── ${deployment} (${health.baseModel ?? 'unknown'})`) |
| 32 | + console.log(` status: ${health.status}`) |
| 33 | + console.log(` replicas: ${health.metrics.replicas}`) |
| 34 | + console.log(` req/s: ${health.metrics.requestRate.toFixed(2)}`) |
| 35 | + console.log(` errors: ${(health.metrics.errorFraction * 100).toFixed(2)}%`) |
| 36 | + console.log(` kvBlocks: ${(health.metrics.kvBlocksFraction * 100).toFixed(1)}%`) |
| 37 | + console.log(` kvSlots: ${(health.metrics.kvSlotsFraction * 100).toFixed(1)}%`) |
| 38 | + console.log(` concurrent: ${health.metrics.concurrentRequests.toFixed(1)}`) |
| 39 | + const q = health.metrics.p50GenerationQueueMs |
| 40 | + const t = health.metrics.p50TimeToFirstTokenMs |
| 41 | + console.log(` p50 queue: ${q === null ? 'n/a' : `${Math.round(q)}ms`}`) |
| 42 | + console.log(` p50 TTFT: ${t === null ? 'n/a' : `${Math.round(t)}ms`}`) |
| 43 | + if (health.reasons.length > 0) { |
| 44 | + console.log(` reasons:`) |
| 45 | + for (const r of health.reasons) console.log(` - ${r}`) |
| 46 | + } |
| 47 | + console.log() |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +void main().catch((error) => { |
| 52 | + console.error(error) |
| 53 | + process.exit(1) |
| 54 | +}) |
0 commit comments