middleware

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultRequestIDHeader = "X-Request-ID"

DefaultRequestIDHeader is the default header name where the request ID is stored.

Variables

This section is empty.

Functions

func CircuitBreaker

func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc

CircuitBreaker creates a Gin middleware that wraps route handlers with a circuit breaker.

This middleware monitors request failures and automatically trips the circuit breaker when failures exceed a configured threshold. Once tripped, requests are blocked and a fallback error response is returned until the circuit breaker recovers.

Features:

  • Failure Detection: Automatically detects failures based on HTTP status codes or custom logic.
  • Customizable Behavior: Configure the circuit breaker settings, error thresholds, and fallback handlers.
  • Selective Application: Use filters to apply the circuit breaker only to specific routes or requests.

Example Usage:

CircuitBreaker(
	WithCircuitBreakerSettings(gobreaker.Settings{
		Name: "CustomCircuitBreaker",
		ReadyToTrip: func(counts gobreaker.Counts) bool {
			return counts.ConsecutiveFailures > 3 // Trip after 3 consecutive failures.
		},
	}),
	WithCircuitBreakerStatusThreshold(http.StatusBadRequest), // Treat >= 400 as errors.
	WithCircuitBreakerErrorHandler(func(c *gin.Context) {
		// Custom error handler for circuit breaker failures.
		c.AbortWithStatusJSON(http.StatusServiceUnavailable, gin.H{
			"error": "Custom error: Circuit breaker activated.",
		})
	}),
	WithCircuitBreakerFilter(func(req *http.Request) bool {
		return req.URL.Path != "/health" // Skip circuit breaker for health checks.
	}),
),

func ConfigureDefaultMiddlewares added in v0.11.0

func ConfigureDefaultMiddlewares(config DefaultMiddlewareConfig) []gin.HandlerFunc

ConfigureDefaultMiddlewares returns a standardized middleware chain for common HTTP concerns. The chain includes recovery, circuit breaker, tracing, request ID, logging, and metrics in an order optimized for proper request handling and observability.

Middleware Chain:

  • Recovery: Recovers from panics and returns a 500 Internal Server Error response.
  • CircuitBreaker: Monitors request failures and may trip to protect the service.
  • Trace: Instruments incoming requests with OpenTelemetry spans if a TracerProvider is given.
  • RequestID: Ensures each request has a unique identifier (injected in the header and context).
  • RequestLogger: Logs incoming requests with metadata such as method, route, and status code.
  • Prometheus: Exposes metrics for monitoring and alerting via Prometheus.

The behavior of certain middlewares (e.g., tracing, logging) is influenced by the fields in DefaultMiddlewareConfig. If the TracerProvider is nil, the global trace provider is used. If the Logger is nil, a default logger is used.

Example usage:

cfg := DefaultMiddlewareConfig{
  Logger:         myLogger,
  TracerProvider: myTracerProvider,
}

router := gin.New()
router.Use(ConfigureDefaultMiddlewares(cfg)...)

func GetRequestIDFromContext

func GetRequestIDFromContext(ctx context.Context) (string, bool)

GetRequestIDFromContext retrieves the request ID from the provided context. Used by downstream handlers and middleware to access the request correlation ID.

func MetricsHandler added in v0.15.0

func MetricsHandler() gin.HandlerFunc

MetricsHandler exposes the Prometheus `/metrics` endpoint as a Gin handler. Returns all registered metrics in Prometheus exposition format for scraping by Prometheus servers or compatible monitoring systems.

Returns:

  • gin.HandlerFunc: Handler that serves Prometheus metrics endpoint

Example:

router.GET("/metrics", middleware.MetricsHandler())

func Prometheus added in v0.15.0

func Prometheus(serviceName string) gin.HandlerFunc

Prometheus returns Gin middleware that collects HTTP metrics for Prometheus monitoring. Captures request counts, latencies, and payload sizes with detailed labeling for comprehensive HTTP traffic observability and performance monitoring.

Collected Metrics:

  • Request count: Total requests segmented by status/method/path
  • Request duration: Latency histogram for performance monitoring
  • Request size: Payload size distribution for bandwidth analysis
  • Response size: Response payload size distribution

Parameters:

  • serviceName: Namespace prefix for metrics (empty string for no prefix)

Returns:

  • gin.HandlerFunc: Middleware that captures metrics for each request

Example:

router := gin.Default()
router.Use(middleware.Prometheus("service_name"))
router.GET("/metrics", middleware.MetricsHandler())

func Recovery

func Recovery(opts ...RecoveryOption) gin.HandlerFunc

Recovery returns a Gin middleware that recovers from panics during request handling and logs the error.

The middleware performs the following tasks:

  1. Recovers from any panic that occurs in the middleware chain or route handlers.
  2. Logs the panic information (including HTTP method and route) using the provided logger or retrieves one from the context.
  3. Calls a custom error handler to generate a response, or defaults to a 500 Internal Server Error response if no custom handler is provided.

Key Features:

  • Custom Logger: Use `WithRecoveryLogger` to specify a logger for capturing panic details. If no logger is provided, the middleware attempts to retrieve one from the context.
  • Custom Error Handler: Use `WithRecoveryHandler` to define a custom function for handling the panic and responding to the client.
  • Default Behavior: If no logger or custom handler is specified, the middleware logs the panic (using the context logger) and returns a 500 Internal Server Error response.

Example Usage:

router.Use(
	Recovery(
    	WithRecoveryLogger(logger), // Use a custom logger for panic recovery.
    	WithRecoveryHandler(func(c *gin.Context, err interface{}) {
        	// Custom error handling logic (e.g., custom JSON response).
        	c.AbortWithStatusJSON(
				http.StatusInternalServerError,
				gin.H{"message": "Something went wrong. Please contact support.", "details": err}
			)
    	}),
	),
)

func RequestID

func RequestID(opts ...RequestIDOption) gin.HandlerFunc

RequestID returns Gin middleware that manages unique request identifiers for HTTP requests. Extracts existing request IDs from headers or generates new ones, then injects them into the request context and response headers for distributed tracing and correlation.

The middleware performs the following tasks:

  1. Extracts the request ID from the incoming request headers using the specified header name (default: "X-Request-ID").
  2. Validates the request ID to ensure it is not empty and does not exceed 64 characters. If invalid or missing, it generates a new request ID using the provided or default generator function.
  3. Sets the request ID in the response headers so that the client knows which request ID was assigned.
  4. Stores the request ID in the request context, making it accessible to downstream middlewares and handlers.

Key Features:

  • Custom Header Name: Use `WithRequestIDHeader` to specify a custom header name for the request ID.
  • Custom ID Generator: Use `WithRequestIDGenerator` or `WithRequestIDContextGenerator` to provide a custom generator function for creating request IDs.
  • Default Generator: By default, the middleware uses the `xid` package to generate compact and globally unique request IDs.
  • Request Context Integration: The request ID is injected into the context, enabling downstream handlers to retrieve it using `GetRequestIDFromContext`.

Example Usage:

router.Use(
	RequestID(
    	WithRequestIDHeader("X-Custom-Request-ID"), // Use a custom header name.
    	WithRequestIDGenerator(func() string {     // Use a custom generator function.
        	return "custom-" + xid.New().String()
    	}),
	),
)

func RequestLogger

func RequestLogger(opts ...RequestLoggerOption) gin.HandlerFunc

RequestLogger returns Gin middleware that logs detailed HTTP request and response information. Captures comprehensive request metadata, measures response times, and injects an enhanced logger with request context into the request for downstream handlers to use.

Functionality:

  • Logs request details, such as method, route, query parameters, client IP, and user agent.
  • Measures and logs the request latency and response status code.
  • Allows filtering of requests to determine whether they should be logged.
  • Injects an augmented logger with request-specific fields into the request context for downstream use.

Key Features:

  • Custom Logger: Use `WithRequestLogger` to provide a custom logger. If not provided, a default logger is used.
  • Request Filters: Use `WithRequestLoggerFilter` to specify one or more filters. Requests that do not pass the filters will not be logged.
  • Request Context Integration: The middleware adds an augmented logger to the request context, allowing downstream handlers to use it for logging.

Example Usage:

router.Use(
	RequestLogger(
		WithRequestLogger(customLogger), // Use a custom logger.
		WithRequestLoggerFilter(func(req *http.Request) bool {
			// Skip logging for health check routes.
			return req.URL.Path != "/health"
		}),
	),
)

func Trace

func Trace(options ...TraceOption) gin.HandlerFunc

Trace returns Gin middleware that integrates OpenTelemetry distributed tracing. Creates spans for HTTP requests, propagates trace context, and captures comprehensive request attributes for distributed system observability and performance monitoring.

The middleware performs the following actions:

  1. Initializes tracing options using the provided TraceOption functions or falls back to defaults. - If no tracer provider is provided, it uses the global tracer provider from OpenTelemetry. - If no propagators are specified, it uses the global text map propagators.
  2. Applies user-defined filters to determine whether a request should be traced.
  3. Extracts tracing context from the incoming request headers using the specified propagators.
  4. Determines the span name using a custom formatter or defaults to "<METHOD> <PATH>".
  5. Creates a new span and adds common HTTP attributes to the span (e.g., method, path, client IP).
  6. Passes the span context through the request for use by downstream handlers and middlewares.
  7. Records errors and sets the span status based on the HTTP response status code.
  8. Ends the span once the request processing is complete.

Example Usage:

// Basic usage with defaults
router.Use(Trace())

// Custom configuration
router.Use(Trace(
    WithTracerProvider(myTracerProvider),
    WithTraceFilter(func(req *http.Request) bool {
        return req.URL.Path != "/health" // Skip health checks
    }),
    WithSpanNameFormatter(func(req *http.Request) string {
        return fmt.Sprintf("api-service %s %s", req.Method, req.URL.Path)
    }),
))

Types

type CircuitBreakerFilter

type CircuitBreakerFilter func(*http.Request) bool

CircuitBreakerFilter is a function that determines whether a request should be wrapped by the circuit breaker.

type CircuitBreakerOption

type CircuitBreakerOption func(*circuitBreakerOptions)

CircuitBreakerOption is a function that configures circuitBreakerOptions.

func WithCircuitBreakerErrorHandler

func WithCircuitBreakerErrorHandler(handler func(c *gin.Context)) CircuitBreakerOption

WithCircuitBreakerErrorHandler sets a custom error response handler for circuit breaker failures. Called when circuit breaker is open and requests are being rejected.

func WithCircuitBreakerFilter

func WithCircuitBreakerFilter(filters ...CircuitBreakerFilter) CircuitBreakerOption

WithCircuitBreakerFilter adds one or more filters to determine whether the circuit breaker applies to specific requests.

func WithCircuitBreakerSettings

func WithCircuitBreakerSettings(settings gobreaker.Settings) CircuitBreakerOption

WithCircuitBreakerSettings allows customizing the circuit breaker settings.

func WithCircuitBreakerStatusThreshold

func WithCircuitBreakerStatusThreshold(threshold int) CircuitBreakerOption

WithCircuitBreakerStatusThreshold sets the HTTP status code threshold for error detection. HTTP responses with status codes >= threshold are considered failures.

type DefaultMiddlewareConfig added in v0.11.0

type DefaultMiddlewareConfig struct {
	// Logger provides custom logging for recovery and request logging middleware.
	// If nil, middleware will use default logger implementations.
	Logger common_logger.Logger

	// TracerProvider enables distributed tracing for request instrumentation.
	// If nil, the global OpenTelemetry trace provider is used.
	TracerProvider trace.TracerProvider
}

DefaultMiddlewareConfig holds configuration options for the default middleware chain.

type RecoveryOption

type RecoveryOption func(*recoveryOptions)

RecoveryOptions is a function that configures recoveryOptions.

func WithRecoveryHandler

func WithRecoveryHandler(handler func(c *gin.Context, err interface{})) RecoveryOption

WithRecoveryHandler sets a custom error handler for panic responses. Allows custom error formatting, additional context, or specialized error responses.

func WithRecoveryLogger

func WithRecoveryLogger(logger common_logger.Logger) RecoveryOption

WithRecoveryLogger sets a custom logger for panic recovery logging. If not provided, the middleware retrieves a logger from the request context.

type RequestIDContextGenerator added in v0.11.0

type RequestIDContextGenerator func(c *gin.Context) string

RequestIDContextGenerator generates unique request IDs using Gin context information. Enables context-aware ID generation based on request properties like headers, IP, etc.

Parameters:

  • c: Gin context with request information

Returns:

  • string: Unique request identifier

Example:

func contextAwareGenerator(c *gin.Context) string {
    userID := c.GetHeader("User-ID")
    return fmt.Sprintf("user-%s-req-%s", userID, xid.New().String())
}

type RequestIDGenerator

type RequestIDGenerator func() string

RequestIDGenerator generates unique request IDs without context dependencies. Simple function type for stateless ID generation.

Returns:

  • string: Unique request identifier

Example:

func customGenerator() string {
    return fmt.Sprintf("req-%d-%s", time.Now().Unix(), uuid.NewString())
}

type RequestIDOption

type RequestIDOption func(*requestIDOptions)

RequestIDOption is a function that configures the requestIDOptions.

func WithRequestIDContextGenerator added in v0.11.0

func WithRequestIDContextGenerator(gen RequestIDContextGenerator) RequestIDOption

WithRequestIDContextGenerator sets a context-aware ID generator function. Enables ID generation based on request properties like headers, user info, or route data.

func WithRequestIDGenerator

func WithRequestIDGenerator(gen RequestIDGenerator) RequestIDOption

WithRequestIDGenerator sets a simple ID generator function without context dependencies. Suitable for stateless ID generation using external libraries or custom algorithms.

func WithRequestIDHeader

func WithRequestIDHeader(headerName string) RequestIDOption

WithRequestIDHeader sets a custom HTTP header name for request ID extraction and injection. Useful when integrating with systems that use different header conventions.

type RequestLoggerFilter

type RequestLoggerFilter func(*http.Request) bool

RequestLoggerFilter determines whether a request should be logged. Returns true to log the request, false to skip logging entirely.

type RequestLoggerOption

type RequestLoggerOption func(*requestLoggerOptions)

RequestLoggerOption is a function that configures requestLoggerOptions.

func WithRequestLogger

func WithRequestLogger(logger common_logger.Logger) RequestLoggerOption

WithRequestLogger sets a custom logger for the request logger middleware. If not provided, the middleware uses the default logger from the logger package.

func WithRequestLoggerFilter

func WithRequestLoggerFilter(filters ...RequestLoggerFilter) RequestLoggerOption

WithRequestLoggerFilter adds request filters for selective logging. All filters must return true for a request to be logged.

type SpanNameFormatter

type SpanNameFormatter func(*http.Request) string

SpanNameFormatter generates custom span names based on HTTP request information. Enables context-aware span naming for better trace organization and filtering.

type TraceFilter

type TraceFilter func(*http.Request) bool

TraceFilter determines whether a request should be traced. Returns true to create a span for the request, false to skip tracing entirely.

type TraceOption

type TraceOption func(*traceOptions)

TraceOption specifies instrumentation configuration options.

func WithSpanNameFormatter

func WithSpanNameFormatter(formatter SpanNameFormatter) TraceOption

WithSpanNameFormatter sets a custom function to format the span name for each request.

func WithTraceFilter

func WithTraceFilter(filters ...TraceFilter) TraceOption

WithTraceFilter adds request filters for selective tracing. All filters must return true for a request to be traced.

func WithTracePropagators

func WithTracePropagators(propagators propagation.TextMapPropagator) TraceOption

WithTracePropagators specifies propagators to use for extracting information from the HTTP requests.

func WithTracerProvider

func WithTracerProvider(provider oteltrace.TracerProvider) TraceOption

WithTracerProvider sets a custom tracer provider for span creation.

Jump to

Keyboard shortcuts

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