Skip to Content

Observability

The observability package provides instrumentation for monitoring and tracing Gofasta applications. It integrates Prometheus for metrics collection and OpenTelemetry for distributed tracing.

Import

import "github.com/gofastadev/gofasta/pkg/observability"

Key Types

MetricsConfig

type MetricsConfig struct { Enabled bool `yaml:"enabled" env:"METRICS_ENABLED"` Path string `yaml:"path" env:"METRICS_PATH"` Namespace string `yaml:"namespace" env:"METRICS_NAMESPACE"` }

TracingConfig

type TracingConfig struct { Enabled bool `yaml:"enabled" env:"TRACING_ENABLED"` Exporter string `yaml:"exporter" env:"TRACING_EXPORTER"` Endpoint string `yaml:"endpoint" env:"TRACING_ENDPOINT"` ServiceName string `yaml:"service_name" env:"TRACING_SERVICE_NAME"` SamplingRate float64 `yaml:"sampling_rate" env:"TRACING_SAMPLING_RATE"` }

Metrics

type Metrics struct { HTTPRequestsTotal *prometheus.CounterVec HTTPRequestDuration *prometheus.HistogramVec HTTPResponseSize *prometheus.HistogramVec ActiveConnections prometheus.Gauge DBQueryDuration *prometheus.HistogramVec CacheHits *prometheus.CounterVec CacheMisses *prometheus.CounterVec QueueJobsProcessed *prometheus.CounterVec QueueJobDuration *prometheus.HistogramVec }

Key Functions

FunctionSignatureDescription
NewMetricsfunc NewMetrics(cfg MetricsConfig) *MetricsCreates and registers Prometheus metrics
MetricsHandlerfunc MetricsHandler() http.HandlerReturns the Prometheus metrics HTTP handler
MetricsMiddlewarefunc MetricsMiddleware(m *Metrics) func(http.Handler) http.HandlerMiddleware that records HTTP request metrics
InitTracerfunc InitTracer(cfg TracingConfig) (func(context.Context) error, error)Initializes the OpenTelemetry tracer and returns a shutdown function
SpanFromContextfunc SpanFromContext(ctx context.Context) trace.SpanRetrieves the current span from context
StartSpanfunc StartSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span)Creates a new child span
TracingMiddlewarefunc TracingMiddleware(serviceName string) func(http.Handler) http.HandlerMiddleware that creates spans for HTTP requests

Usage

Setting Up Metrics

metrics := observability.NewMetrics(observability.MetricsConfig{ Enabled: true, Path: "/metrics", Namespace: "myapp", }) // Expose the metrics endpoint mux.Handle("GET /metrics", observability.MetricsHandler()) // Add metrics middleware to record HTTP request data handler := observability.MetricsMiddleware(metrics)(mux)

Custom Metrics

// Increment a counter metrics.HTTPRequestsTotal.WithLabelValues("GET", "/api/users", "200").Inc() // Observe a duration timer := prometheus.NewTimer(metrics.HTTPRequestDuration.WithLabelValues("GET", "/api/users")) defer timer.ObserveDuration() // Track cache hits/misses metrics.CacheHits.WithLabelValues("users").Inc() metrics.CacheMisses.WithLabelValues("sessions").Inc()

Setting Up Tracing

shutdown, err := observability.InitTracer(observability.TracingConfig{ Enabled: true, Exporter: "otlp", // "otlp", "jaeger", or "stdout" Endpoint: "localhost:4317", ServiceName: "my-service", SamplingRate: 0.5, // Sample 50% of traces }) if err != nil { log.Fatalf("failed to init tracer: %v", err) } defer shutdown(ctx) // Add tracing middleware handler := observability.TracingMiddleware("my-service")(mux)

Creating Spans

func (s *UserService) Create(ctx context.Context, input CreateUserInput) (*User, error) { ctx, span := observability.StartSpan(ctx, "UserService.Create") defer span.End() span.SetAttributes( attribute.String("user.email", input.Email), attribute.String("user.role", input.Role), ) user, err := s.repo.Create(ctx, input) if err != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error()) return nil, err } return user, nil }

Database Query Tracing

func (r *UserRepository) FindByID(ctx context.Context, id string) (*User, error) { ctx, span := observability.StartSpan(ctx, "UserRepository.FindByID") defer span.End() timer := prometheus.NewTimer(r.metrics.DBQueryDuration.WithLabelValues("FindByID")) defer timer.ObserveDuration() var user User err := r.db.WithContext(ctx).First(&user, "id = ?", id).Error return &user, err }

Configuration via config.yaml

observability: metrics: enabled: true path: /metrics namespace: myapp tracing: enabled: true exporter: otlp endpoint: localhost:4317 service_name: my-service sampling_rate: 1.0
  • Logger — Structured logging complements metrics and traces
  • Health — Health endpoints alongside metrics
  • Middleware — Apply observability middleware to routes
Last updated on