gintelemetry

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

README

gintelemetry

Go Reference License

Opinionated OpenTelemetry for Gin. One function call. Zero boilerplate. Full observability.

Why?

Setting up OpenTelemetry is tedious. This package does it for you.

tel, router, _ := gintelemetry.Start(ctx, gintelemetry.Config{
    ServiceName: "my-service",
})
defer tel.Shutdown(ctx)

That's it. You now have traces, metrics, and logs flowing to your collector.

Install

go get github.com/Levy-Tal/gintelemetry

Quick Start

package main

import (
    "context"
    "github.com/Levy-Tal/gintelemetry"
)

func main() {
    ctx := context.Background()
    
    tel, router, err := gintelemetry.Start(ctx, gintelemetry.Config{
        ServiceName: "my-api",
        Endpoint:    "localhost:4317",
        Insecure:    true, // Use insecure connection for local development
        LogLevel:    gintelemetry.LevelInfo,
    })
    if err != nil {
        panic(err)
    }
    defer tel.Shutdown(ctx)

    router.GET("/hello", func(c *gin.Context) {
        ctx := c.Request.Context()
        
        // Logging with automatic trace correlation
        tel.Log().Info(ctx, "handling request")
        
        // Metrics
        tel.Metric().IncrementCounter(ctx, "requests",
            tel.Attr().String("endpoint", "hello"),
        )
        
        c.String(200, "Hello!")
    })

    router.Run(":8080")
}

Usage

Configuration

Basic (gRPC, default):

config := gintelemetry.Config{
    ServiceName: "my-service",
    Endpoint:    "localhost:4317",          // gRPC default port
    Insecure:    true,                       // Use insecure for local development
    LogLevel:    gintelemetry.LevelDebug,
}

HTTP Protocol:

config := gintelemetry.Config{
    ServiceName: "my-service",
    Endpoint:    "localhost:4318",          // HTTP default port
}.WithHTTP()

// Or explicitly
config.Protocol = gintelemetry.ProtocolHTTP

With TLS (Trusted CA):

config := gintelemetry.Config{
    ServiceName: "my-service",
}.WithTrustedCA("/path/to/ca.crt")

With mTLS (Mutual TLS):

config := gintelemetry.Config{
    ServiceName: "my-service",
}.WithMTLS(
    "/path/to/client.crt",
    "/path/to/client.key",
    "/path/to/ca.crt",
)

HTTP with TLS:

config := gintelemetry.Config{
    ServiceName: "my-service",
    Endpoint:    "localhost:4318",
}.WithHTTP().WithTrustedCA("/path/to/ca.crt")

With Global Attributes:

// Using map
config := gintelemetry.Config{
    ServiceName: "my-service",
    GlobalAttributes: map[string]string{
        "team":        "platform",
        "environment": "production",
        "region":      "us-east-1",
    },
}

// Using builder pattern
config := gintelemetry.Config{
    ServiceName: "my-service",
}.WithGlobalAttribute("team", "platform").
  WithGlobalAttribute("environment", "production").
  WithGlobalAttribute("region", "us-east-1")

// Or set all at once
config := gintelemetry.Config{
    ServiceName: "my-service",
}.WithGlobalAttributes(map[string]string{
    "team":        "platform",
    "environment": "production",
})

// Or use environment variables (no recompilation needed!)
// export OTEL_RESOURCE_ATTRIBUTES="team=platform,environment=production,region=us-east-1"
config := gintelemetry.Config{
    ServiceName: "my-service",
    // Attributes will be loaded from OTEL_RESOURCE_ATTRIBUTES
}
Logging
ctx := c.Request.Context()

tel.Log().Info(ctx, "message", "key", "value")
tel.Log().Warn(ctx, "warning")
tel.Log().Error(ctx, "error", "error", err.Error())
tel.Log().Debug(ctx, "debug info")
Tracing
// Automatic tracing for all routes (via otelgin middleware)

// Manual spans
ctx, stop := tel.Trace().StartSpan(ctx, "operation")
defer stop()

// With attributes
ctx, stop := tel.Trace().StartSpanWithAttributes(ctx, "db.query",
    tel.Attr().String("db.system", "postgres"),
    tel.Attr().Int("rows", 42),
)
defer stop()

// Add attributes
tel.Trace().SetAttributes(ctx,
    tel.Attr().String("user.id", userId),
)

// Record errors
if err != nil {
    tel.Trace().RecordError(ctx, err)
}
Metrics

Convenience Methods (Recommended):

// Counter - increment by 1
tel.Metric().IncrementCounter(ctx, "requests.total",
    tel.Attr().String("method", "GET"),
)

// Counter - add specific value
tel.Metric().AddCounter(ctx, "bytes.sent", bytesCount)

// Histogram - record value
tel.Metric().RecordHistogram(ctx, "request.duration.ms", duration)

// Duration - automatically converts to milliseconds
tel.Metric().RecordDuration(ctx, "db.query.duration", time.Since(start))

// Gauge
tel.Metric().RecordGauge(ctx, "memory.bytes", memUsed)

// Float64 variants
tel.Metric().AddFloat64Counter(ctx, "cpu.percent", 0.75)
tel.Metric().RecordFloat64Histogram(ctx, "size.mb", 2.5)
tel.Metric().RecordFloat64Gauge(ctx, "temperature", 23.5)

Direct Instrument Access (Advanced):

// For more control, get instruments directly
tel.Metric().Counter("requests.total").Add(ctx, 1,
    metric.WithAttributes(tel.Attr().String("method", "GET")),
)

tel.Metric().Histogram("request.duration.ms").Record(ctx, duration,
    metric.WithAttributes(tel.Attr().String("endpoint", "/api")),
)
Attributes

Use tel.Attr() to create attributes that work everywhere:

attrs := []attribute.KeyValue{
    tel.Attr().String("user.id", "123"),
    tel.Attr().Int("status", 200),
}

// Works for tracing
tel.Trace().SetAttributes(ctx, attrs...)

// Works for metrics
tel.Metric().IncrementCounter(ctx, "requests", attrs...)

// Available attribute types
tel.Attr().String(key, value)
tel.Attr().Int(key, value)
tel.Attr().Int64(key, value)
tel.Attr().Float64(key, value)
tel.Attr().Bool(key, value)
tel.Attr().Strings(key, []string{...})
Convenience Helpers

Measure Duration:

// Automatically records duration and handles errors
err := tel.MeasureDuration(ctx, "db.query.duration", func() error {
    return db.Query(ctx, query)
})

Trace Functions:

// Automatically creates span and records errors
err := tel.WithSpan(ctx, "process.order", func(ctx context.Context) error {
    tel.Log().Info(ctx, "processing order")
    return processOrder(ctx, orderID)
})

Understanding Context

All telemetry methods accept a context.Context for trace correlation. This allows logs, metrics, and spans to be linked together.

How It Works
// 1. Start with request context (automatically has a span from otelgin middleware)
ctx := c.Request.Context()

// 2. Log with context - automatically includes trace/span IDs
tel.Log().Info(ctx, "processing request")

// 3. Create child spans
ctx, stop := tel.Trace().StartSpan(ctx, "database.query")
defer stop()

// 4. All operations use the same context chain
tel.Log().Info(ctx, "querying database")  // Linked to "database.query" span
tel.Metric().RecordDuration(ctx, "db.latency", duration)
What If Context Has No Span?

Using context.Background() or a context without a span is safe but:

  • ✅ Logs will still be recorded
  • ✅ Metrics will still be recorded
  • ✅ Operations will not fail or panic
  • ❌ Trace correlation will be lost (logs won't link to traces)

Best Practice: Always propagate context from the request through your call chain.

Error Handling

gintelemetry is designed to never fail your application. All telemetry operations are safe and handle errors gracefully.

Silent Failures

If telemetry operations fail (e.g., logger is nil, span not recording, collector unavailable), they:

  • ✅ Return without error
  • ✅ Never panic
  • ✅ Don't block your application
  • ⚠️ May log warnings (if logger is available)
// These are all safe, even if telemetry isn't initialized properly
tel.Log().Info(ctx, "message")          // No-op if logger is nil
tel.Trace().RecordError(ctx, err)       // No-op if span not recording
tel.Metric().IncrementCounter(ctx, "x") // Falls back to no-op if creation fails
When to Check Errors

The only error you should handle is from Start() and Shutdown():

tel, router, err := gintelemetry.Start(ctx, config)
if err != nil {
    // This is a real startup error - handle it
    log.Fatalf("failed to initialize telemetry: %v", err)
}
defer tel.Shutdown(ctx)

Best Practices

Metric Naming

❌ BAD - Dynamic metric names:

// Creates a new cached metric for EVERY user!
tel.Metric().Counter("user_" + userID + "_requests").Add(ctx, 1)

✅ GOOD - Use attributes:

// Single metric with user.id attribute
tel.Metric().IncrementCounter(ctx, "user.requests",
    tel.Attr().String("user.id", userID),
)
Why Avoid Dynamic Metric Names?

Metrics are cached (up to 10,000). Dynamic names exhaust the cache and hurt performance.

Context Propagation

✅ GOOD:

func handleRequest(c *gin.Context) {
    ctx := c.Request.Context()
    
    // Pass context through call chain
    processOrder(ctx, orderID)
}

func processOrder(ctx context.Context, orderID string) error {
    tel.Log().Info(ctx, "processing order", "order_id", orderID)
    return nil
}

❌ BAD:

func processOrder(orderID string) error {
    // Lost context - no trace correlation!
    tel.Log().Info(context.Background(), "processing order")
    return nil
}

Testing

Use NewTestConfig() for easy testing without requiring a real collector:

func TestMyHandler(t *testing.T) {
    ctx := context.Background()
    
    // Creates config with no-op exporters
    tel, router, err := gintelemetry.Start(ctx, gintelemetry.NewTestConfig("test-service"))
    if err != nil {
        t.Fatalf("failed to start telemetry: %v", err)
    }
    defer tel.Shutdown(ctx)
    
    // Test your handlers
    router.GET("/test", myHandler)
    
    // Make test requests...
}

The test config:

  • Uses insecure localhost connection
  • Sets log level to Error (less noise)
  • Disables retries (fails fast)
  • Safe to use even without a collector running

Environment Variables

gintelemetry supports standard OpenTelemetry environment variables:

Variable Description Default Example
OTEL_SERVICE_NAME Service name Required (or set in Config) my-api
OTEL_EXPORTER_OTLP_ENDPOINT Collector endpoint Required (or set in Config) localhost:4317
OTEL_EXPORTER_OTLP_PROTOCOL Protocol (grpc/http) grpc grpc or http
OTEL_RESOURCE_ATTRIBUTES Global attributes None team=platform,env=prod

Example:

export OTEL_SERVICE_NAME=my-api
export OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_RESOURCE_ATTRIBUTES="team=platform,environment=production,region=us-east-1"
go run main.go
// Config fields take precedence over env vars
tel, router, _ := gintelemetry.Start(ctx, gintelemetry.Config{
    // ServiceName can come from OTEL_SERVICE_NAME env var
    // Endpoint can come from OTEL_EXPORTER_OTLP_ENDPOINT env var
    // Global attributes can come from OTEL_RESOURCE_ATTRIBUTES env var
})
Global Attributes from Environment

The OTEL_RESOURCE_ATTRIBUTES environment variable allows you to add global attributes without recompiling:

# Development
export OTEL_RESOURCE_ATTRIBUTES="team=backend,environment=dev,region=local"

# Production
export OTEL_RESOURCE_ATTRIBUTES="team=backend,environment=production,region=us-east-1,version=1.2.3"

Format: Comma-separated key=value pairs

Precedence: Config attributes override environment attributes (if both specify the same key)

Use Case: Change team, environment, region, version without rebuilding - perfect for:

  • Different deployment environments
  • Multi-tenant deployments
  • CI/CD pipelines
  • Container orchestration (Kubernetes, Docker)

Features

  • One-line setup - Start() does everything
  • Auto-instrumentation - All routes traced automatically
  • Trace correlation - Logs include trace/span IDs
  • Clean API - Log.*, Metric.*, Trace.* namespaces
  • Convenience methods - IncrementCounter, RecordDuration, WithSpan
  • Unified attributes - Attr() works across all telemetry types
  • Zero imports - Only import gintelemetry (and gin)
  • Flexible transport - Support for gRPC and HTTP protocols
  • Secure - Support for TLS and mTLS
  • Global attributes - Add team, environment, region to all telemetry
  • Testing utilities - NewTestConfig() for easy testing
  • Production-ready - Batching, resource attribution, graceful shutdown

OpenTelemetry Collector

You need an OTLP collector running. Quick start with Docker:

docker run -d --name otel-collector \
  -p 4317:4317 \
  -p 4318:4318 \
  otel/opentelemetry-collector:latest

Or use Jaeger all-in-one:

docker run -d --name jaeger \
  -p 16686:16686 \
  -p 4317:4317 \
  -e COLLECTOR_OTLP_ENABLED=true \
  jaegertracing/all-in-one:latest

Then visit http://localhost:16686 to view traces.

What You Get

Before (manual OpenTelemetry):

import (
    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/attribute"
    "go.opentelemetry.io/otel/metric"
    "go.opentelemetry.io/otel/trace"
    // ... 10+ more imports
    // ... 100+ lines of setup code
)

After (gintelemetry):

import "github.com/Levy-Tal/gintelemetry"

router, shutdown, _ := gintelemetry.Start(ctx, config)
defer shutdown(ctx)
// Done!

API Reference

Category Function Description
Setup Start(ctx, config) Initialize everything
Attributes Attr().String/Int/Bool(...) Unified attributes for all telemetry
Logging Log().Info/Warn/Error/Debug(ctx, msg, ...) Structured logging
Tracing Trace().StartSpan(ctx, name) Create spans
Trace().SetAttributes(ctx, ...) Add span attributes
Trace().RecordError(ctx, err) Record errors
WithSpan(ctx, name, fn) Execute function in span
Metrics Metric().IncrementCounter(ctx, name, ...) Increment counter
Metric().RecordDuration(ctx, name, duration, ...) Record timing
Metric().RecordHistogram(ctx, name, value, ...) Record value
Metric().RecordGauge(ctx, name, value, ...) Record gauge
Metric().Counter/Histogram/Gauge(name) Get instrument directly
Helpers MeasureDuration(ctx, name, fn) Time and trace function
Testing NewTestConfig(serviceName) Test configuration

Examples

Complete working examples with detailed explanations:

Basic Example

Simple hello world showing core features:

  • Basic setup and configuration
  • Logging with trace correlation
  • Counter metrics with attributes
  • Manual span creation
  • Convenience helpers
Database Example

Database instrumentation patterns:

  • Query tracing with timing
  • Database operation metrics
  • Error handling and recording
  • Connection pool monitoring
  • Best practices for DB instrumentation
Testing Example

How to test instrumented code:

  • Using NewTestConfig() for tests
  • Testing services with telemetry
  • HTTP handler testing
  • Concurrent request testing
  • Benchmarking instrumented code
Environment Variables Example

Configure everything via environment variables:

  • Zero hardcoded configuration
  • Global attributes from OTEL_RESOURCE_ATTRIBUTES
  • Same binary for all environments
  • Docker and Kubernetes examples
  • CI/CD friendly configuration

Each example includes:

  • Complete runnable code
  • Detailed README with explanations
  • Docker Compose for local collector
  • Common patterns and best practices

Quick Start:

cd examples/basic
docker compose up -d  # Start Jaeger
go run main.go        # Run example
# Visit http://localhost:16686 to view traces

Documentation

Requirements

  • Go 1.24+
  • OpenTelemetry Collector (or Jaeger/Grafana/etc.)

License

Apache-2.0

Documentation

Overview

Package gintelemetry provides opinionated OpenTelemetry bootstrap for Gin applications.

Index

Constants

View Source
const (
	LevelDebug = slog.LevelDebug
	LevelInfo  = slog.LevelInfo
	LevelWarn  = slog.LevelWarn
	LevelError = slog.LevelError
)
View Source
const (
	StatusUnset = codes.Unset
	StatusError = codes.Error
	StatusOK    = codes.Ok
)

Status codes for span status

Variables

This section is empty.

Functions

This section is empty.

Types

type Attribute

type Attribute = attribute.KeyValue

type AttributeAPI

type AttributeAPI struct{}

AttributeAPI provides unified attribute builders that work across all telemetry types. Attributes created with this API can be used for tracing, metrics, and logging.

func (AttributeAPI) Bool

func (AttributeAPI) Bool(key string, value bool) attribute.KeyValue

Bool creates a bool-valued attribute.

func (AttributeAPI) Float64

func (AttributeAPI) Float64(key string, value float64) attribute.KeyValue

Float64 creates a float64-valued attribute.

func (AttributeAPI) Int

func (AttributeAPI) Int(key string, value int) attribute.KeyValue

Int creates an int-valued attribute.

func (AttributeAPI) Int64

func (AttributeAPI) Int64(key string, value int64) attribute.KeyValue

Int64 creates an int64-valued attribute.

func (AttributeAPI) String

func (AttributeAPI) String(key, value string) attribute.KeyValue

String creates a string-valued attribute.

func (AttributeAPI) Strings

func (AttributeAPI) Strings(key string, values []string) attribute.KeyValue

Strings creates a string slice-valued attribute.

type Config

type Config struct {
	// ServiceName is required and reported in all telemetry data.
	ServiceName string

	// Endpoint is the OTLP collector endpoint.
	// For gRPC: "localhost:4317" (default port 4317)
	// For HTTP: "localhost:4318" (default port 4318)
	// Defaults to OTEL_EXPORTER_OTLP_ENDPOINT environment variable.
	Endpoint string

	// Protocol specifies the transport protocol (grpc or http).
	// Defaults to ProtocolGRPC.
	Protocol Protocol

	// Insecure determines whether to use a non-TLS connection.
	// Defaults to true if not explicitly set.
	// Set to false to enable TLS.
	Insecure bool

	// TLS configuration for secure connections (when Insecure = false).
	TLS *TLSConfig

	// LogLevel sets the minimum log level. Defaults to LevelInfo.
	// Use LevelDebug, LevelInfo, LevelWarn, LevelError.
	LogLevel Level

	// GlobalAttributes are added to all telemetry (traces, metrics, logs).
	// Use this for team names, environment, region, etc.
	GlobalAttributes map[string]string

	// ShutdownTimeout is the maximum time to wait for telemetry shutdown.
	// Defaults to 10 seconds if not set.
	ShutdownTimeout time.Duration

	// SetGlobalProvider controls whether to set the global OpenTelemetry provider.
	// WARNING: Setting this to true makes the telemetry system use global state,
	// which can cause issues with concurrent tests and multiple service instances.
	// Only enable this if you rely on instrumentation libraries that require the
	// global provider. The default (false) provides isolated, instance-based telemetry.
	SetGlobalProvider bool

	// ExporterRetries specifies the number of retry attempts when creating exporters.
	// This is useful in environments like Kubernetes where the collector may not be
	// immediately available. Set to 0 for no retries (fail fast), or a positive number
	// for retry attempts with exponential backoff. Defaults to 3 retries.
	ExporterRetries int
}

Config holds the configuration for initializing the telemetry stack.

func NewTestConfig

func NewTestConfig(serviceName string) Config

NewTestConfig creates a configuration suitable for testing with no-op exporters. This allows tests to run without requiring a real OTLP collector.

The returned config uses insecure connections and points to a localhost endpoint that doesn't need to exist (the exporter retries are set to 0 for fast failure).

Example:

func TestMyHandler(t *testing.T) {
    ctx := context.Background()
    tel, router, err := gintelemetry.Start(ctx, gintelemetry.NewTestConfig("test-service"))
    if err != nil {
        t.Fatalf("failed to start telemetry: %v", err)
    }
    defer tel.Shutdown(ctx)

    // Test your handlers...
    router.GET("/test", myHandler)
}

func (Config) WithExporterRetries

func (c Config) WithExporterRetries(retries int) Config

func (Config) WithGRPC

func (c Config) WithGRPC() Config

func (Config) WithGlobalAttribute

func (c Config) WithGlobalAttribute(key, value string) Config

func (Config) WithGlobalAttributes

func (c Config) WithGlobalAttributes(attrs map[string]string) Config

func (Config) WithHTTP

func (c Config) WithHTTP() Config

func (Config) WithInsecure

func (c Config) WithInsecure(insecure bool) Config

func (Config) WithLogLevel

func (c Config) WithLogLevel(level Level) Config

func (Config) WithMTLS

func (c Config) WithMTLS(certFile, keyFile, caFile string) Config

func (Config) WithNoRetry

func (c Config) WithNoRetry() Config

func (Config) WithProtocol

func (c Config) WithProtocol(protocol Protocol) Config

func (Config) WithTLS

func (c Config) WithTLS(tls *TLSConfig) Config

func (Config) WithTrustedCA

func (c Config) WithTrustedCA(caFile string) Config

type Level

type Level = slog.Level

type LogAPI

type LogAPI struct {
	// contains filtered or unexported fields
}

func (LogAPI) Debug

func (l LogAPI) Debug(ctx context.Context, msg string, args ...any)

Debug logs a debug message with trace correlation. The context should contain an active span from the request or manually created span. If ctx has no span, logs will still be recorded but without trace correlation. Using context.Background() is safe but loses correlation benefits.

Example:

tel.Log().Debug(ctx, "cache hit", "key", cacheKey, "ttl", ttl)

func (LogAPI) Error

func (l LogAPI) Error(ctx context.Context, msg string, args ...any)

Error logs an error message with trace correlation. The context should contain an active span from the request or manually created span. If ctx has no span, logs will still be recorded but without trace correlation. Using context.Background() is safe but loses correlation benefits.

Example:

tel.Log().Error(ctx, "database query failed", "error", err.Error(), "query", query)

func (LogAPI) Info

func (l LogAPI) Info(ctx context.Context, msg string, args ...any)

Info logs an informational message with trace correlation. The context should contain an active span from the request or manually created span. If ctx has no span, logs will still be recorded but without trace correlation. Using context.Background() is safe but loses correlation benefits.

Example:

tel.Log().Info(ctx, "user logged in", "user_id", userID, "ip", clientIP)

func (LogAPI) Logger

func (l LogAPI) Logger() *slog.Logger

func (LogAPI) Warn

func (l LogAPI) Warn(ctx context.Context, msg string, args ...any)

Warn logs a warning message with trace correlation. The context should contain an active span from the request or manually created span. If ctx has no span, logs will still be recorded but without trace correlation. Using context.Background() is safe but loses correlation benefits.

Example:

tel.Log().Warn(ctx, "rate limit approaching", "current", count, "limit", maxCount)

func (LogAPI) With

func (l LogAPI) With(args ...any) *slog.Logger

func (LogAPI) WithGroup

func (l LogAPI) WithGroup(name string) *slog.Logger

type MetricAPI

type MetricAPI struct {
	// contains filtered or unexported fields
}

MetricAPI provides functions for recording metrics.

IMPORTANT: Metrics are cached internally (up to 10,000 unique combinations). Do NOT use dynamic values in metric names. Use attributes instead:

✗ BAD:  tel.Metric().Counter("user_" + userID).Add(ctx, 1)
✓ GOOD: tel.Metric().IncrementCounter(ctx, "user_events", tel.Attr().String("user.id", userID))

If you exceed the cache limit, metrics will still work but won't be cached, which may impact performance.

Context Usage: All metric recording methods accept a context for trace correlation. If the context contains an active span, metrics can be correlated with traces. Using context.Background() is safe but loses correlation benefits.

func (MetricAPI) AddCounter

func (m MetricAPI) AddCounter(ctx context.Context, name string, value int64, attrs ...MetricAttribute)

AddCounter adds a value to a counter with optional attributes. This is a convenience method equivalent to Counter(name).Add(ctx, value, metric.WithAttributes(attrs...)).

func (MetricAPI) AddFloat64Counter

func (m MetricAPI) AddFloat64Counter(ctx context.Context, name string, value float64, attrs ...MetricAttribute)

AddFloat64Counter adds a value to a float64 counter with optional attributes. This is a convenience method equivalent to Float64Counter(name).Add(ctx, value, metric.WithAttributes(attrs...)).

func (MetricAPI) Counter

func (m MetricAPI) Counter(name string, opts ...metric.Int64CounterOption) metric.Int64Counter

func (MetricAPI) Float64Counter

func (m MetricAPI) Float64Counter(name string, opts ...metric.Float64CounterOption) metric.Float64Counter

func (MetricAPI) Float64Gauge

func (m MetricAPI) Float64Gauge(name string, opts ...metric.Float64GaugeOption) metric.Float64Gauge

func (MetricAPI) Float64Histogram

func (m MetricAPI) Float64Histogram(name string, opts ...metric.Float64HistogramOption) metric.Float64Histogram

func (MetricAPI) Gauge

func (m MetricAPI) Gauge(name string, opts ...metric.Int64GaugeOption) metric.Int64Gauge

func (MetricAPI) Histogram

func (m MetricAPI) Histogram(name string, opts ...metric.Int64HistogramOption) metric.Int64Histogram

func (MetricAPI) IncrementCounter

func (m MetricAPI) IncrementCounter(ctx context.Context, name string, attrs ...MetricAttribute)

IncrementCounter increments a counter by 1 with optional attributes. This is a convenience method equivalent to Counter(name).Add(ctx, 1, metric.WithAttributes(attrs...)).

func (MetricAPI) RecordDuration

func (m MetricAPI) RecordDuration(ctx context.Context, name string, duration time.Duration, attrs ...MetricAttribute)

RecordDuration records a duration as milliseconds to a histogram with optional attributes. This is a convenience method that converts the duration to milliseconds and records it.

func (MetricAPI) RecordFloat64Gauge

func (m MetricAPI) RecordFloat64Gauge(ctx context.Context, name string, value float64, attrs ...MetricAttribute)

RecordFloat64Gauge records a float64 gauge value with optional attributes. This is a convenience method equivalent to Float64Gauge(name).Record(ctx, value, metric.WithAttributes(attrs...)).

func (MetricAPI) RecordFloat64Histogram

func (m MetricAPI) RecordFloat64Histogram(ctx context.Context, name string, value float64, attrs ...MetricAttribute)

RecordFloat64Histogram records a float64 histogram value with optional attributes. This is a convenience method equivalent to Float64Histogram(name).Record(ctx, value, metric.WithAttributes(attrs...)).

func (MetricAPI) RecordGauge

func (m MetricAPI) RecordGauge(ctx context.Context, name string, value int64, attrs ...MetricAttribute)

RecordGauge records a gauge value with optional attributes. This is a convenience method equivalent to Gauge(name).Record(ctx, value, metric.WithAttributes(attrs...)).

func (MetricAPI) RecordHistogram

func (m MetricAPI) RecordHistogram(ctx context.Context, name string, value int64, attrs ...MetricAttribute)

RecordHistogram records a histogram value with optional attributes. This is a convenience method equivalent to Histogram(name).Record(ctx, value, metric.WithAttributes(attrs...)).

type MetricAttribute

type MetricAttribute = attribute.KeyValue

type Protocol

type Protocol string

Protocol defines the transport protocol for OTLP exporters.

const (
	// ProtocolGRPC uses gRPC for OTLP transport (default).
	ProtocolGRPC Protocol = "grpc"

	// ProtocolHTTP uses HTTP/protobuf for OTLP transport.
	ProtocolHTTP Protocol = "http"
)

type TLSConfig

type TLSConfig struct {
	CertFile           string
	KeyFile            string
	CAFile             string
	InsecureSkipVerify bool
}

type Telemetry

type Telemetry struct {
	// contains filtered or unexported fields
}

func Start

func Start(ctx context.Context, cfg Config) (*Telemetry, *gin.Engine, error)

func (*Telemetry) Attr

func (t *Telemetry) Attr() AttributeAPI

Attr returns the unified attribute builder for use across all telemetry types. Attributes created with this API work for tracing, metrics, and logging.

Example:

attrs := []attribute.KeyValue{
    tel.Attr().String("user.id", "123"),
    tel.Attr().Int("status", 200),
}
tel.Trace().SetAttributes(ctx, attrs...)
tel.Metric().Counter("requests").Add(ctx, 1, metric.WithAttributes(attrs...))

func (*Telemetry) Flush

func (t *Telemetry) Flush(ctx context.Context) error

func (*Telemetry) Log

func (t *Telemetry) Log() LogAPI

func (*Telemetry) LoggerProvider

func (t *Telemetry) LoggerProvider() *sdklog.LoggerProvider

func (*Telemetry) MeasureDuration

func (t *Telemetry) MeasureDuration(ctx context.Context, metricName string, fn func() error) error

MeasureDuration executes fn and records its duration to a histogram metric. If fn returns an error, it's automatically recorded in the current span (if one exists).

Example:

err := tel.MeasureDuration(ctx, "db.query.duration", func() error {
    return db.Query(ctx, ...)
})

func (*Telemetry) MeterProvider

func (t *Telemetry) MeterProvider() *sdkmetric.MeterProvider

func (*Telemetry) Metric

func (t *Telemetry) Metric() MetricAPI

func (*Telemetry) Shutdown

func (t *Telemetry) Shutdown(ctx context.Context) error

func (*Telemetry) ShutdownDone

func (t *Telemetry) ShutdownDone() <-chan struct{}

func (*Telemetry) Trace

func (t *Telemetry) Trace() TraceAPI

func (*Telemetry) TraceFunction

func (t *Telemetry) TraceFunction(ctx context.Context, spanName string, fn func(context.Context) error) error

TraceFunction creates a span, executes fn with the span context, and ends the span. Errors returned by fn are automatically recorded in the span.

Example:

err := tel.TraceFunction(ctx, "process.order", func(ctx context.Context) error {
    tel.Log().Info(ctx, "processing order")
    return processOrder(ctx, orderID)
})

func (*Telemetry) TracerProvider

func (t *Telemetry) TracerProvider() *sdktrace.TracerProvider

func (*Telemetry) WithSpan

func (t *Telemetry) WithSpan(ctx context.Context, spanName string, fn func(context.Context) error) error

WithSpan creates a span, executes fn with the span context, and ends the span. This is an alias for TraceFunction for more ergonomic usage.

Example:

err := tel.WithSpan(ctx, "database.query", func(ctx context.Context) error {
    return db.Query(ctx, query)
})

type TraceAPI

type TraceAPI struct {
	// contains filtered or unexported fields
}

func (TraceAPI) AddEvent

func (TraceAPI) AddEvent(ctx context.Context, name string, attrs ...Attribute)

AddEvent adds an event to the current span if one exists and is recording. Events represent significant points in time within a span's duration. If no span exists or the span is not recording, this is a safe no-op.

Example:

tel.Trace().AddEvent(ctx, "cache.miss",
    tel.Attr().String("cache.key", key),
)

func (TraceAPI) RecordError

func (TraceAPI) RecordError(ctx context.Context, err error)

RecordError records an error in the current span if one exists and is recording. If no span exists or the span is not recording, this is a safe no-op. This method never returns an error itself and never panics.

The error is recorded with the span status set to Error.

Example:

if err != nil {
    tel.Trace().RecordError(ctx, err)
    return err
}

func (TraceAPI) SetAttributes

func (TraceAPI) SetAttributes(ctx context.Context, attrs ...Attribute)

SetAttributes adds attributes to the current span if one exists and is recording. If no span exists or the span is not recording, this is a safe no-op. The context must contain an active span for attributes to be recorded.

Example:

tel.Trace().SetAttributes(ctx,
    tel.Attr().String("user.id", userID),
    tel.Attr().Int("items.count", len(items)),
)

func (TraceAPI) SetStatus

func (TraceAPI) SetStatus(ctx context.Context, code codes.Code, description string)

SetStatus sets the status of the current span if one exists and is recording. Use this to mark a span as successful (StatusOK), failed (StatusError), or unset (StatusUnset). If no span exists or the span is not recording, this is a safe no-op.

Example:

tel.Trace().SetStatus(ctx, gintelemetry.StatusOK, "operation completed successfully")

func (TraceAPI) SpanFromContext

func (TraceAPI) SpanFromContext(ctx context.Context) trace.Span

SpanFromContext returns the current span from the context. This is useful for advanced use cases where you need direct access to the span.

func (TraceAPI) StartSpan

func (t TraceAPI) StartSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, func())

StartSpan creates a new span and returns a context containing the span and a function to end it. The returned context should be used for all operations within this span's scope. Always call the returned function (typically with defer) to properly end the span.

Example:

ctx, stop := tel.Trace().StartSpan(ctx, "database.query")
defer stop()
// ... perform database query ...

func (TraceAPI) StartSpanWithAttributes

func (t TraceAPI) StartSpanWithAttributes(ctx context.Context, name string, attrs ...Attribute) (context.Context, func())

StartSpanWithAttributes creates a new span with attributes and returns a context and end function. This is a convenience method that combines StartSpan with initial attributes.

Example:

ctx, stop := tel.Trace().StartSpanWithAttributes(ctx, "db.query",
    tel.Attr().String("db.system", "postgres"),
    tel.Attr().String("db.operation", "SELECT"),
)
defer stop()

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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