OpenTelemetry Go provides several alternative exporters beyond OTLP for different use cases and backends.
Available exporters:
Console exporters for development, debugging, and examples.
Package: go.opentelemetry.io/otel/exporters/stdout/stdouttrace
go get go.opentelemetry.io/otel/exporters/stdout/stdouttrace@v1.38.0package main
import (
"context"
"log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func main() {
ctx := context.Background()
// Create stdout trace exporter
exporter, err := stdouttrace.New(
stdouttrace.WithPrettyPrint(),
)
if err != nil {
log.Fatal(err)
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
)
otel.SetTracerProvider(tp)
defer tp.Shutdown(ctx)
}type Option interface {
// Has unexported methods
}
// WithPrettyPrint enables formatted JSON output
func WithPrettyPrint() Option
// WithWriter sets the output writer
func WithWriter(w io.Writer) Option
// WithoutTimestamps disables timestamps in output
func WithoutTimestamps() OptionPackage: go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
go get go.opentelemetry.io/otel/exporters/stdout/stdoutmetric@v1.38.0import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
)
exporter, err := stdoutmetric.New(
stdoutmetric.WithPrettyPrint(),
)
if err != nil {
log.Fatal(err)
}
mp := sdkmetric.NewMeterProvider(
sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)),
)
otel.SetMeterProvider(mp)Package: go.opentelemetry.io/otel/exporters/stdout/stdoutlog
go get go.opentelemetry.io/otel/exporters/stdout/stdoutlog@v0.9.0import (
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
"go.opentelemetry.io/otel/log/global"
sdklog "go.opentelemetry.io/otel/sdk/log"
)
exporter, err := stdoutlog.New(
stdoutlog.WithPrettyPrint(),
)
if err != nil {
log.Fatal(err)
}
lp := sdklog.NewLoggerProvider(
sdklog.WithProcessor(sdklog.NewBatchProcessor(exporter)),
)
global.SetLoggerProvider(lp)Pull-based metric exporter for Prometheus.
Package: go.opentelemetry.io/otel/exporters/prometheus
go get go.opentelemetry.io/otel/exporters/prometheus@v0.51.0package main
import (
"context"
"log"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
)
func main() {
ctx := context.Background()
// Create Prometheus exporter
exporter, err := prometheus.New()
if err != nil {
log.Fatal(err)
}
// Create meter provider with Prometheus exporter
mp := metric.NewMeterProvider(
metric.WithReader(exporter),
)
otel.SetMeterProvider(mp)
// Serve Prometheus metrics
http.Handle("/metrics", promhttp.Handler())
log.Println("Serving metrics on :8080/metrics")
log.Fatal(http.ListenAndServe(":8080", nil))
}type Option interface {
// Has unexported methods
}
// WithNamespace sets the Prometheus namespace
func WithNamespace(namespace string) Option
// WithAggregationSelector sets the aggregation selector
func WithAggregationSelector(selector metric.AggregationSelector) Option
// WithoutTargetInfo disables target_info metric
func WithoutTargetInfo() Option
// WithoutScopeInfo disables otel_scope_info metric
func WithoutScopeInfo() Option
// WithoutUnits disables metric units in names
func WithoutUnits() Optionpackage main
import (
"context"
"log"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/metric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
)
func main() {
ctx := context.Background()
// Create resource
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceName("my-service"),
semconv.ServiceVersion("1.0.0"),
),
)
if err != nil {
log.Fatal(err)
}
// Create Prometheus exporter
exporter, err := prometheus.New(
prometheus.WithNamespace("myapp"),
prometheus.WithoutUnits(),
)
if err != nil {
log.Fatal(err)
}
// Create meter provider
mp := sdkmetric.NewMeterProvider(
sdkmetric.WithResource(res),
sdkmetric.WithReader(exporter),
)
otel.SetMeterProvider(mp)
// Create instruments
meter := otel.Meter("my-service")
requestCounter, err := meter.Int64Counter(
"http_requests_total",
metric.WithDescription("Total number of HTTP requests"),
)
if err != nil {
log.Fatal(err)
}
// Record metrics
go func() {
for {
requestCounter.Add(ctx, 1, metric.WithAttributes(
attribute.String("method", "GET"),
attribute.Int("status", 200),
))
time.Sleep(1 * time.Second)
}
}()
// Serve Prometheus metrics
http.Handle("/metrics", promhttp.Handler())
log.Println("Serving Prometheus metrics on http://localhost:8080/metrics")
log.Fatal(http.ListenAndServe(":8080", nil))
}Export trace spans to Zipkin.
Package: go.opentelemetry.io/otel/exporters/zipkin
go get go.opentelemetry.io/otel/exporters/zipkin@v1.38.0package main
import (
"context"
"log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/zipkin"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func main() {
ctx := context.Background()
// Create Zipkin exporter
exporter, err := zipkin.New(
"http://localhost:9411/api/v2/spans",
)
if err != nil {
log.Fatal(err)
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
)
otel.SetTracerProvider(tp)
defer tp.Shutdown(ctx)
}type Option func(*config)
// WithLogger sets the logger
func WithLogger(logger *log.Logger) Option
// WithClient sets the HTTP client
func WithClient(client *http.Client) Optionpackage main
import (
"context"
"log"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/zipkin"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
)
func main() {
ctx := context.Background()
// Create resource
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceName("my-service"),
semconv.ServiceVersion("1.0.0"),
),
)
if err != nil {
log.Fatal(err)
}
// Create Zipkin exporter
exporter, err := zipkin.New(
"http://localhost:9411/api/v2/spans",
zipkin.WithClient(&http.Client{
Timeout: 10 * time.Second,
}),
)
if err != nil {
log.Fatal(err)
}
// Create tracer provider
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
)
otel.SetTracerProvider(tp)
defer tp.Shutdown(ctx)
// Use tracer
tracer := otel.Tracer("my-component")
ctx, span := tracer.Start(ctx, "example-operation")
defer span.End()
span.SetAttributes(
attribute.String("key", "value"),
)
}Using multiple exporters simultaneously.
package main
import (
"context"
"log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func main() {
ctx := context.Background()
// Create OTLP exporter for production
otlpExporter, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint("otlp.example.com:443"),
)
if err != nil {
log.Fatal(err)
}
// Create stdout exporter for debugging
stdoutExporter, err := stdouttrace.New(
stdouttrace.WithPrettyPrint(),
)
if err != nil {
log.Fatal(err)
}
// Create tracer provider with both exporters
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(otlpExporter),
sdktrace.WithBatcher(stdoutExporter),
)
otel.SetTracerProvider(tp)
defer tp.Shutdown(ctx)
}// Development: stdout for debugging
exporter, _ := stdouttrace.New(stdouttrace.WithPrettyPrint())
// Production: OTLP or other backend
// exporter, _ := otlptracehttp.New(ctx)// Pull-based metrics (Prometheus scrapes endpoint)
exporter, _ := prometheus.New()
mp := sdkmetric.NewMeterProvider(
sdkmetric.WithReader(exporter),
)// Prometheus: use namespace to avoid conflicts
exporter, _ := prometheus.New(
prometheus.WithNamespace("myapp"),
)