Skip to content

Golang OpenTelemetry Toolkit, with examples for Datadog, Dynatrace, Elasticsearch/Kibana, Grafana Loki/Jaeger/Tempo, Honeycomb, New Relic, OpenObserve, Uptrace

License

Notifications You must be signed in to change notification settings

yolkhovyy/go-otelw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Golang OpenTelemetry Toolkit

License GitHub Tag Go Reference Go Report Card

Golang OpenTelemetry Toolkit includes:

🚀 Golang utilities to simplify OpenTelemetry instrumentation, configuration and shutdown
OTEL Collector configuration examples for popular observability platforms

Observability backend examples included:

⚠️ This project is pre-v1.0.0 and may change.

go-otelw is pronounced /ˈɡuːtldʌb/- short for Go OpenTelemetry Wrapper.

Content

Toolkit Overview

The diagram below illustrates how telemetry from the Example service, instrumented and configured with go-otelw, can be routed via the OTEL Collector to any OTEL-compatible backend—or even to multiple backends at once.

Simply instrument and configure your services with go-otelw, and use provided OTEL Collector configuration examples to route telemetry to the observability backend of your choice.

Overview

💡 The main purpose of this toolkit is to provide Configure() and Shutdown() utilities which abstract away the complexity of OpenTelemetry setup and shutdown. For example, configuring and shutting down a tracer looks like this:

	tracer, err := tracew.Configure(ctx, config.Tracer, other params)
	...
	defer func() {
		err := tracer.Shutdown(ctx)
		...
	}()

where config.Tracer is loaded from environment variables:

...
EXAMPLE_TRACER_ENABLE=true
EXAMPLE_TRACER_OTLP_ENDPOINT=otel-collector:4317
...

or, from a configuration file, e.g. in YAML format:

...
Tracer:
  Enable: true
  OTLP:
    Endpoint: localhost:4318
...

💡 This toolkit also provides OTEL Collector configuration examples for popular observability backends—both commercial and open source.

Package Content

  • Golang OpenTelemetry Wrapper
  • OTEL Collector configuration Examples
  • Usage Example - HTTP Echo Service
  • Docker Compose to run the Echo Service and its dependencies

How to Use go-otelw

Install

go get github.com/yolkhovyy/go-otelw@latest

Config Types

For simplicity, go-otelw provides minimal configuration types for logger, tracer, and metric in otelw/config.go:

type Config struct {
	// Logging configuration
	Logger slogw.Config `json:"logger" yaml:"logger" mapstructure:"Logger"`

	// Tracing configuration
	Tracer tracew.Config `json:"tracer" yaml:"tracer" mapstructure:"Tracer"`

	// Metrics configuration
	Metric metricw.Config `json:"metric" yaml:"metric" mapstructure:"Metric"`
}

It also includes configuration for the OTLP protocol used to connect to the OTEL Collector, defined in otelw/otlp/config.go:

type Config struct {
	// Protocol to use for telemetry collection - GRPC (default), HTTP.
	Protocol Protocol `json:"protocol" yaml:"protocol" mapstructure:"protocol"`

	// Endpoint for OTLP protocol.
	Endpoint string `json:"endpoint" yaml:"endpoint" mapstructure:"endpoint"`

	// Whether to use an insecure endpoint (without TLS).
	Insecure bool `json:"insecure" yaml:"insecure" mapstructure:"insecure"`

	// Path to the client certificate file.
	ClientCertificate string `json:"clientCertificate" yaml:"clientCertificate" mapstructure:"clientCertificate"`

	// Path to the client private key file.
	ClientKey string `json:"clientKey" yaml:"clientKey" mapstructure:"clientKey"`

	// Path to the Certificate Authority (CA) file.
	Certificate string `json:"certificate" yaml:"certificate" mapstructure:"certificate"`
}

go-otelw configuration can be loaded from YAML or JSON files on application startup. See an example in cmd/example/config.yml

For fine-grained configuration, you can also use OpenTelemetry environment variables.

Configure and Shutdown Utilities

go-otelw simplifies the use of OpenTelemetry by providing Configure() and Shutdown() utility functions for logger, tracer and metric.

All-in Configuration and Shutdown Example

See cmd/example/main.go

	serviceAttributes := []attribute.KeyValue{
		semconv.ServiceNameKey.String(serviceName),
		semconv.ServiceVersionKey.String(version.Tag),
	}
	
	logger, tracer, metric, err := otelw.Configure(ctx, config.Config, serviceAttributes)
	if err != nil {
		fmt.Fprintf(os.Stderr, "otelw configure: %v", err)

		return osx.ExitFailure
	}

	defer func() {
		err := errors.Join(err,
			metric.Shutdown(ctx),
			tracer.Shutdown(ctx),
			logger.Shutdown(ctx))
		if err != nil {
			fmt.Fprintf(os.Stderr, "otelw shutdown: %v", err)
		}
	}()

Individual Logger, Tracer and Metric Configuration

See cmd/example/internal/otelw/otelw.go

	logger, err := slogw.Configure(ctx, config.Logger, attrs, writers...)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("slogw configure: %w", err)
	}

	tracer, err := tracew.Configure(ctx, config.Tracer, attrs, writers...)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("tracew configure: %w", err)
	}

	metric, err := metricw.Configure(ctx, config.Metric, attrs, writers...)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("metricw configure: %w", err)
	}

Tracing and Logging Examples

See cmd/example/internal/domain/domain.go

	ctx, span := tracew.Start(ctx, "echo", "worker"+strconv.Itoa(sequence))
	defer func() { span.End(err) }()

	logger := slogw.DefaultLogger()
	logger.InfoContext(ctx, "echo worker", 
		slog.Int("sequence", sequence),
		slog.String("input", input),
	)