OxiPulse speaks OTLP. Grafana can query Prometheus. The bridge between them is the OpenTelemetry Collector — a vendor-neutral pipeline that receives OTLP data and exports it to any backend. This guide walks through a complete self-hosted setup.
Architecture
OxiPulse agent → OTel Collector (OTLP receiver)
↓
Prometheus remote write
↓
Prometheus
↓
GrafanaPrerequisites
- A Linux server to run the collector and Prometheus (can be the same host)
- Docker and Docker Compose
- OxiPulse installed on the machine(s) you want to monitor
1. Docker Compose stack
Create a docker-compose.yml:
services:
otelcol:
image: otel/opentelemetry-collector-contrib:latest
ports:
- "4317:4317" # OTLP gRPC
volumes:
- ./otelcol.yaml:/etc/otelcol-contrib/config.yaml
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=changeme
volumes:
- grafana_data:/var/lib/grafana
volumes:
prometheus_data:
grafana_data:2. OpenTelemetry Collector config
Create otelcol.yaml:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
exporters:
prometheusremotewrite:
endpoint: "http://prometheus:9090/api/v1/write"
service:
pipelines:
metrics:
receivers: [otlp]
exporters: [prometheusremotewrite]3. Prometheus config
Create prometheus.yml:
global:
scrape_interval: 15s
storage:
tsdb:
retention.time: 30dEnable remote write receiver by adding --web.enable-remote-write-receiver to the Prometheus
command args, or use the command key in Docker Compose:
prometheus:
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--web.enable-remote-write-receiver"4. Start the stack
docker compose up -d5. Point OxiPulse at the collector
Edit /etc/oxipulse/config.toml on each monitored server:
endpoint = "http://YOUR_COLLECTOR_IP:4317"
token = "YOUR_TOKEN"sudo systemctl restart oxipulse6. Build a Grafana dashboard
Open Grafana at http://localhost:3000, add Prometheus as a data source
(http://prometheus:9090), and create panels with these queries:
| Panel | PromQL |
|---|---|
| CPU % | system_cpu_usage |
| RAM used % | system_memory_used / system_memory_total * 100 |
| Disk used % | system_disk_used / system_disk_total * 100 |
| Network in | rate(system_network_received_total[5m]) |
| Network out | rate(system_network_transmitted_total[5m]) |
Filter by agent using the service_instance_id label, which OxiPulse sets to the agent's
unique identifier.
Using Grafana Cloud instead
If you prefer a managed backend, Grafana Cloud provides an OTLP endpoint you can point OxiPulse
at directly — no collector or Prometheus required. Replace the endpoint in config.toml with
your Grafana Cloud OTLP URL and set the token to your Grafana Cloud API key.