← Status boardMonitor setup guide

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

  1. Choose where config lives
    • Git + redeploy: edit data/monitors.json in this repo (good for stable public URLs).
    • Vercel only: set env var MONITORS_JSON to a single-line JSON array (good for secrets or URLs you do not want in git).
  2. Add one row per check — at minimum id, name, and url (see Field reference).
  3. Validate locally: npm run validate:monitors (checks JSON shape and required fields).
  4. Smoke-test: npm run dev → open / and confirm each row goes green (or adjust expectedStatus / method).
  5. Deploy — push to GitHub and let Vercel build; confirm / and /setup on production.

Two ways to configure monitors

A. File in the repo (default)

B. Environment variable MONITORS_JSON (Vercel / other hosts)


Field reference

FieldRequiredDescription
idYesStable unique string (e.g. my-app-api-health). Used as React key and in logs.
nameYesHuman label on the dashboard (e.g. My App · API (Fly)).
urlYesFull URL to probe, including path (e.g. https://api.example.com/api/v1/health).
methodNoGET or HEAD. Default GET. Use HEAD only if the server supports it (some CDNs or apps return 405 for HEAD).
expectedStatusNoArray of HTTP status codes counted as healthy. Default [200, 204]. For frontends behind redirects, you may add 301, 302, 307, 308.
timeoutMsNoAbort the request after this many milliseconds. Default 10000.
notesNoShown 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

StackWhat 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 healthPrefer a dedicated /health (or /api/v1/health) route that returns 200 without auth.
Background worker with no HTTPYou 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 APIIf 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):

ProductWhat is probed (high level)
Invest AIxingai-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-apphttps://www.xingai.app and /apps — marketing site (separate Vercel project from Invest AI).
Meal Coach AIxingai-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 rowMaps to
Frontend URLVercel deployment xingai-invest-ai.
/api/v1/health and /api/v2/health on FlyFastAPI app xingai-invest-ai-api.
/api/v1/search/hot on FlySQLite-backed hot list; written by market_cache_worker on the same Fly machine as the API.
/api/v1/health on *.vercel.appConfirms 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:

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

SymptomThings to try
405 on a monitorSwitch method from HEAD to GET, or probe a path that allows HEAD.
301 / 302 shown as downAdd those codes to expectedStatus, or set url to the final URL after redirects.
TimeoutIncrease timeoutMs (cold starts on Fly / serverless can be slow).
Works locally, fails on VercelConfirm 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 VercelSet CRON_SECRET in Vercel env; Cron sends Authorization: Bearer <CRON_SECRET>.
Deploy fails: Hobby cron limitVercel 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.

中文说明(快速对照)


Related files in this repo

FileRole
data/monitors.jsonDefault monitor list
data/monitors.example.jsonCopy-paste template with placeholders
data/monitors.schema.jsonJSON Schema for editors
src/lib/monitors.tsLoad order: MONITORS_JSON → file
src/lib/probe.tsHTTP probe implementation