feat: add end-to-end observability (metrics, health, mobile RUM, dashboards, alerts)
Run Tests on Branches / Detect Changes (push) Successful in 10s
Run Tests on Branches / Backend Tests (push) Failing after 20s
Run Tests on Branches / Frontend Tests (push) Has been skipped
Run Tests on Branches / Frontend Mobile Tests (push) Failing after 20s

- Backend: OTel metrics via OTLP -> Alloy -> Prometheus (OTEL_METRICS_EXPORTER=otlp)
- New business metrics (src/metrics.js): searches, CIMA latency/errors, cache
  hits/misses, logins, rate-limits, pharmacy writes/links, push sent/failed,
  DB + Redis timings/errors, HTTP req count/duration, heartbeat
- Backend health endpoints /healthz and /readyz
- Mobile (Expo): Grafana Faro RUM via @grafana/faro-react-native
- redis/postgres exporters in docker-compose + Prometheus scrape jobs
- Grafana dashboards (backend, datastores, mobile RUM, overview)
- Prometheus alert rules (farmafinder_*) -> existing Alertmanager (Telegram)
- Design/spec saved to docs/superpowers/specs/
This commit is contained in:
Antoni Nuñez Romeu
2026-07-13 15:57:52 +02:00
parent 2713be85a3
commit 839c64c12a
16 changed files with 907 additions and 27 deletions
+36
View File
@@ -0,0 +1,36 @@
import { initializeFaro } from '@grafana/faro-react-native';
let initialized = false;
/**
* Initializes Grafana Faro RUM for the React Native app.
*
* Telemetry (crashes, JS errors, console, app-start, memory/ANR vitals,
* session + screen tracking) is sent OTLP/HTTP to the Alloy collector.
*
* NOTE: `@grafana/faro-react-native` ships a native module, so it requires a
* custom dev build / EAS build (not Expo Go). Initialization is wrapped in a
* try/catch so a collector outage never crashes the app.
*/
export function initFaro(): void {
if (initialized) return;
initialized = true;
try {
const url =
process.env.EXPO_PUBLIC_FARO_URL || 'http://grafana.hacecalor.net:4318';
initializeFaro({
app: {
name: 'farmafinder-mobile',
version: '1.0.0',
environment: __DEV__ ? 'development' : 'production',
},
url,
sessionTracking: { enabled: true },
// Crash/JS error/console capture are on by default.
});
} catch (err) {
console.warn('[faro] initialization failed:', err);
}
}