Skip to content

Monitoring & Metrics

Set these environment variables and restart your services. Metrics and logs will flow to Grafana automatically.

Terminal window
# Grafana Cloud
GRAFANA_LOKI_URL=https://logs-prod-xxx.grafana.net
GRAFANA_LOKI_TOKEN=glc_xxx
GRAFANA_PROMETHEUS_URL=https://prometheus-prod-xxx.grafana.net/api/prom
GRAFANA_PROMETHEUS_TOKEN=glc_xxx
# Self-hosted (basic auth instead of bearer token)
GRAFANA_LOKI_USERNAME=your-username
GRAFANA_LOKI_PASSWORD=your-password

See Grafana Setup for a step-by-step walkthrough.

  • http_requests_total — request count by path, method, and status
  • http_request_duration_ms — duration histogram (P50/P95/P99 available)
  • errors_total — error count by service

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 serving
Terminal window
GRAFANA_LOKI_URL # Loki push endpoint
GRAFANA_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 flush
GRAFANA_FLUSH_INTERVAL=5000 # Flush interval in ms
# Average response time by endpoint
avg by (path) (
rate(http_request_duration_ms_sum[5m]) /
rate(http_request_duration_ms_count[5m])
)
# Request rate by service
sum(rate(http_requests_total[1m])) by (service)
# Error rate
sum(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,}"

Metrics and logs are always stored in-memory. Access them directly:

  • http://localhost:8000/api/observability/logs
  • http://localhost:8000/api/observability/metrics
  • http://localhost:8000/api/observability/errors
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
})