1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-03 18:35:08 +02:00

Add example test for the prometheus exporter (#8137)

We used to have the examples in core, but now that they are in contrib
it can be hard to find examples of how to use the prometheus exporter.

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
David Ashpole
2026-04-08 15:18:24 -04:00
committed by GitHub
parent edd072f2c9
commit 7ac83c37af
2 changed files with 203 additions and 1 deletions
+202
View File
@@ -0,0 +1,202 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package prometheus_test
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/prometheus/client_golang/prometheus"
"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.40.0"
)
func Example() {
// 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.40.0",otel_scope_version="v1.0.0"} 10
}
func Example_customRegistry() {
// 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.40.0",otel_scope_version="v1.0.0"} 5
}
func Example_noTranslation() {
// 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.40.0",otel_scope_version="v1.0.0"} 5
}
+1 -1
View File
@@ -9,6 +9,7 @@ retract v0.59.0
require (
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2
github.com/prometheus/common v0.67.5
github.com/prometheus/otlptranslator v1.0.0
github.com/stretchr/testify v1.11.1
go.opentelemetry.io/otel v1.43.0
@@ -29,7 +30,6 @@ require (
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect