observability

package module
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2026 License: MIT Imports: 30 Imported by: 0

README

GitHub Release Coveralls GitHub License Open in DevContainer

go-observability

Go Observability

Lightweight observability building blocks for Go microservices.

go-observability provides a compact, opinionated set of helpers for:

  • Configuration loading and validation (BaseConfig, environment and LDFlags support)
  • Structured JSON logging powered by Zap
  • OpenTelemetry integration (tracing + metrics) with sensible defaults
  • Gin middleware and gRPC interceptors for tracing, logging and panic recovery

Documentation

Comprehensive documentation and examples are published in the docs/ folder and the project site:

  • Docs folder: docs/index.md
  • Local preview: run task docs-serve (see Taskfile.yml)

Quick start

Install the library and use it in your service by embedding observability.BaseConfig and calling observability.LoadCfg, observability.NewLogger and observability.InitOtel during startup. See full examples in the examples/ directory.

Examples

Hands-on examples are available under examples/:

  • examples/gin-example — Gin middleware demo (route skipping, panic recovery, metrics)
  • examples/gin-service — Simple Gin service
  • examples/grpc-service — gRPC server with interceptors and grpcurl examples
  • examples/simple-service — Minimal example with /ping

Development & docs workflow

Use the provided Taskfile for common tasks:

# Install docs tools locally (recommended: pipx)
task docs-install-pipx

# Serve docs locally
task docs-serve

# Run linters and tests
task lint
task analysis
task test

Contributing

See CONTRIBUTING.md and docs/contributing.md for contribution guidelines, PR templates and code review expectations.

License

This project is licensed under the terms in the LICENSE file.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ServiceName = ""
	Version     = "dev"
	BuildTime   = "unknown"
)

Global build metadata (injected via LDFlags)

Functions

func GetBuildTime

func GetBuildTime() string

func GetMeter

func GetMeter(name string) metric.Meter

GetMeter returns a meter instance

func GetServiceName

func GetServiceName() string

Accessor helpers for build metadata. Using functions avoids potential typecheck issues for tools that evaluate package symbols differently.

func GetTracer

func GetTracer(name string) trace.Tracer

GetTracer returns a tracer instance

func GetVersion

func GetVersion() string

func GinLogger

func GinLogger(logger *Logger) gin.HandlerFunc

GinLogger middleware logs HTTP requests with OpenTelemetry trace context

func GinLoggerWithConfig

func GinLoggerWithConfig(logger *Logger, cfg *ObservabilityMiddlewareConfig) gin.HandlerFunc

GinLoggerWithConfig middleware logs HTTP requests with OpenTelemetry trace context and skip configuration

func GinMiddleware

func GinMiddleware(logger *Logger, serviceName string) []gin.HandlerFunc

GinMiddleware combines tracing, recovery, and logging middleware Usage: router.Use(observability.GinMiddleware(logger, "service-name")...)

func GinMiddlewareWithConfig

func GinMiddlewareWithConfig(logger *Logger, serviceName string, cfg *ObservabilityMiddlewareConfig) []gin.HandlerFunc

GinMiddlewareWithConfig combines tracing, recovery, and logging middleware with skip configuration Usage: router.Use(observability.GinMiddlewareWithConfig(logger, "service-name", cfg)...)

func GinRecovery

func GinRecovery(logger *Logger) gin.HandlerFunc

GinRecovery middleware recovers from panics and returns structured error responses

func GinRecoveryWithConfig

func GinRecoveryWithConfig(logger *Logger, cfg *ObservabilityMiddlewareConfig) gin.HandlerFunc

GinRecoveryWithConfig middleware recovers from panics and returns structured error responses with skip configuration

func GinTracing

func GinTracing(serviceName string) gin.HandlerFunc

GinTracing middleware creates OpenTelemetry spans for HTTP requests

func GinTracingWithConfig

func GinTracingWithConfig(serviceName string, cfg *ObservabilityMiddlewareConfig) gin.HandlerFunc

GinTracingWithConfig middleware creates OpenTelemetry spans for HTTP requests with skip configuration

func GrpcStreamInterceptors

func GrpcStreamInterceptors(logger *Logger) []grpc.StreamServerInterceptor

GrpcStreamInterceptors returns a chain of stream interceptors (recovery + logging) Usage: grpc.NewServer(grpc.ChainStreamInterceptor(observability.GrpcStreamInterceptors(logger)...))

func GrpcStreamRecoveryInterceptor

func GrpcStreamRecoveryInterceptor(logger *Logger) grpc.StreamServerInterceptor

GrpcStreamRecoveryInterceptor recovers from panics in gRPC streaming handlers

func GrpcStreamServerInterceptor

func GrpcStreamServerInterceptor(logger *Logger) grpc.StreamServerInterceptor

GrpcStreamServerInterceptor logs gRPC streaming requests with OpenTelemetry trace context

func GrpcUnaryInterceptors

func GrpcUnaryInterceptors(logger *Logger) []grpc.UnaryServerInterceptor

GrpcUnaryInterceptors returns a chain of unary interceptors (recovery + logging) Usage: grpc.NewServer(grpc.ChainUnaryInterceptor(observability.GrpcUnaryInterceptors(logger)...))

func GrpcUnaryRecoveryInterceptor

func GrpcUnaryRecoveryInterceptor(logger *Logger) grpc.UnaryServerInterceptor

GrpcUnaryRecoveryInterceptor recovers from panics in gRPC unary handlers

func GrpcUnaryServerInterceptor

func GrpcUnaryServerInterceptor(logger *Logger) grpc.UnaryServerInterceptor

GrpcUnaryServerInterceptor logs gRPC unary requests with OpenTelemetry trace context

func InitOtel

func InitOtel(cfg BaseConfig) (func(context.Context) error, error)

InitOtel initializes OpenTelemetry with support for Tracing (Push) and Metrics (Pull/Push/Hybrid)

func LoadCfg

func LoadCfg(cfg any) error

Types

type BaseConfig

type BaseConfig struct {
	ServiceName           string `env:"SERVICE_NAME"`
	Version               string
	BuildTime             string
	LogLevel              string  `env:"LOG_LEVEL" env-default:"info"`
	OtelEndpoint          string  `env:"OTEL_ENDPOINT" env-default:"localhost:4318"`
	MetricsPort           int     `env:"METRICS_PORT" env-default:"9090"`
	OtelTracingSampleRate float64 `env:"OTEL_TRACING_SAMPLE_RATE" env-default:"1.0"`
	MetricsMode           string  `env:"METRICS_MODE" env-default:"pull"`
	MetricsPath           string  `env:"METRICS_PATH" env-default:"/metrics"`
	MetricsPushEndpoint   string  `env:"METRICS_PUSH_ENDPOINT"`
	MetricsPushInterval   int     `env:"METRICS_PUSH_INTERVAL" env-default:"30"`
	MetricsProtocol       string  `env:"METRICS_PROTOCOL" env-default:"http"`
}

func (*BaseConfig) IsHybrid

func (b *BaseConfig) IsHybrid() bool

IsHybrid returns true if MetricsMode is "hybrid"

func (*BaseConfig) IsPull

func (b *BaseConfig) IsPull() bool

IsPull returns true if MetricsMode is "pull" or "hybrid"

func (*BaseConfig) IsPush

func (b *BaseConfig) IsPush() bool

IsPush returns true if MetricsMode is "push" or "hybrid"

func (*BaseConfig) SetMetadata

func (b *BaseConfig) SetMetadata(s, v, t string)

type ErrorResponse

type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
	TraceID string `json:"trace_id,omitempty"`
	Path    string `json:"path,omitempty"`
}

ErrorResponse represents the JSON error response structure

type Logger

type Logger struct {
	*zap.SugaredLogger
}

func NewLogger

func NewLogger(cfg *BaseConfig) *Logger

func (*Logger) Debug

func (l *Logger) Debug(msg string, args ...any)

func (*Logger) Error

func (l *Logger) Error(msg string, args ...any)

func (*Logger) Fatal

func (l *Logger) Fatal(msg string, args ...any)

func (*Logger) Info

func (l *Logger) Info(msg string, args ...any)

Helper methods for logging

func (*Logger) Sync

func (l *Logger) Sync()

func (*Logger) Warn

func (l *Logger) Warn(msg string, args ...any)

type MetadataSetter

type MetadataSetter interface {
	SetMetadata(serviceName, version, buildTime string)
}

type ObservabilityMiddlewareConfig

type ObservabilityMiddlewareConfig struct {
	// ExcludedPaths is a list of paths to exclude from observability tracking
	ExcludedPaths []string
	// SkipRoute is a custom predicate function to determine if a route should be skipped
	// If both ExcludedPaths and SkipRoute are set, SkipRoute takes precedence
	SkipRoute func(path string) bool
}

ObservabilityMiddlewareConfig holds configuration for observability middleware

Jump to

Keyboard shortcuts

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