Monitoring & Metrics
Set these environment variables and restart your services. Metrics and logs will flow to Grafana automatically.
# Grafana CloudGRAFANA_LOKI_URL=https://logs-prod-xxx.grafana.netGRAFANA_LOKI_TOKEN=glc_xxx
GRAFANA_PROMETHEUS_URL=https://prometheus-prod-xxx.grafana.net/api/promGRAFANA_PROMETHEUS_TOKEN=glc_xxx
# Self-hosted (basic auth instead of bearer token)GRAFANA_LOKI_USERNAME=your-usernameGRAFANA_LOKI_PASSWORD=your-passwordSee Grafana Setup for a step-by-step walkthrough.
Metrics
Section titled “Metrics”http_requests_total— request count by path, method, and statushttp_request_duration_ms— duration histogram (P50/P95/P99 available)errors_total— error count by service
Log Labels
Section titled “Log Labels”Logs are tagged by service so you can filter them in Loki:
{job="main-app"} # OAuth, uploads, domain management{job="hosting-service"} # Firehose, caching, content servingAll Options
Section titled “All Options”GRAFANA_LOKI_URL # Loki push endpointGRAFANA_PROMETHEUS_URL # Prometheus remote write endpoint
GRAFANA_LOKI_TOKEN # Bearer token (Grafana Cloud)GRAFANA_LOKI_USERNAME # Basic auth (self-hosted)GRAFANA_LOKI_PASSWORD
GRAFANA_BATCH_SIZE=100 # Entries per flushGRAFANA_FLUSH_INTERVAL=5000 # Flush interval in msDashboard Queries
Section titled “Dashboard Queries”# Average response time by endpointavg by (path) ( rate(http_request_duration_ms_sum[5m]) / rate(http_request_duration_ms_count[5m]))
# Request rate by servicesum(rate(http_requests_total[1m])) by (service)
# Error ratesum(rate(errors_total[5m])) by (service) /sum(rate(http_requests_total[5m])) by (service){job="main-app"} |= "error" | json{job="hosting-service"} |~ "duration.*[1-9][0-9]{3,}"Without Grafana
Section titled “Without Grafana”Metrics and logs are always stored in-memory. Access them directly:
http://localhost:8000/api/observability/logshttp://localhost:8000/api/observability/metricshttp://localhost:8000/api/observability/errors
Programmatic Setup
Section titled “Programmatic Setup”import { initializeGrafanaExporters } from '@wisp/observability'
initializeGrafanaExporters({ lokiUrl: 'https://logs.grafana.net', lokiAuth: { bearerToken: 'token' }, prometheusUrl: 'https://prometheus.grafana.net/api/prom', prometheusAuth: { bearerToken: 'token' }, serviceName: 'my-service', batchSize: 100, flushIntervalMs: 5000})