Monitoring setup guide
This guide helps you add or change uptime checks for any project (Next.js on Vercel, APIs on Fly.io, static sites, etc.). The running app reads data/monitors.json unless the MONITORS_JSON environment variable is set.
In the deployed app: open /setup for this same document (readable in the browser).
Five-minute checklist
- Choose where config lives
- Git + redeploy: edit
data/monitors.jsonin this repo (good for stable public URLs). - Vercel only: set env var
MONITORS_JSONto a single-line JSON array (good for secrets or URLs you do not want in git).
- Git + redeploy: edit
- Add one row per check — at minimum
id,name, andurl(see Field reference). - Validate locally:
npm run validate:monitors(checks JSON shape and required fields). - Smoke-test:
npm run dev→ open/and confirm each row goes green (or adjustexpectedStatus/method). - Deploy — push to GitHub and let Vercel build; confirm
/and/setupon production.
Two ways to configure monitors
A. File in the repo (default)
- Path:
data/monitors.json - Must be a JSON array of monitor objects.
- Optional: copy from
data/monitors.example.jsonas a template, then rename/replace URLs. - IDE hints: VS Code / Cursor can validate against
data/monitors.schema.json(see Editor integration).
B. Environment variable MONITORS_JSON (Vercel / other hosts)
- In the Vercel project → Settings → Environment Variables, add
MONITORS_JSON. - Value must be a valid JSON array (same shape as the file). Often pasted as one line to avoid newline issues.
- When
MONITORS_JSONis non-empty, the app ignoresdata/monitors.jsonfor that deployment.
Field reference
| Field | Required | Description |
|---|---|---|
id | Yes | Stable unique string (e.g. my-app-api-health). Used as React key and in logs. |
name | Yes | Human label on the dashboard (e.g. My App · API (Fly)). |
url | Yes | Full URL to probe, including path (e.g. https://api.example.com/api/v1/health). |
method | No | GET or HEAD. Default GET. Use HEAD only if the server supports it (some CDNs or apps return 405 for HEAD). |
expectedStatus | No | Array of HTTP status codes counted as healthy. Default [200, 204]. For frontends behind redirects, you may add 301, 302, 307, 308. |
timeoutMs | No | Abort the request after this many milliseconds. Default 10000. |
notes | No | Shown under the URL on the dashboard — use for what this row represents (e.g. “same Fly machine as worker”, “SQLite read path”). |
Probe behavior: the checker uses fetch with redirect: "follow" and a small User-Agent string. It does not parse JSON bodies; health is determined by HTTP status (and absence of network errors).
Choosing URLs for common stacks
| Stack | What to probe |
|---|---|
| Next.js / static frontend (Vercel, etc.) | Production site root or / on your real domain. If you see redirects, widen expectedStatus or probe the final URL directly. |
| REST / FastAPI health | Prefer a dedicated /health (or /api/v1/health) route that returns 200 without auth. |
| Background worker with no HTTP | You cannot hit the worker directly. Options: (1) probe an API route that reads worker-written data (e.g. a cache catalog), or (2) accept that machine-level health is implied by the API + same host docs. |
| SQLite / file DB on same host as API | If the API reads that DB on a specific route, probing that route (200) shows API + volume readable; it does not guarantee the worker wrote fresh data unless you define a stricter contract later. |
Default sample: three products (today)
The checked-in data/monitors.json is a multi-app smoke set aligned with xingai-invest-ai/docs/deploy/release-runbook.md (Vercel project list + Fly backend):
| Product | What is probed (high level) |
|---|---|
| Invest AI | xingai-invest-ai.vercel.app (frontend); Fly xingai-invest-ai-api.fly.dev — /api/v1/health, /api/v2/health, /api/v1/search/hot; plus /api/v1/health via the Vercel host (same path browsers use when API is rewritten). |
| xingai-dot-app | https://www.xingai.app and /apps — marketing site (separate Vercel project from Invest AI). |
| Meal Coach AI | xingai-meal-coach-ai.vercel.app / and /plan. The meal decision API is POST-only (/api/meal-decision), so it is not probed with GET here. |
Edit or delete rows if you only want one product, or point URLs at staging.
Invest AI (detail)
| Monitor row | Maps to |
|---|---|
| Frontend URL | Vercel deployment xingai-invest-ai. |
/api/v1/health and /api/v2/health on Fly | FastAPI app xingai-invest-ai-api. |
/api/v1/search/hot on Fly | SQLite-backed hot list; written by market_cache_worker on the same Fly machine as the API. |
/api/v1/health on *.vercel.app | Confirms the Invest AI Next.js host can reach the backend through configured rewrites. |
Duplicate or edit rows if your canonical frontend URL is not the default Vercel preview hostname.
Validate before deploy
npm run validate:monitors
This runs a small Node script that:
- Parses
data/monitors.json - Ensures each entry has
id,name,url(non-empty strings) - Checks optional fields have sensible types
It does not perform live HTTP checks (use the dashboard for that).
Editor integration (JSON Schema)
In VS Code / Cursor, add (or merge) into .vscode/settings.json:
{
"json.schemas": [
{
"fileMatch": ["data/monitors.json", "data/monitors.example.json"],
"url": "./data/monitors.schema.json"
}
]
}
This repository includes .vscode/settings.json with that rule preconfigured when you open the xingai-ops-status folder.
Troubleshooting
| Symptom | Things to try |
|---|---|
| 405 on a monitor | Switch method from HEAD to GET, or probe a path that allows HEAD. |
| 301 / 302 shown as down | Add those codes to expectedStatus, or set url to the final URL after redirects. |
| Timeout | Increase timeoutMs (cold starts on Fly / serverless can be slow). |
| Works locally, fails on Vercel | Confirm MONITORS_JSON is valid one-line JSON; confirm the probed host allows requests from Vercel egress (no IP allowlist blocking without Fly/Vercel IPs). |
/api/cron 401 on Vercel | Set CRON_SECRET in Vercel env; Cron sends Authorization: Bearer <CRON_SECRET>. |
| Deploy fails: Hobby cron limit | Vercel Hobby allows at most one Cron invocation per day. This repo’s vercel.json uses a daily schedule; for */10 * * * * style schedules upgrade to Pro or remove crons and trigger /api/cron from an external scheduler. |
中文说明(快速对照)
- 配置位置二选一: 仓库里的
data/monitors.json,或 Vercel 环境变量MONITORS_JSON(整段 JSON 数组,常写成一行)。 - 必填字段:
id、name、url;其余见上表。 - 本地校验: 执行
npm run validate:monitors。 - 看板与文档: 浏览器打开
/看状态,打开/setup阅读本指南。 - Worker 无独立 HTTP 时: 用「能读到 worker 写入数据」的 API URL 作为间接探活,并在
notes里写清楚含义。
Related files in this repo
| File | Role |
|---|---|
data/monitors.json | Default monitor list |
data/monitors.example.json | Copy-paste template with placeholders |
data/monitors.schema.json | JSON Schema for editors |
src/lib/monitors.ts | Load order: MONITORS_JSON → file |
src/lib/probe.ts | HTTP probe implementation |