or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

attributes.mdbridges.mdcontext-propagation.mdexporters-other.mdexporters-otlp.mdindex.mdlogging.mdmetrics.mdsdk-log.mdsdk-metric.mdsdk-resource.mdsdk-trace.mdsemantic-conventions.mdtracing.md
tile.json

exporters-otlp.mddocs/

OTLP Exporters

OpenTelemetry Protocol (OTLP) exporters send telemetry data using the OTLP protocol over gRPC or HTTP. OTLP is the native protocol for OpenTelemetry and is the recommended export format.

Overview

The SDK provides OTLP exporters for all three signals:

  1. Trace Exporters: Export spans (gRPC and HTTP)
  2. Metric Exporters: Export metrics (gRPC and HTTP)
  3. Log Exporters: Export log records (gRPC and HTTP)

OTLP Trace Exporters

Export trace spans using the OTLP protocol.

OTLP HTTP Trace Exporter

Package: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp

import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"

Installation

go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp@v1.38.0

Creating the Exporter

func New(ctx context.Context, opts ...Option) (*Exporter, error)

Example:

package main

import (
	"context"
	"log"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	ctx := context.Background()

	// Create OTLP HTTP trace exporter
	exporter, err := otlptracehttp.New(ctx,
		otlptracehttp.WithEndpoint("localhost:4318"),
		otlptracehttp.WithInsecure(),
	)
	if err != nil {
		log.Fatal(err)
	}

	// Create tracer provider with exporter
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tp)

	defer func() {
		if err := tp.Shutdown(ctx); err != nil {
			log.Printf("Error shutting down tracer provider: %v", err)
		}
	}()
}

Configuration Options

type Option interface {
	// Has unexported methods
}

Available Options:

// WithEndpoint sets the OTLP endpoint (default: "localhost:4318")
func WithEndpoint(endpoint string) Option

// WithInsecure disables TLS
func WithInsecure() Option

// WithURLPath sets the URL path (default: "/v1/traces")
func WithURLPath(urlPath string) Option

// WithHeaders sets HTTP headers
func WithHeaders(headers map[string]string) Option

// WithTLSClientConfig sets the TLS configuration
func WithTLSClientConfig(tlsCfg *tls.Config) Option

// WithCompression sets the compression method (gzip)
func WithCompression(compression Compression) Option

// WithTimeout sets the request timeout (default: 10s)
func WithTimeout(duration time.Duration) Option

// WithRetry configures retry behavior
func WithRetry(config RetryConfig) Option

Example with Options:

import (
	"crypto/tls"
	"time"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
)

exporter, err := otlptracehttp.New(ctx,
	otlptracehttp.WithEndpoint("otlp.example.com:443"),
	otlptracehttp.WithHeaders(map[string]string{
		"Authorization": "Bearer " + token,
	}),
	otlptracehttp.WithCompression(otlptracehttp.GzipCompression),
	otlptracehttp.WithTimeout(30*time.Second),
	otlptracehttp.WithRetry(otlptracehttp.RetryConfig{
		Enabled:         true,
		InitialInterval: 1 * time.Second,
		MaxInterval:     30 * time.Second,
		MaxElapsedTime:  5 * time.Minute,
	}),
)

OTLP gRPC Trace Exporter

Package: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc

import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"

Installation

go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.38.0

Creating the Exporter

func New(ctx context.Context, opts ...Option) (*Exporter, error)

Example:

import (
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

exporter, err := otlptracegrpc.New(ctx,
	otlptracegrpc.WithEndpoint("localhost:4317"),
	otlptracegrpc.WithInsecure(),
)
if err != nil {
	log.Fatal(err)
}

tp := sdktrace.NewTracerProvider(
	sdktrace.WithBatcher(exporter),
)

Configuration Options

// WithEndpoint sets the OTLP endpoint (default: "localhost:4317")
func WithEndpoint(endpoint string) Option

// WithInsecure disables TLS
func WithInsecure() Option

// WithHeaders sets gRPC metadata
func WithHeaders(headers map[string]string) Option

// WithTLSCredentials sets TLS credentials
func WithTLSCredentials(creds credentials.TransportCredentials) Option

// WithCompressor sets the gRPC compressor
func WithCompressor(compressor string) Option

// WithTimeout sets the request timeout
func WithTimeout(duration time.Duration) Option

// WithRetry configures retry behavior
func WithRetry(config RetryConfig) Option

// WithDialOption sets custom gRPC dial options
func WithDialOption(opts ...grpc.DialOption) Option

OTLP Metric Exporters

Export metrics using the OTLP protocol.

OTLP HTTP Metric Exporter

Package: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp

import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"

Installation

go get go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp@v1.38.0

Creating the Exporter

func New(ctx context.Context, opts ...Option) (*Exporter, error)

Example:

import (
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
)

exporter, err := otlpmetrichttp.New(ctx,
	otlpmetrichttp.WithEndpoint("localhost:4318"),
	otlpmetrichttp.WithInsecure(),
)
if err != nil {
	log.Fatal(err)
}

mp := sdkmetric.NewMeterProvider(
	sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)),
)
otel.SetMeterProvider(mp)

Configuration Options

Similar to trace exporter with different default URL path (/v1/metrics).

// WithEndpoint sets the OTLP endpoint
func WithEndpoint(endpoint string) Option

// WithInsecure disables TLS
func WithInsecure() Option

// WithURLPath sets the URL path (default: "/v1/metrics")
func WithURLPath(urlPath string) Option

// WithHeaders sets HTTP headers
func WithHeaders(headers map[string]string) Option

// WithCompression sets the compression method
func WithCompression(compression Compression) Option

// WithTimeout sets the request timeout
func WithTimeout(duration time.Duration) Option

// WithTemporalitySelector sets the temporality selector
func WithTemporalitySelector(selector TemporalitySelector) Option

// WithAggregationSelector sets the aggregation selector
func WithAggregationSelector(selector AggregationSelector) Option

OTLP gRPC Metric Exporter

Package: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc

import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"

Installation

go get go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc@v1.38.0

Creating the Exporter

func New(ctx context.Context, opts ...Option) (*Exporter, error)

Example:

import (
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
)

exporter, err := otlpmetricgrpc.New(ctx,
	otlpmetricgrpc.WithEndpoint("localhost:4317"),
	otlpmetricgrpc.WithInsecure(),
)
if err != nil {
	log.Fatal(err)
}

mp := sdkmetric.NewMeterProvider(
	sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)),
)

OTLP Log Exporters

Export log records using the OTLP protocol. Note: Logging is currently in beta.

OTLP HTTP Log Exporter

Package: go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp

import "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"

Installation

go get go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp@v0.9.0

Creating the Exporter

func New(ctx context.Context, opts ...Option) (*Exporter, error)

Example:

import (
	"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
	"go.opentelemetry.io/otel/log/global"
	sdklog "go.opentelemetry.io/otel/sdk/log"
)

exporter, err := otlploghttp.New(ctx,
	otlploghttp.WithEndpoint("localhost:4318"),
	otlploghttp.WithInsecure(),
)
if err != nil {
	log.Fatal(err)
}

lp := sdklog.NewLoggerProvider(
	sdklog.WithProcessor(sdklog.NewBatchProcessor(exporter)),
)
global.SetLoggerProvider(lp)

OTLP gRPC Log Exporter

Package: go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc

import "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc"

Installation

go get go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc@v0.9.0

Complete Example

Full OTLP Setup for All Signals

package main

import (
	"context"
	"log"
	"time"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	"go.opentelemetry.io/otel/log/global"
	"go.opentelemetry.io/otel/propagation"
	sdklog "go.opentelemetry.io/otel/sdk/log"
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
)

func setupOTLP(ctx context.Context) (shutdown func(context.Context) error, err error) {
	var shutdownFuncs []func(context.Context) error

	shutdown = func(ctx context.Context) error {
		var err error
		for _, fn := range shutdownFuncs {
			err = errors.Join(err, fn(ctx))
		}
		shutdownFuncs = nil
		return err
	}

	// Create resource
	res, err := resource.New(ctx,
		resource.WithAttributes(
			semconv.ServiceName("my-service"),
			semconv.ServiceVersion("1.0.0"),
			semconv.DeploymentEnvironment("production"),
		),
		resource.WithProcess(),
		resource.WithHost(),
		resource.WithOS(),
	)
	if err != nil {
		return nil, err
	}

	// Setup trace provider
	traceExporter, err := otlptracehttp.New(ctx,
		otlptracehttp.WithEndpoint("localhost:4318"),
		otlptracehttp.WithInsecure(),
		otlptracehttp.WithCompression(otlptracehttp.GzipCompression),
	)
	if err != nil {
		return nil, err
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(traceExporter,
			sdktrace.WithMaxQueueSize(4096),
			sdktrace.WithBatchTimeout(5*time.Second),
		),
		sdktrace.WithResource(res),
	)
	otel.SetTracerProvider(tp)
	shutdownFuncs = append(shutdownFuncs, tp.Shutdown)

	// Setup meter provider
	metricExporter, err := otlpmetrichttp.New(ctx,
		otlpmetrichttp.WithEndpoint("localhost:4318"),
		otlpmetrichttp.WithInsecure(),
		otlpmetrichttp.WithCompression(otlpmetrichttp.GzipCompression),
	)
	if err != nil {
		return nil, err
	}

	mp := sdkmetric.NewMeterProvider(
		sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter,
			sdkmetric.WithInterval(30*time.Second),
		)),
		sdkmetric.WithResource(res),
	)
	otel.SetMeterProvider(mp)
	shutdownFuncs = append(shutdownFuncs, mp.Shutdown)

	// Setup logger provider
	logExporter, err := otlploghttp.New(ctx,
		otlploghttp.WithEndpoint("localhost:4318"),
		otlploghttp.WithInsecure(),
		otlploghttp.WithCompression(otlploghttp.GzipCompression),
	)
	if err != nil {
		return nil, err
	}

	lp := sdklog.NewLoggerProvider(
		sdklog.WithProcessor(sdklog.NewBatchProcessor(logExporter)),
		sdklog.WithResource(res),
	)
	global.SetLoggerProvider(lp)
	shutdownFuncs = append(shutdownFuncs, lp.Shutdown)

	// Setup propagators
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
		propagation.TraceContext{},
		propagation.Baggage{},
	))

	return shutdown, nil
}

func main() {
	ctx := context.Background()

	// Setup OTLP exporters
	shutdown, err := setupOTLP(ctx)
	if err != nil {
		log.Fatal(err)
	}

	// Cleanup on exit
	defer func() {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		if err := shutdown(ctx); err != nil {
			log.Printf("Error shutting down: %v", err)
		}
	}()

	// Your application code here
	log.Println("Application running with OTLP exporters")
}

Environment Variables

The OTLP exporters respect standard OpenTelemetry environment variables:

# Endpoint configuration
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.example.com:4318
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otlp.example.com:4318/v1/traces
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://otlp.example.com:4318/v1/metrics
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://otlp.example.com:4318/v1/logs

# Headers (comma-separated key=value pairs)
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer token,X-Custom=value
OTEL_EXPORTER_OTLP_TRACES_HEADERS=Authorization=Bearer token
OTEL_EXPORTER_OTLP_METRICS_HEADERS=Authorization=Bearer token
OTEL_EXPORTER_OTLP_LOGS_HEADERS=Authorization=Bearer token

# TLS configuration
OTEL_EXPORTER_OTLP_INSECURE=true
OTEL_EXPORTER_OTLP_CERTIFICATE=/path/to/cert.pem

# Compression
OTEL_EXPORTER_OTLP_COMPRESSION=gzip

# Timeout
OTEL_EXPORTER_OTLP_TIMEOUT=10000

Best Practices

1. Use HTTP for Most Cases

// HTTP is simpler and works in more environments
exporter, err := otlptracehttp.New(ctx)

// gRPC requires more dependencies
// exporter, err := otlptracegrpc.New(ctx)

2. Enable Compression

exporter, err := otlptracehttp.New(ctx,
	otlptracehttp.WithCompression(otlptracehttp.GzipCompression),
)

3. Configure Timeouts

exporter, err := otlptracehttp.New(ctx,
	otlptracehttp.WithTimeout(30*time.Second),
)

4. Use TLS in Production

// Good: Use TLS in production
exporter, err := otlptracehttp.New(ctx,
	otlptracehttp.WithEndpoint("otlp.example.com:443"),
)

// Bad: Only use insecure for local development
exporter, err := otlptracehttp.New(ctx,
	otlptracehttp.WithEndpoint("localhost:4318"),
	otlptracehttp.WithInsecure(),
)

5. Configure Retries

exporter, err := otlptracehttp.New(ctx,
	otlptracehttp.WithRetry(otlptracehttp.RetryConfig{
		Enabled:         true,
		InitialInterval: 1 * time.Second,
		MaxInterval:     30 * time.Second,
		MaxElapsedTime:  5 * time.Minute,
	}),
)

Related Documentation

  • SDK Trace: Using exporters with TracerProvider
  • SDK Metric: Using exporters with MeterProvider
  • SDK Log: Using exporters with LoggerProvider
  • Other Exporters: Non-OTLP exporters