fix(otel): lazy-init metrics and fix Grafana dashboards
Run Tests on Branches / Detect Changes (push) Successful in 14s
Run Tests on Branches / Backend Tests (push) Successful in 4m3s
Run Tests on Branches / Frontend Tests (push) Has been skipped
Run Tests on Branches / Frontend Mobile Tests (push) Has been skipped
Run Tests on Branches / Parapharmacy API Tests (push) Has been skipped
Run Tests on Branches / PIP Platform Tests (push) Has been skipped

- Fix OTel custom metrics not reaching Prometheus: ESM static import
  hoisting caused metrics.getMeter() to run before sdk.start(), getting
  NoopMeterProvider. Changed to lazy-init pattern so instruments are
  created on first use after the SDK configures the real MeterProvider.

- Fix Grafana dashboards job labels: OTel adds service.namespace prefix
  (job=farmafinder/farmafinder-backend), updated queries to use regex
  match (job=~".*farmafinder-backend").

- Fix histogram metric names: OTel appends unit suffix (_milliseconds)
  to histogram names (e.g. http_request_duration_ms_milliseconds_bucket).

Verified: app_heartbeat_total, http_requests_total, db_query_duration_ms,
redis_cmd_duration_ms, and all other custom metrics now flow correctly
through OTLP -> Alloy -> Prometheus remote_write.
This commit is contained in:
Antoni Nuñez Romeu
2026-07-21 13:18:18 +02:00
parent 159e14bed8
commit f32ff701e1
3 changed files with 87 additions and 48 deletions
@@ -11,20 +11,20 @@
"id": 1, "title": "Backend req/s", "type": "stat",
"gridPos": { "h": 5, "w": 6, "x": 0, "y": 0 },
"datasource": { "type": "prometheus", "uid": "PBFA97CFB590B2093" },
"targets": [ { "expr": "sum(rate(http_requests_total{job=\"farmafinder-backend\"}[5m]))", "legendFormat": "req/s" } ]
"targets": [ { "expr": "sum(rate(http_requests_total{job=~\".*farmafinder-backend\"}[5m]))", "legendFormat": "req/s" } ]
},
{
"id": 2, "title": "Backend 5xx ratio", "type": "stat",
"gridPos": { "h": 5, "w": 6, "x": 6, "y": 0 },
"datasource": { "type": "prometheus", "uid": "PBFA97CFB590B2093" },
"targets": [ { "expr": "sum(rate(http_requests_total{status_class=\"5xx\",job=\"farmafinder-backend\"}[5m])) / sum(rate(http_requests_total{job=\"farmafinder-backend\"}[5m]))", "legendFormat": "5xx" } ],
"targets": [ { "expr": "sum(rate(http_requests_total{status_class=\"5xx\",job=~\".*farmafinder-backend\"}[5m])) / sum(rate(http_requests_total{job=~\".*farmafinder-backend\"}[5m]))", "legendFormat": "5xx" } ],
"fieldConfig": { "defaults": { "unit": "percentunit", "thresholds": { "steps": [ { "color": "green", "value": 0 }, { "color": "yellow", "value": 0.01 }, { "color": "red", "value": 0.05 } ] } } }
},
{
"id": 3, "title": "CIMA errors/s", "type": "stat",
"gridPos": { "h": 5, "w": 6, "x": 12, "y": 0 },
"datasource": { "type": "prometheus", "uid": "PBFA97CFB590B2093" },
"targets": [ { "expr": "sum(rate(cima_requests_total{status=\"error\",job=\"farmafinder-backend\"}[5m]))", "legendFormat": "cima err/s" } ]
"targets": [ { "expr": "sum(rate(cima_requests_total{status=\"error\",job=~\".*farmafinder-backend\"}[5m]))", "legendFormat": "cima err/s" } ]
},
{
"id": 4, "title": "Mobile events/s", "type": "stat",
@@ -59,6 +59,6 @@
"timezone": "browser",
"title": "FarmaFinder — Overview",
"uid": "farmafinder-overview",
"version": 1,
"version": 2,
"weekStart": ""
}