Go + Ginのmiddlewareの仕組みを使って実現する。
middlewareの仕組みはこちらに記載
adapter/http/middleware/request_id.go
package middleware
import (
	"context"
	"github.com/gin-gonic/gin"
	"hoge/constants"
)
func RequestIDMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		requestID := c.Request.Header.Get("X-Request-ID")
		ctx := c.Request.Context()
		ctx = context.WithValue(ctx, constants.RequestIDKey, requestID)
		c.Request = c.Request.WithContext(ctx)
		c.Next()
	}
}
hoge/constants/context.go
package constants
type requestIDKeyType struct{}
var RequestIDKey = requestIDKeyType{}
adapter/http/middleware/logger.go
package middleware
import (
	"fmt"
	"time"
	"github.com/gin-gonic/gin"
)
var customLogFormatter = func(param gin.LogFormatterParams) string {
	var statusColor, methodColor, resetColor string
	if param.IsOutputColor() {
		statusColor = param.StatusCodeColor()
		methodColor = param.MethodColor()
		resetColor = param.ResetColor()
	}
	if param.Latency > time.Minute {
		param.Latency = param.Latency.Truncate(time.Second)
	}
	return fmt.Sprintf("[GIN] %v| %s |%s %3d %s| %13v | %15s |%s %-7s %s %#v\n%s",
		param.TimeStamp.Format("2006/01/02 - 15:04:05"),
		param.Request.Header.Get("X-Request-ID"),
		statusColor, param.StatusCode, resetColor,
		param.Latency,
		param.ClientIP,
		methodColor, param.Method, resetColor,
		param.Path,
		param.ErrorMessage,
	)
}
func LoggerConfig() gin.LoggerConfig {
	conf := gin.LoggerConfig{}
	conf.Formatter = customLogFormatter
	return conf
}
adapter/http/router/router.go
~ 略 ~
func (r *Router) SetupRoutes(e *gin.Engine) {
	e.Use(requestid.New())
	e.Use(gin.LoggerWithConfig(middleware.LoggerConfig()))
	e.Use(gin.Recovery())
	e.Use(middleware.RequestIDMiddleware())
~ 略 ~
参考:
https://github.com/gin-gonic/gin/blob/7a865dcf1dbe6ec52e074b1ddce830d278eb72cf/logger.go#L141
https://github.com/gin-gonic/gin/blob/7a865dcf1dbe6ec52e074b1ddce830d278eb72cf/gin.go#L224