34 lines
1.1 KiB
Go
34 lines
1.1 KiB
Go
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
|
|
}
|
|
}
|