Published on

Sending OpenTelemetry Metrics to Prometheus

Sending OpenTelemetry Metrics to Prometheus

What is OpenTelemetry?

OpenTelemetry is an open source and vendor-neutral API for distributed traces (including logs and errors) and metrics. With OpenTelemetry, you can instrument your application once and then add or change OpenTelemetry-compatible backends without changing the instrumentation.

OpenTelemetry Metrics

OpenTelemetry specifies how to collect, aggregate, and send metrics to backend platforms. Using OpenTelemetry instruments, you can create counter, gauge, and histogram metrics.

The simplest Counter instrument looks like this:

import (
	"go.opentelemetry.io/otel/metric/global"
	"go.opentelemetry.io/otel/metric"
)

var meter = metric.Must(global.Meter("promtest"))

counter := meter.NewInt64Counter("test.my_counter",
	metric.WithDescription("Just a test counter"),
)

// Increment the counter.
counter.Add(ctx, 1)
counter.Add(ctx, 10)

Prometheus exporter

You can send OpenTelemetry metrics to Prometheus using OpenTelemetry exporter that provides a Prometheus target:

import (
	"go.opentelemetry.io/otel/exporters/prometheus"
	"go.opentelemetry.io/otel/metric/global"
	"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
	"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
	controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
	processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
	selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
)

func configureOpentelemetry() {
	exporter := configureMetrics()

	http.HandleFunc("/metrics", exporter.ServeHTTP)
	fmt.Println("listenening on http://localhost:8088/metrics")

	go func() {
		_ = http.ListenAndServe(":8088", nil)
	}()
}

func configureMetrics() *prometheus.Exporter {
	config := prometheus.Config{}

	ctrl := controller.New(
		processor.NewFactory(
			selector.NewWithHistogramDistribution(
				histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
			),
			export.CumulativeExportKindSelector(),
			processor.WithMemory(true),
		),
	)

	exporter, err := prometheus.New(config, ctrl)
	if err != nil {
		panic(err)
	}

	global.SetMeterProvider(exporter.MeterProvider())

	return exporter
}

Prometheus target is available at http://localhost:8088/metrics and can be scraped by Prometheus with the following config:

scrape_configs:
  - job_name: 'opentelemetry'
    static_configs:
      - targets: ['localhost:8088']

You can find a runnable example at GitHub.