prometheus

package module
v0.66.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 27, 2026 License: Apache-2.0, BSD-3-Clause Imports: 20 Imported by: 622

README

Prometheus Exporter

PkgGoDev

Documentation

Overview

Package prometheus provides a Prometheus Exporter that converts OTLP metrics into the Prometheus exposition format and implements prometheus.Collector to provide a handler for these metrics.

The Prometheus exporter ignores metrics from the Prometheus bridge. To export these metrics, simply register them directly with the Prometheus Handler.

Example
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/prometheus/client_golang/prometheus/promhttp"

	otelprom "go.opentelemetry.io/otel/exporters/prometheus"
	otelmetric "go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/sdk/metric"

	semconv "go.opentelemetry.io/otel/semconv/v1.41.0"
)

func main() {
	// Create a new Prometheus exporter. It automatically registers with the DefaultRegisterer.
	exporter, err := otelprom.New()
	if err != nil {
		log.Fatal(err)
	}

	// Register the exporter with a new MeterProvider.
	provider := metric.NewMeterProvider(metric.WithReader(exporter))
	meter := provider.Meter(
		"example-global",
		otelmetric.WithInstrumentationVersion("v1.0.0"),
		otelmetric.WithSchemaURL(semconv.SchemaURL),
	)

	// Create a counter instrument.
	counter, err := meter.Float64Counter("bar", otelmetric.WithDescription("a simple counter"))
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	counter.Add(ctx, 10)

	// Serve metrics using promhttp.Handler().
	// In production, you would use http.ListenAndServe(":8080", promhttp.Handler()).
	// For this testable example, we use httptest.NewServer.
	server := httptest.NewServer(promhttp.Handler())
	defer server.Close()

	// Make an HTTP request to the endpoint.
	resp, err := http.Get(server.URL) //nolint:noctx
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	// The response contains all metrics registered with the default registry,
	// including Go runtime metrics. To make this example testable and deterministic,
	// we filter the output for lines containing our metric name.
	lines := strings.SplitSeq(string(body), "\n")
	for line := range lines {
		if strings.Contains(line, "bar") {
			fmt.Println(line)
		}
	}

}
Output:
# HELP bar_total a simple counter
# TYPE bar_total counter
bar_total{otel_scope_name="example-global",otel_scope_schema_url="https://opentelemetry.io/schemas/1.41.0",otel_scope_version="v1.0.0"} 10
Example (CustomRegistry)
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"

	otelprom "go.opentelemetry.io/otel/exporters/prometheus"
	otelmetric "go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/sdk/metric"

	semconv "go.opentelemetry.io/otel/semconv/v1.41.0"
)

func main() {
	// Create a custom Prometheus registry. This is often used to avoid global state.
	reg := prometheus.NewRegistry()

	// Create a new Prometheus exporter using the custom registry.
	exporter, err := otelprom.New(otelprom.WithRegisterer(reg))
	if err != nil {
		log.Fatal(err)
	}

	// Register the exporter with a new MeterProvider.
	provider := metric.NewMeterProvider(metric.WithReader(exporter))
	meter := provider.Meter(
		"example-custom",
		otelmetric.WithInstrumentationVersion("v1.0.0"),
		otelmetric.WithSchemaURL(semconv.SchemaURL),
	)

	// Create a counter instrument.
	counter, err := meter.Float64Counter("foo", otelmetric.WithDescription("another counter"))
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	counter.Add(ctx, 5)

	// Serve metrics using promhttp.HandlerFor.
	server := httptest.NewServer(promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
	defer server.Close()

	// Make an HTTP request to the endpoint.
	resp, err := http.Get(server.URL) //nolint:noctx
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	// Filter the output for lines containing our metric name.
	lines := strings.SplitSeq(string(body), "\n")
	for line := range lines {
		if strings.Contains(line, "foo") {
			fmt.Println(line)
		}
	}

}
Output:
# HELP foo_total another counter
# TYPE foo_total counter
foo_total{otel_scope_name="example-custom",otel_scope_schema_url="https://opentelemetry.io/schemas/1.41.0",otel_scope_version="v1.0.0"} 5
Example (NoTranslation)
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/model"
	"github.com/prometheus/otlptranslator"

	otelprom "go.opentelemetry.io/otel/exporters/prometheus"
	otelmetric "go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/sdk/metric"

	semconv "go.opentelemetry.io/otel/semconv/v1.41.0"
)

func main() {
	// Set NameEscapingScheme to NoEscaping to prevent the prometheus client from escaping to underscores.
	model.NameEscapingScheme = model.NoEscaping

	// Create a new Prometheus exporter using NoTranslation strategy.
	// This keeps the original OpenTelemetry metric names.
	// It uses the global registry by default.
	exporter, err := otelprom.New(
		otelprom.WithTranslationStrategy(otlptranslator.NoTranslation),
	)
	if err != nil {
		log.Fatal(err)
	}

	// Register the exporter with a new MeterProvider.
	provider := metric.NewMeterProvider(metric.WithReader(exporter))
	meter := provider.Meter(
		"example-no-translation",
		otelmetric.WithInstrumentationVersion("v1.0.0"),
		otelmetric.WithSchemaURL(semconv.SchemaURL),
	)

	// Create a counter instrument.
	// We use a name with a dot ("my.metric").
	// With NoTranslation strategy, suffixes like _total are not added.
	counter, err := meter.Float64Counter("my.metric", otelmetric.WithDescription("a counter without translation"))
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	counter.Add(ctx, 5)

	// Serve metrics using promhttp.Handler (uses default gatherer).
	server := httptest.NewServer(promhttp.Handler())
	defer server.Close()

	// Make an HTTP request to the endpoint.
	resp, err := http.Get(server.URL) //nolint:noctx
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	// Filter the output for lines containing our metric name.
	lines := strings.SplitSeq(string(body), "\n")
	for line := range lines {
		if strings.Contains(line, "my.metric") {
			fmt.Println(line)
		}
	}

}
Output:
# HELP "my.metric" a counter without translation
# TYPE "my.metric" counter
{"my.metric",otel_scope_name="example-no-translation",otel_scope_schema_url="https://opentelemetry.io/schemas/1.41.0",otel_scope_version="v1.0.0"} 5

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Exporter

type Exporter struct {
	metric.Reader
}

Exporter is a Prometheus Exporter that embeds the OTel metric.Reader interface for easy instantiation with a MeterProvider.

func New

func New(opts ...Option) (*Exporter, error)

New returns a Prometheus Exporter.

func (*Exporter) MarshalLog added in v0.40.0

func (e *Exporter) MarshalLog() any

MarshalLog returns logging data about the Exporter.

type Option added in v0.32.0

type Option interface {
	// contains filtered or unexported methods
}

Option sets exporter option values.

func WithAggregationSelector added in v0.33.0

func WithAggregationSelector(agg metric.AggregationSelector) Option

WithAggregationSelector configure the Aggregation Selector the exporter will use. If no AggregationSelector is provided the DefaultAggregationSelector is used.

func WithNamespace added in v0.38.0

func WithNamespace(ns string) Option

WithNamespace configures the Exporter to prefix metric with the given namespace. Metadata metrics such as target_info are not prefixed since these have special behavior based on their name. Namespaces will be prepended even if otlptranslator.NoTranslation is set as a translation strategy. If the provided namespace is empty, nothing will be prepended to metric names.

func WithProducer added in v0.41.0

func WithProducer(producer metric.Producer) Option

WithProducer configure the metric Producer the exporter will use as a source of external metric data.

func WithRegisterer added in v0.33.0

func WithRegisterer(reg prometheus.Registerer) Option

WithRegisterer configures which prometheus Registerer the Exporter will register with. If no registerer is used the prometheus DefaultRegisterer is used.

func WithResourceAsConstantLabels added in v0.45.0

func WithResourceAsConstantLabels(resourceFilter attribute.Filter) Option

WithResourceAsConstantLabels configures the Exporter to add the resource attributes the resourceFilter returns true for as attributes on all exported metrics.

The does not affect the target info generated from resource attributes.

func WithTranslationStrategy added in v0.60.0

func WithTranslationStrategy(strategy otlptranslator.TranslationStrategyOption) Option

WithTranslationStrategy provides a standardized way to define how metric and label names should be handled during translation to Prometheus format. See: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.48.0/specification/metrics/sdk_exporters/prometheus.md#configuration. The recommended approach is to use either otlptranslator.UnderscoreEscapingWithSuffixes for full Prometheus-style compatibility or otlptranslator.NoTranslation for OpenTelemetry-style names.

By default, if the NameValidationScheme variable in github.com/prometheus/common/model is "legacy", the default strategy is otlptranslator.UnderscoreEscapingWithSuffixes. If the validation scheme is "utf8", then currently the default Strategy is otlptranslator.NoUTF8EscapingWithSuffixes.

Notice: It is planned that a future release of this SDK will change the default to always be otlptranslator.UnderscoreEscapingWithSuffixes in all circumstances. Users wanting a different translation strategy should specify it explicitly.

func WithoutCounterSuffixes deprecated added in v0.40.0

func WithoutCounterSuffixes() Option

WithoutCounterSuffixes disables exporter's addition _total suffixes on counters.

By default, metric names include a _total suffix to follow Prometheus naming conventions. For example, the counter metric happy.people would become happy_people_total. With this option set, the name would instead be happy_people.

Can be used in conjunction with WithTranslationStrategy to disable counter suffixes in strategies that would otherwise add suffixes, but this behavior is not recommended and may be removed in a future release.

Deprecated: Use WithTranslationStrategy instead.

func WithoutScopeInfo added in v0.34.0

func WithoutScopeInfo() Option

WithoutScopeInfo configures the Exporter to not export labels about Instrumentation Scope to all metric points.

func WithoutTargetInfo added in v0.33.0

func WithoutTargetInfo() Option

WithoutTargetInfo configures the Exporter to not export the resource target_info metric. If not specified, the Exporter will create a target_info metric containing the metrics' resource.Resource attributes.

func WithoutUnits deprecated added in v0.33.0

func WithoutUnits() Option

WithoutUnits disables exporter's addition of unit suffixes to metric names, and will also prevent unit comments from being added in OpenMetrics once unit comments are supported.

By default, metric names include a unit suffix to follow Prometheus naming conventions. For example, the counter metric request.duration, with unit milliseconds would become request_duration_milliseconds_total. With this option set, the name would instead be request_duration_total.

Can be used in conjunction with WithTranslationStrategy to disable unit suffixes in strategies that would otherwise add suffixes, but this behavior is not recommended and may be removed in a future release.

Deprecated: Use WithTranslationStrategy instead.

Directories

Path Synopsis
Package internal provides internal functionality for the prometheus package.
Package internal provides internal functionality for the prometheus package.
counter
Package counter provides a simple counter for generating unique IDs.
Package counter provides a simple counter for generating unique IDs.
observ
Package observ provides experimental observability instrumentation for the prometheus exporter.
Package observ provides experimental observability instrumentation for the prometheus exporter.
x
Package x documents experimental features for go.opentelemetry.io/otel/exporters/prometheus.
Package x documents experimental features for go.opentelemetry.io/otel/exporters/prometheus.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL