otelkit

package module
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2025 License: MIT Imports: 10 Imported by: 0

README ΒΆ

OtelKit

CI Go Reference Go Report Card Release License Used by Contributors Last Commit PRs Welcome Codecov

A simplified, opinionated wrapper around OpenTelemetry tracing for Go applications. OtelKit provides an easy-to-use API for creating and managing distributed traces while hiding the complexity of the underlying OpenTelemetry SDK.

Features

πŸš€ Simple API - Easy-to-use wrapper around OpenTelemetry
πŸ”§ Flexible Configuration - Supports both simple and advanced configurations
🌐 HTTP Middleware - Built-in middleware for popular HTTP frameworks
πŸ“Š Multiple Exporters - Support for Jaeger, OTLP HTTP, and OTLP gRPC
⚑ Performance Optimized - Configurable sampling and batch processing
πŸ›‘οΈ Production Ready - Comprehensive error handling and graceful shutdown

Quick Start

Installation
go get github.com/kernelshard/otelkit

For most applications, use the simplified SetupTracing approach:

package main

import (
    "context"
    "log"
    
    "github.com/kernelshard/otelkit"
    "go.opentelemetry.io/otel/attribute"
)

func main() {
    // Initialize tracing with sensible defaults
    shutdown, err := otelkit.SetupTracing(context.Background(), "my-service", "v1.0.0")
    if err != nil {
        log.Fatal(err)
    }
    defer shutdown(context.Background())

    // Create a tracer
    tracer := otelkit.New("my-service")
    
    // Create a span
    ctx, span := tracer.Start(context.Background(), "do-work")
    defer span.End()
    
    // Add attributes
    otelkit.AddAttributes(span,
        attribute.String("user.id", "12345"),
        attribute.String("operation", "process-payment"),
    )
    
    // Your business logic here
    doWork(ctx)
}

func doWork(ctx context.Context) {
    // Work happens here...
}
Alternative: Provider-based Setup

For more control, use the provider-based approach:

package main

import (
    "context"
    "log"
    
    "github.com/kernelshard/otelkit"
    "go.opentelemetry.io/otel/attribute"
)

func main() {
    // Initialize with provider configuration
    provider, err := otelkit.NewDefaultProvider(context.Background(), "my-service", "v1.0.0")
    if err != nil {
        log.Fatal(err)
    }
    defer provider.Shutdown(context.Background())

    // Create a tracer
    tracer := otelkit.New("my-service")
    
    // Create a span
    ctx, span := tracer.Start(context.Background(), "do-work")
    defer span.End()
    
    // Add attributes
    otelkit.AddAttributes(span,
        attribute.String("user.id", "12345"),
        attribute.String("operation", "process-payment"),
    )
    
    // Your business logic here
    doWork(ctx)
}

func doWork(ctx context.Context) {
    // Work happens here...
}
HTTP Middleware
package main

import (
    "context"
    "net/http"
    
    "github.com/gorilla/mux"
    "github.com/kernelshard/otelkit"
)

func main() {
    // Setup tracing
    provider, _ := otelkit.NewDefaultProvider(context.Background(), "web-service")
    defer provider.Shutdown(context.Background())
    
    tracer := otelkit.New("web-service")
    middleware := otelkit.NewHttpMiddleware(tracer)

    // Setup router with middleware
    r := mux.NewRouter()
    r.Use(middleware.Middleware)
    r.HandleFunc("/users/{id}", getUserHandler)
    
    http.ListenAndServe(":8080", r)
}

func getUserHandler(w http.ResponseWriter, r *http.Request) {
    // Handler automatically traced by middleware
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("User data"))
}

Advanced Configuration

For production environments, you'll want more control over the configuration:

package main

import (
    "context"
    "time"
    
    "github.com/kernelshard/otelkit"
)

func main() {
    // Advanced configuration
    config := otelkit.NewProviderConfig("payment-service", "v2.1.0").
        WithOTLPExporter("https://api.honeycomb.io", "http", false).
        WithSampling("probabilistic", 0.05). // 5% sampling
        WithBatchOptions(
            2*time.Second,  // batch timeout
            10*time.Second, // export timeout  
            1024,          // max batch size
            4096,          // max queue size
        )
    
    provider, err := otelkit.NewProvider(context.Background(), config)
    if err != nil {
        log.Fatal(err)
    }
    defer provider.Shutdown(context.Background())
    
    // Use tracer as normal
    tracer := otelkit.New("payment-service")
    // ...
}

Configuration Options

Sampling Strategies
  • probabilistic - Sample based on probability ratio (0.0 to 1.0)
  • always_on - Sample all traces (100%)
  • always_off - Sample no traces (0%)
Exporters
  • OTLP HTTP - HTTP-based OTLP exporter (default)
  • OTLP gRPC - gRPC-based OTLP exporter (more efficient for high throughput)
Batch Processing

Fine-tune performance with batch processor settings:

config.WithBatchOptions(
    batchTimeout,       // Max time to wait before exporting
    exportTimeout,      // Max time for export operation
    maxExportBatchSize, // Max spans per batch
    maxQueueSize,       // Max queued spans before dropping
)

API Reference

Core Types
  • Tracer - Main tracer wrapper with convenience methods
  • ProviderConfig - Configuration for tracer provider
  • HTTPMiddleware - HTTP middleware for automatic request tracing
For Most Use Cases:
  • SetupTracing(ctx, serviceName, serviceVersion...) - βœ… Recommended: Simplest setup with sensible defaults
  • New(name) - Create tracer instance for span creation
  • NewHttpMiddleware(tracer) - Create HTTP middleware for request tracing
For Advanced Configuration:
  • NewProviderConfig(serviceName, serviceVersion) - Create provider configuration
  • NewProvider(ctx, config) - Create provider with custom configuration
Utility Functions
  • AddAttributes(span, ...attrs) - Safely add attributes to span
  • AddEvent(span, name, ...attrs) - Add timestamped event to span
  • RecordError(span, err) - Record error and set span status
  • EndSpan(span) - Safely end span
Deprecated Functions (Avoid for new code)

The following functions are deprecated and will be removed in v1.0.0:

  • SetupTracingWithDefaults() - Use SetupTracing() instead
  • MustSetupTracing() - Handle errors explicitly instead
  • SetupCustomTracing() - Use NewProviderConfig() with NewProvider() instead

Usage Recommendations

// Simple setup with environment variables
shutdown, err := otelkit.SetupTracing(ctx, "my-service")
defer shutdown(ctx)
tracer := otelkit.New("my-service")
🟑 Advanced Approach (When you need custom config)
// Custom configuration
config := otelkit.NewProviderConfig("my-service", "v1.0.0").
    WithOTLPExporter("https://api.honeycomb.io", "http", false).
    WithSampling("probabilistic", 0.05)
provider, err := otelkit.NewProvider(ctx, config)
defer provider.Shutdown(ctx)
tracer := otelkit.New("my-service")
πŸ”΄ Avoid (Deprecated)
// These will be removed in v1.0.0
otelkit.SetupTracingWithDefaults(ctx, "service", "v1")
otelkit.MustSetupTracing(ctx, "service")
otelkit.SetupCustomTracing(ctx, config)

Examples

Check the /examples directory for complete working examples:

Best Practices

1. Use Appropriate Sampling in Production
// Development: 100% sampling
config.WithSampling("always_on", 0)

// Production: Low sampling rate
config.WithSampling("probabilistic", 0.01) // 1%
2. Always Defer Span Ending
ctx, span := tracer.Start(ctx, "operation")
defer span.End() // Always defer this
3. Add Meaningful Attributes
otelkit.AddAttributes(span,
    attribute.String("user.id", userID),
    attribute.String("operation.type", "payment"),
    attribute.Int64("amount", amount),
)
4. Handle Errors Properly
if err := doSomething(); err != nil {
    otelkit.RecordError(span, err)
    return err
}
5. Use Context Propagation
// Always pass context to maintain trace continuity
func processPayment(ctx context.Context, amount int64) error {
    ctx, span := tracer.Start(ctx, "process-payment")
    defer span.End()
    
    return callPaymentAPI(ctx, amount) // Pass ctx along
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Built on top of OpenTelemetry Go
  • Inspired by the need for simpler tracing setup in Go applications

Documentation ΒΆ

Overview ΒΆ

Package otelkit provides a simplified, opinionated wrapper around OpenTelemetry tracing for Go applications.

This package offers easy-to-use APIs for creating and managing distributed traces while hiding the complexity of the underlying OpenTelemetry SDK. It provides zero-configuration setup with sensible defaults, while still allowing full customization when needed.

For most use cases, start with SetupTracing:

ctx := context.Background()
shutdown, err := otelkit.SetupTracing(ctx, "my-service")
if err != nil {
    log.Fatal(err)
}
defer shutdown(ctx)

tracer := otelkit.New("my-service")
ctx, span := tracer.Start(ctx, "operation-name")
defer span.End()

Advanced Configuration ΒΆ

For custom configuration, use NewProviderConfig with NewProvider:

config := otelkit.NewProviderConfig("my-service", "v1.0.0").
    WithOTLPExporter("https://api.honeycomb.io", "http", false).
    WithSampling("probabilistic", 0.05)
provider, err := otelkit.NewProvider(ctx, config)
if err != nil {
    log.Fatal(err)
}
defer provider.Shutdown(ctx)

HTTP Middleware ΒΆ

For HTTP request tracing:

tracer := otelkit.New("web-service")
middleware := otelkit.NewHttpMiddleware(tracer)
r.Use(middleware.Middleware)

The package handles: - OTLP exporter configuration (HTTP/gRPC) - Sampling strategies (probabilistic, always_on, always_off) - Resource management with service metadata - Context propagation for distributed tracing - HTTP and gRPC instrumentation - Error recording and span utilities

Configuration can be done via environment variables or programmatically. See the README for comprehensive examples and configuration options.

Index ΒΆ

Constants ΒΆ

View Source
const ErrorCodeExternalService = tracer.ErrorCodeExternalService

ErrorCodeExternalService is a constant for external service errors.

Variables ΒΆ

This section is empty.

Functions ΒΆ

func AddAttributes ΒΆ

func AddAttributes(span trace.Span, attrs ...attribute.KeyValue)

AddAttributes safely adds one or more attributes to the given span. If the span is nil, this function is a no-op.

func AddEvent ΒΆ

func AddEvent(span trace.Span, name string, attrs ...attribute.KeyValue)

AddEvent safely adds a named event with optional attributes to the span. If the span is nil, this function is a no-op.

func AddTimedEvent ΒΆ

func AddTimedEvent(span trace.Span, name string, duration time.Duration)

AddTimedEvent adds an event with duration information to the span.

func EndSpan ΒΆ

func EndSpan(span trace.Span)

EndSpan safely ends the given span. If the span is nil, this function is a no-op.

func IsRecording ΒΆ

func IsRecording(span trace.Span) bool

IsRecording checks if the span is currently recording telemetry data. Returns false if the span is nil or if the span context is invalid.

func MustSetupTracing deprecated

func MustSetupTracing(ctx context.Context, serviceName string, serviceVersion ...string) func(context.Context) error

MustSetupTracing is like SetupTracing but panics on error. Use this for simple programs where you want to fail fast.

Deprecated: Handle errors explicitly instead. This function will be removed in v1.0.0.

func New ΒΆ

func New(name string) *tracer.Tracer

New creates a new tracer instance with the given name. This is the main entry point for creating tracers that will be used throughout your application for manual span creation.

Example:

tracer := otelkit.New("my-service")
ctx, span := tracer.Start(ctx, "operation-name")
defer span.End()

func NewDefaultProvider ΒΆ

func NewDefaultProvider(ctx context.Context, serviceName string, serviceVersion ...string) (*sdktrace.TracerProvider, error)

NewDefaultProvider creates a tracer provider with default settings and sets it as the global provider. This is a convenience function for quick setup in development or simple applications.

Example:

provider, err := otelkit.NewDefaultProvider(ctx, "my-service", "v1.0.0")
if err != nil {
    log.Fatal(err)
}
defer provider.Shutdown(ctx)

func NewHttpMiddleware ΒΆ

func NewHttpMiddleware(tracer *tracer.Tracer) *middleware.HTTPMiddleware

NewHttpMiddleware creates HTTP middleware for automatic request tracing. This middleware automatically creates spans for HTTP requests and adds useful attributes like HTTP method, URL, status code, and user agent.

Example:

tracer := otelkit.New("web-service")
middleware := otelkit.NewHttpMiddleware(tracer)
r.Use(middleware.Middleware)

func NewProvider ΒΆ

NewProvider creates and configures a new TracerProvider using the provided configuration, then sets it as the global OpenTelemetry provider (only once per application lifecycle). This is the recommended way to initialize tracing when you need custom configuration.

Example:

config := otelkit.NewProviderConfig("payment-service", "v1.2.3").
    WithOTLPExporter("https://api.honeycomb.io", "http", false).
    WithSampling("probabilistic", 0.05)

provider, err := otelkit.NewProvider(ctx, config)
if err != nil {
    log.Fatal(err)
}
defer provider.Shutdown(ctx)

func NewProviderConfig ΒΆ

func NewProviderConfig(serviceName, serviceVersion string) *provider.ProviderConfig

NewProviderConfig creates a new ProviderConfig with sensible defaults for advanced configuration. This is the starting point for custom tracer provider configuration when you need more control than the default setup provides.

Example:

config := otelkit.NewProviderConfig("my-service", "v1.0.0").
    WithOTLPExporter("https://api.honeycomb.io", "http", false).
    WithSampling("probabilistic", 0.05)

func RecordError ΒΆ

func RecordError(span trace.Span, err error)

RecordError safely records an error on the span and sets the span status to error. This function handles nil checks for both span and error.

func RecordErrorWithCode ΒΆ

func RecordErrorWithCode(span trace.Span, err error, code string, message string)

RecordErrorWithCode safely records an error on the span with a custom error code and message.

func SetGlobalTracerProvider ΒΆ

func SetGlobalTracerProvider(tp *sdktrace.TracerProvider)

SetGlobalTracerProvider sets the global tracer provider. This is typically called automatically by the setup functions, but can be called manually if needed.

func SetupCustomTracing deprecated

func SetupCustomTracing(ctx context.Context, cfg *provider.ProviderConfig) (*sdktrace.TracerProvider, error)

SetupCustomTracing provides full control over the tracing setup. Use this when you need custom configuration that goes beyond environment variables.

Deprecated: Use NewProviderConfig() with NewProvider() for advanced configuration. This function will be removed in v1.0.0.

func SetupTracing ΒΆ

func SetupTracing(ctx context.Context, serviceName string, serviceVersion ...string) (func(context.Context) error, error)

SetupTracing initializes OpenTelemetry tracing with sensible defaults. This is the simplest way to get started with tracing.

Example:

shutdown, err := otelkit.SetupTracing(ctx, "my-service")
if err != nil {
    log.Fatal(err)
}
defer shutdown(ctx)

func SetupTracingWithDefaults deprecated

func SetupTracingWithDefaults(ctx context.Context, serviceName, serviceVersion string) (func(context.Context) error, error)

SetupTracingWithDefaults initializes tracing with hardcoded defaults. This is useful for quick setup without environment variables.

Deprecated: Use SetupTracing instead. This function will be removed in v1.0.0.

func ShutdownTracerProvider ΒΆ

func ShutdownTracerProvider(ctx context.Context, tp *sdktrace.TracerProvider) error

ShutdownTracerProvider gracefully shuts down the tracer provider, ensuring all pending spans are exported before the application terminates.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

if err := otelkit.ShutdownTracerProvider(ctx, provider); err != nil {
    log.Printf("Error during tracer shutdown: %v", err)
}

Types ΒΆ

type ConfigError ΒΆ

type ConfigError = config.ConfigError

ConfigError represents a configuration validation error.

type HTTPMiddleware ΒΆ

type HTTPMiddleware = middleware.HTTPMiddleware

HTTPMiddleware is an alias for the HTTP middleware type. This provides a cleaner API surface for users of this package.

type InitializationError ΒΆ

type InitializationError = config.InitializationError

InitializationError represents an error during tracer provider initialization.

type ProviderConfig ΒΆ

type ProviderConfig = provider.ProviderConfig

ProviderConfig is an alias for the provider configuration type. This provides a cleaner API surface for users of this package.

type Span ΒΆ

type Span = trace.Span

Span is an alias for the underlying OpenTelemetry span interface. This provides a cleaner API surface for users of this package.

type TracedHTTPClient ΒΆ

type TracedHTTPClient = tracer.TracedHTTPClient

TracedHTTPClient is an alias for the traced HTTP client type.

func NewTracedHTTPClient ΒΆ

func NewTracedHTTPClient(client *http.Client, tr *Tracer, service string) *TracedHTTPClient

NewTracedHTTPClient creates a new traced HTTP client.

type Tracer ΒΆ

type Tracer = tracer.Tracer

Tracer is an alias for the tracer wrapper type. This provides a cleaner API surface for users of this package.

Directories ΒΆ

Path Synopsis
examples
basic command
Package main demonstrates basic OpenTelemetry tracing with HTTP middleware.
Package main demonstrates basic OpenTelemetry tracing with HTTP middleware.
dummy_service command
gin command
Package main demonstrates OpenTelemetry tracing with Gin framework integration.
Package main demonstrates OpenTelemetry tracing with Gin framework integration.
production command
Package main demonstrates a production-ready OpenTelemetry tracing setup with comprehensive configuration, error handling, and best practices for real-world applications.
Package main demonstrates a production-ready OpenTelemetry tracing setup with comprehensive configuration, error handling, and best practices for real-world applications.
internal
Package middleware provides HTTP middleware for automatic request tracing.
Package middleware provides HTTP middleware for automatic request tracing.
Package provider implements the factory and builder patterns for creating and configuring OpenTelemetry tracer providers.
Package provider implements the factory and builder patterns for creating and configuring OpenTelemetry tracer providers.
Package tracer provides span utility functions for OpenTelemetry tracing.
Package tracer provides span utility functions for OpenTelemetry tracing.

Jump to

Keyboard shortcuts

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