tracing

package
v0.8.59 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2025 License: Apache-2.0 Imports: 11 Imported by: 0

README

OpenTelemetry Tracing Package

This package provides OpenTelemetry tracing instrumentation for Meshery components.

Features

  • Easy Initialization: Simple setup with the InitTracer function
  • Standardized Tags: Consistent service identification with service.name, service.version, and environment
  • Context Propagation: Automatic W3C Trace Context header propagation across service boundaries
  • HTTP Middleware: Ready-to-use middleware for tracing HTTP requests
  • Client Instrumentation: HTTP client transport wrapper for outgoing requests

Quick Start

Initialize Tracing
import (
    "context"
    "github.com/meshery/meshkit/tracing"
)

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

    cfg := tracing.Config{
        ServiceName:    "meshery-server",
        ServiceVersion: "v0.6.0",
        Environment:    "production",
        Endpoint:       "localhost:4317",  // OTLP collector endpoint
        Insecure:       false,             // Use false in production with TLS
    }

    tp, err := tracing.InitTracer(ctx, cfg)
    if err != nil {
        log.Fatalf("Failed to initialize tracer: %v", err)
    }
    defer tp.Shutdown(ctx)
}
HTTP Server Middleware

Wrap your HTTP handler to automatically create spans for incoming requests:

import (
    "net/http"
    "github.com/meshery/meshkit/tracing"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/api", apiHandler)

    // Wrap with tracing middleware
    tracedHandler := tracing.HTTPMiddleware(mux, "meshery-api")

    http.ListenAndServe(":8080", tracedHandler)
}
HTTP Client Instrumentation

Instrument HTTP clients to propagate trace context to downstream services:

import (
    "net/http"
    "github.com/meshery/meshkit/tracing"
)

func makeRequest() {
    client := &http.Client{
        Transport: tracing.NewTransport(nil),
    }

    resp, err := client.Get("http://remote-service/api")
    // Trace context is automatically propagated
}

Configuration

Config Fields
  • ServiceName (required): Name identifying your service
  • ServiceVersion (optional): Version of your service
  • Environment (optional): Deployment environment (e.g., "production", "staging", "development")
  • Endpoint (required): OTLP collector endpoint (e.g., "localhost:4317")
  • Insecure (optional, defaults to false): Set to true for non-TLS connections (development only). When false (default), TLS is used for secure connections.

Integration Examples

Meshery Server
// In server/main.go
func main() {
    ctx := context.Background()
    
    cfg := tracing.Config{
        ServiceName:    "meshery-server",
        ServiceVersion: version.GetVersion(),
        Environment:    os.Getenv("ENVIRONMENT"),
        Endpoint:       os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT"),
        Insecure:       os.Getenv("ENVIRONMENT") == "development",
    }
    
    tp, err := tracing.InitTracer(ctx, cfg)
    if err != nil {
        log.Fatalf("Failed to initialize tracer: %v", err)
    }
    defer tp.Shutdown(ctx)
    
    // Wrap router with tracing
    router := setupRouter()
    tracedRouter := tracing.HTTPMiddleware(router, "meshery-server")
    
    http.ListenAndServe(":9081", tracedRouter)
}
Remote Provider
// In remote provider main.go
func main() {
    ctx := context.Background()
    
    cfg := tracing.Config{
        ServiceName:    "meshery-cloud",
        ServiceVersion: version,
        Environment:    env,
        Endpoint:       otelEndpoint,
        Insecure:       isLocalDev,
    }
    
    tp, err := tracing.InitTracer(ctx, cfg)
    if err != nil {
        log.Fatalf("Failed to initialize tracer: %v", err)
    }
    defer tp.Shutdown(ctx)
    
    // For Echo framework
    e := echo.New()
    
    // Wrap HTTP client for calls to Meshery Server
    client := &http.Client{
        Transport: tracing.NewTransport(nil),
    }
}

W3C Trace Context Propagation

The package automatically configures W3C Trace Context propagation. This ensures that:

  1. Incoming requests with traceparent headers are properly linked to parent traces
  2. Outgoing requests include traceparent headers for distributed tracing
  3. Trace context flows seamlessly between services

OTLP Collector Setup

The tracing package requires an OpenTelemetry Collector endpoint. Common setups:

Local Development (Docker)
docker run -d --name jaeger \
  -p 4317:4317 \
  -p 16686:16686 \
  jaegertracing/all-in-one:latest
Production

Configure your OTLP endpoint in environment variables:

export OTEL_EXPORTER_OTLP_ENDPOINT=collector.example.com:4317
export ENVIRONMENT=production

Viewing Traces

After setting up the collector, traces can be viewed in:

Best Practices

  1. Always call tp.Shutdown(ctx) on application exit to flush remaining spans
  2. Use meaningful operation names in middleware to identify endpoints
  3. Set environment to distinguish traces across deployments
  4. Use TLS in production by setting Insecure: false
  5. Instrument HTTP clients that make calls to other services for full distributed tracing

Package Structure

tracing/
├── tracing.go        # Core initialization and configuration
├── middleware.go     # HTTP middleware and client instrumentation
├── tracing_test.go   # Unit tests
├── example_test.go   # Example usage
├── jaeger.go         # Backward compatibility note
├── zipkin.go         # Backward compatibility note
└── README.md         # This file

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func HTTPHandler

func HTTPHandler(handler http.HandlerFunc, operation string) http.HandlerFunc

HTTPHandler wraps an HTTP handler function with OpenTelemetry tracing It automatically creates spans for incoming HTTP requests and propagates trace context

func HTTPMiddleware

func HTTPMiddleware(handler http.Handler, operation string) http.Handler

HTTPMiddleware wraps an HTTP handler with OpenTelemetry tracing It automatically creates spans for incoming HTTP requests and propagates trace context

Example

ExampleHTTPMiddleware demonstrates how to use HTTP middleware for tracing

package main

import (
	"net/http"

	"github.com/meshery/meshkit/tracing"
)

func main() {
	// Your existing HTTP handler
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		_, _ = w.Write([]byte("Hello, World!"))
	})

	// Wrap with tracing middleware
	tracedHandler := tracing.HTTPMiddleware(handler, "my-api")

	// Use the wrapped handler with your server
	_ = tracedHandler // In practice, use with http.ListenAndServe or your router
}

func InitTracer

func InitTracer(ctx context.Context, cfg Config) (*sdktrace.TracerProvider, error)

InitTracer initializes and configures the global OpenTelemetry trace provider It sets up OTLP gRPC exporter, resource attributes, and W3C trace context propagation

Example

ExampleInitTracer demonstrates how to initialize OpenTelemetry tracing

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/meshery/meshkit/tracing"
)

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

	// Configure tracer
	cfg := tracing.Config{
		ServiceName:    "meshery-server",
		ServiceVersion: "v0.6.0",
		Environment:    "development",
		Endpoint:       "localhost:4317",
		Insecure:       true, // Use true for local development, false for production
	}

	// Initialize tracer
	tp, err := tracing.InitTracer(ctx, cfg)
	if err != nil {
		log.Fatalf("Failed to initialize tracer: %v", err)
	}

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

	fmt.Println("Tracer initialized successfully")
}
Output:

Tracer initialized successfully

func InitTracerFromYamlConfig added in v0.8.57

func InitTracerFromYamlConfig(ctx context.Context, config string) (*sdktrace.TracerProvider, error)

func NewTransport

func NewTransport(base http.RoundTripper) http.RoundTripper

NewTransport creates an HTTP transport instrumented with OpenTelemetry Use this when making HTTP client requests to propagate trace context

Example

ExampleNewTransport demonstrates how to use instrumented HTTP client

package main

import (
	"net/http"

	"github.com/meshery/meshkit/tracing"
)

func main() {
	// Create HTTP client with tracing
	client := &http.Client{
		Transport: tracing.NewTransport(nil),
	}

	// Use the client as normal - trace context will be automatically propagated
	_, _ = client.Get("http://example.com")
}

Types

type Config

type Config struct {
	// ServiceName is the name of the service being traced
	ServiceName string `yaml:"service_name" json:"service_name"`
	// ServiceVersion is the version of the service
	ServiceVersion string `yaml:"service_version" json:"service_version"`
	// Environment is the deployment environment (e.g., "production", "staging", "development")
	Environment string `yaml:"environment" json:"environment"`
	// Endpoint is the OTLP collector endpoint (e.g., "localhost:4317")
	Endpoint string `yaml:"endpoint" json:"endpoint"`
	// Insecure determines whether to use an insecure connection (no TLS)
	Insecure bool `yaml:"insecure" json:"insecure"`
}

Config holds the configuration parameters for tracing

Jump to

Keyboard shortcuts

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