OVS Exporter

OTel-native Prometheus exporter for Open vSwitch (OVS).
Listens on port 10054 by default. Scrapes data from ovsdb (via libovsdb) and ovs-vswitchd (via the unixctl socket), exposes metrics at /metrics, and can additionally push metrics, traces, and logs to an OTLP endpoint.
If this project is useful to you, a star on the repo would be appreciated.
Quick start
Docker (mount the OVS sockets read-only):
docker run --rm -p 10054:10054 \
-v /var/run/openvswitch:/var/run/openvswitch:ro \
ghcr.io/barnes-c/ovs-exporter:latest
Binary:
make build
./ovs-exporter --ovs.db-socket=unix:/var/run/openvswitch/db.sock
Scrape: curl localhost:10054/metrics. Probes: /healthz, /readyz.
See examples/ for systemd, Kubernetes DaemonSet + ServiceMonitor, and OTel Collector configs.
Configuration
Key flags (full list via --help):
| Flag |
Default |
Purpose |
--web.listen-address |
:10054 |
Listen address |
--web.telemetry-path |
/metrics |
Prometheus endpoint |
--web.prometheus |
true |
Disable for OTLP-push-only deployments |
--ovs.db-socket |
unix:/var/run/openvswitch/db.sock |
libovsdb endpoint |
--ovs.run-dir |
/var/run/openvswitch |
unixctl socket directory |
--cache.ttl |
60s |
unixctl scrape interval |
OTel pipeline
The OTel pipeline is entirely environment-driven; see the OTel SDK env var spec for the full list. /metrics is always served unless --web.prometheus=false.
| Variable |
Purpose |
OTEL_METRICS_EXPORTER |
Comma-separated push exporters: otlp, console, none (default none) |
OTEL_TRACES_EXPORTER |
Traces exporter: otlp, console, none (default none) |
OTEL_LOGS_EXPORTER |
Logs exporter: otlp, console, none (default none) |
OTEL_EXPORTER_OTLP_ENDPOINT |
Collector endpoint, e.g. localhost:4317 |
OTEL_EXPORTER_OTLP_PROTOCOL |
grpc or http/protobuf |
OTEL_METRIC_EXPORT_INTERVAL |
OTLP metric push interval, in ms |
OTEL_TRACES_SAMPLER |
e.g. parentbased_traceidratio |
OTEL_TRACES_SAMPLER_ARG |
Sampler argument (e.g. 0.1) |
OTEL_SERVICE_NAME |
Resource service.name (default ovs-exporter) |
OTEL_CONFIG_FILE |
Path to otelconf YAML; overrides all other OTEL_* vars |
The three exporter selectors default to none instead of the spec default otlp. The OTel exporters stays silent until OTLP is opted in.
Traces cover the scrape pipeline (ovsdb, unixctl-ovs, HTTP handler). Logs are emitted via the OTel logs SDK when an exporter is set.
Metrics
All instruments use the OTel-spec naming convention (ovs.<area>.<name>).
| Metric |
Type |
Source |
ovs.bridge.ports.count |
gauge |
ovsdb |
ovs.bridges.count |
gauge |
ovsdb |
ovs.coverage.events |
counter |
unixctl |
ovs.datapath.cache.hit |
counter |
unixctl |
ovs.datapath.flows |
gauge |
unixctl |
ovs.datapath.interface.info |
gauge |
unixctl |
ovs.datapath.lookups |
counter |
unixctl |
ovs.datapath.masks.hit |
counter |
unixctl |
ovs.interface.{errors,drops,collisions} |
counter |
ovsdb |
ovs.interface.{rx,tx}.{bytes,packets} |
counter |
ovsdb |
ovs.interface.admin_state |
gauge |
ovsdb |
ovs.interface.external_ids |
gauge |
ovsdb |
ovs.interface.if_index |
gauge |
ovsdb |
ovs.interface.info |
gauge |
ovsdb |
ovs.interface.ingress_policing.{rate,burst,kpkts_rate,kpkts_burst} |
gauge |
ovsdb |
ovs.interface.link_speed |
gauge |
ovsdb |
ovs.interface.link_state |
gauge |
ovsdb |
ovs.interface.mtu |
gauge |
ovsdb |
ovs.interface.of_port |
gauge |
ovsdb |
ovs.interface.options |
gauge |
ovsdb |
ovs.interface.status |
gauge |
ovsdb |
ovs.memory.usage |
gauge |
unixctl |
ovs.ports.count |
gauge |
ovsdb |
ovs.upcall.dump.duration |
gauge |
unixctl |
ovs.upcall.flows.{current,max,limit} |
gauge |
unixctl |
ovs.upcall.handler.keys |
gauge |
unixctl |
See collector/ for the per-collector implementation.
Development
make all # fmt, vet, lint, build, test
make test # go test -race ./...
make test-integration # smoke stack + integration tests (podman/docker)
make snapshot # local goreleaser build
License
Apache-2.0