- Backend: Implement Prometheus metrics collection
- Add prometheus-client dependency
- Create metrics utility module with HTTP request tracking counters, histograms, gauges
- Implement MetricsMiddleware to track request latency, count, and active requests
- Add /metrics endpoint to expose metrics in Prometheus text format
- Normalize paths to prevent cardinality explosion (e.g., /api/{id} for UUIDs)
- Exclude /metrics and /health from detailed tracking
- Frontend: Add web vitals and API metrics collection
- Install web-vitals library (v4.0.0) for Core Web Vitals tracking
- Create metrics utility module for FCP, LCP, CLS, INP, TTFB collection
- Implement useTrackedFetch hook for automatic API call metrics (method, endpoint, status, duration)
- Initialize web vitals tracking in App component on mount
- Provide exportMetrics() for sending metrics to backend
- Testing:
- Add comprehensive backend metrics tests (9 tests, 100% coverage)
- Add comprehensive frontend metrics tests (10 tests)
- All tests passing
- Documentation:
- Expand Docs/Observability.md with complete APM section
- Include metrics reference, integration examples (Prometheus, Datadog, NewRelic)
- Add troubleshooting guide and best practices for cardinality management
- Update Tasks.md to mark APM task as complete
Metrics exposed:
- bangui_http_requests_total: HTTP request count by method, endpoint, status
- bangui_http_request_duration_seconds: Request latency histogram
- bangui_http_active_requests: Active request gauge
- Web Vitals: CLS, FCP, INP, LCP, TTFB with ratings
- API metrics: endpoint, method, status, duration, timestamp
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
92 lines
2.3 KiB
Markdown
92 lines
2.3 KiB
Markdown
## [MEDIUM] No Application Performance Monitoring (APM)
|
|
|
|
**Status: COMPLETED ✓**
|
|
|
|
**What was done:**
|
|
- Backend Prometheus metrics: `/metrics` endpoint exposes request count, latency, active requests
|
|
- Frontend web-vitals tracking: FCP, LCP, CLS, INP, TTFB collection
|
|
- API call metrics: automatic tracking of latency and error rates
|
|
- Complete documentation with examples and integration guides
|
|
|
|
**Implementation:**
|
|
- Backend: `app/utils/metrics.py`, `app/middleware/metrics.py`, `app/routers/metrics.py`
|
|
- Frontend: `src/utils/metrics.ts`, `src/hooks/useTrackedFetch.ts`
|
|
- Documentation: `Docs/Observability.md` (APM section)
|
|
|
|
**Metrics exposed:**
|
|
- `bangui_http_requests_total` - HTTP request count by method, endpoint, status
|
|
- `bangui_http_request_duration_seconds` - Request latency histogram
|
|
- `bangui_http_active_requests` - Current active requests gauge
|
|
- Web Vitals: CLS, FCP, INP, LCP, TTFB
|
|
- API call metrics: method, endpoint, status, duration
|
|
|
|
---
|
|
|
|
## [LOW] Frontend charts not memoized
|
|
|
|
**Where found**
|
|
|
|
- `frontend/src/components/TopCountriesPieChart.tsx`
|
|
- `frontend/src/components/TopCountriesBarChart.tsx`
|
|
|
|
**Why this is needed**
|
|
|
|
Charts re-render on every parent update, Recharts reprocesses 5000+ points.
|
|
|
|
**Goal**
|
|
|
|
Memoize chart components.
|
|
|
|
**What to do**
|
|
|
|
1. Wrap with `React.memo` with custom comparison
|
|
2. Ensure data objects are stable
|
|
|
|
**Possible traps and issues**
|
|
|
|
- Shallow comparison might not be enough
|
|
- Memoization has memory cost
|
|
|
|
**Docs changes needed**
|
|
|
|
- No documentation changes
|
|
|
|
**Doc references**
|
|
|
|
- `frontend/src/components/TopCountriesChart.tsx`
|
|
|
|
---
|
|
|
|
## [LOW] No request deduplication on frontend
|
|
|
|
**Where found**
|
|
|
|
- `frontend/src/hooks/useFetchData.ts` — each call launches new request
|
|
- User clicks "Refresh" twice → two identical requests
|
|
|
|
**Why this is needed**
|
|
|
|
Duplicates waste bandwidth, cause race conditions (response 2 arrives first, then response 1 overwrites with stale data).
|
|
|
|
**Goal**
|
|
|
|
Deduplicate identical in-flight requests.
|
|
|
|
**What to do**
|
|
|
|
1. Implement request cache
|
|
2. Clear cache entry when response received
|
|
3. Use in `useFetchData`
|
|
|
|
**Possible traps and issues**
|
|
|
|
- Cache must be cleared on data mutation
|
|
- Stale data in cache possible if not careful
|
|
|
|
**Docs changes needed**
|
|
|
|
- No documentation changes
|
|
|
|
**Doc references**
|
|
|
|
- `frontend/src/hooks/useFetchData.ts` |