@@ -27,60 +27,104 @@ from apiforgepy import ApiForgeMiddleware
2727
2828app = FastAPI()
2929
30- app.add_middleware(
31- ApiForgeMiddleware,
32- mode = " local" ,
33- )
30+ app.add_middleware(ApiForgeMiddleware)
3431
3532@app.get (" /users/{user_id} " )
3633def get_user (user_id : int ):
3734 return {" id" : user_id}
3835
39- # Dashboard → http://localhost:4242
36+ # Dashboard auto-starts at http://localhost:4242
4037```
4138
39+ ## Dashboard
40+
41+ Open ** http://localhost:4242 ** after starting your app. No configuration needed — the dashboard server starts automatically in the background.
42+
43+ - ** Health Score** (0–100) — global API health at a glance
44+ - ** Latency percentiles** — P50 / P90 / P99 per route
45+ - ** Error rates** — 4xx and 5xx breakdown
46+ - ** Automatic insights** — latency anomalies, dead endpoints, release regressions
47+ - ** Time series chart** — click any route to see its latency over time
48+
49+ Data is stored locally in ` .apiforge.db ` (SQLite). Nothing leaves your machine.
50+
4251## Configuration
4352
4453``` python
4554app.add_middleware(
4655 ApiForgeMiddleware,
47- mode = " local" ,
4856 db_path = " .apiforge.db" ,
49- dashboard_port = 4242 , # set to 0 to disable
50- flush_interval = 60_000 , # ms
57+ dashboard_port = 4242 , # set to 0 to disable
58+ flush_interval = 60_000 , # aggregate and flush every 60s (ms)
5159 env = " production" ,
52- release = " v1.4.0" , # enables release regression detection
60+ release = " v1.4.0" , # enables release regression detection
5361 service = " user-service" ,
54- sampling = 1.0 , # 0.0–1.0
62+ sampling = 1.0 , # 0.0–1.0 sample rate
5563 ignore_paths = [" /health" , " /favicon.ico" ],
5664)
5765```
5866
67+ ## Cloud mode
68+
69+ Send metrics to the APIForge SaaS platform instead of storing them locally:
70+
71+ ``` python
72+ app.add_middleware(
73+ ApiForgeMiddleware,
74+ cloud_url = os.environ[" APIFORGE_CLOUD_URL" ],
75+ api_key = os.environ[" APIFORGE_API_KEY" ],
76+ service = " user-service" ,
77+ env = " production" ,
78+ release = os.environ.get(" APP_VERSION" ),
79+ )
80+ ```
81+
82+ In cloud mode, metrics are aggregated in memory for 60 seconds and sent as a single batch — the local dashboard and SQLite database are not used.
83+
84+ ## Release tracking
85+
86+ Pass your release version to enable before/after deployment comparison:
87+
88+ ``` python
89+ import os
90+ app.add_middleware(ApiForgeMiddleware, release = os.environ.get(" APP_VERSION" ))
91+ ```
92+
93+ When a new release is detected, APIForge compares P90 latency before and after and surfaces regressions automatically.
94+
5995## What you get
6096
61- - ** Latency percentiles** — P50 / P90 / P99 per endpoint, updated every 60s
62- - ** Error rate by route** — 2xx / 4xx / 5xx breakdown in real time
63- - ** API Health Score** — a single 0–100 score summarizing your API's health
64- - ** Automatic insights** — plain-language alerts with no configuration
65- - ** Dead endpoint detection** — routes with no traffic in 21+ days
66- - ** Release impact tracking** — before/after comparison on every deploy
97+ - ** Per-route latency** — P50, P90, P99 per endpoint, updated every 60 s
98+ - ** Error rate by route** — 2xx / 3xx / 4xx / 5xx breakdown
99+ - ** API Health Score** — a single 0–100 score summarising your API's health
100+ - ** Ghost route detection** — requests that match no declared Starlette/FastAPI route
101+ - ** Latency anomaly alerts** — Z-score detection against a 7-day baseline
102+ - ** Dead endpoint detection** — routes with no traffic for 21+ days
103+ - ** Release regression analysis** — automatic P90 comparison per deploy
104+ - ** Progressive drift detection** — slow latency increases over weeks
105+ - ** Untracked route detection** — declared routes that never received traffic
106+ - ** Inflight concurrency tracking** — ` inflight_avg ` and ` inflight_max ` per route
67107
68108## Graceful shutdown
69109
110+ Cleanup (flush buffer, close dashboard, close SQLite) happens automatically via ` atexit ` . For explicit control in long-running processes:
111+
70112``` python
71- import signal
113+ from contextlib import asynccontextmanager
114+ from fastapi import FastAPI
115+ from apiforgepy import ApiForgeMiddleware
72116
73- mw = None
117+ forge = None
74118
75119@asynccontextmanager
76120async def lifespan (app ):
77121 yield
78- if mw :
79- mw .shutdown()
122+ if forge :
123+ forge .shutdown()
80124
81125app = FastAPI(lifespan = lifespan)
82- mw = ApiForgeMiddleware. __new__ (ApiForgeMiddleware)
83- app.add_middleware(ApiForgeMiddleware, mode = " local " )
126+ forge = ApiForgeMiddleware(app) # store reference before adding
127+ app.add_middleware(ApiForgeMiddleware)
84128```
85129
86130## Privacy by design
0 commit comments