package middleware import ( "time" "github.com/ogen-go/ogen/middleware" "go.uber.org/zap" ) // statusCoder is implemented by ogen's *...StatusCode error wrappers. type statusCoder interface{ GetStatusCode() int } // OgenLogging is an ogen middleware that logs each operation's duration and // outcome. Handler errors carrying a 4xx/5xx-class status are logged at the // appropriate level: client errors (and expected 503s during startup) at // warn without a stacktrace, server errors at error. func OgenLogging(log *zap.Logger) middleware.Middleware { return func(req middleware.Request, next func(req middleware.Request) (middleware.Response, error)) (middleware.Response, error) { start := time.Now() resp, err := next(req) lg := log.With(zap.String("operation", req.OperationID), zap.Duration("duration", time.Since(start))) if err == nil { lg.Info("request completed") return resp, err } if sc, ok := err.(statusCoder); ok && sc.GetStatusCode() < 500 { lg.Warn("request rejected", zap.Int("status", sc.GetStatusCode()), zap.NamedError("reason", err)) } else { lg.Error("request failed", zap.Error(err)) } return resp, err } }