diff --git a/net/http/roundtripware/logger.go b/net/http/roundtripware/logger.go index f1047e2..5c5030b 100644 --- a/net/http/roundtripware/logger.go +++ b/net/http/roundtripware/logger.go @@ -9,24 +9,94 @@ import ( keeltime "github.com/foomo/keel/time" ) +type ( + LoggerOptions struct { + Message string + ErrorMessage string + MinWarnCode int + MinErrorCode int + } + LoggerOption func(*LoggerOptions) +) + +// GetDefaultLoggerOptions returns the default options +func GetDefaultLoggerOptions() LoggerOptions { + return LoggerOptions{ + Message: "sent request", + ErrorMessage: "failed to sent request", + MinWarnCode: 400, + MinErrorCode: 500, + } +} + +// LoggerWithMessage middleware option +func LoggerWithMessage(v string) LoggerOption { + return func(o *LoggerOptions) { + o.Message = v + } +} + +// LoggerWithErrorMessage middleware option +func LoggerWithErrorMessage(v string) LoggerOption { + return func(o *LoggerOptions) { + o.ErrorMessage = v + } +} + +// LoggerWithMinWarnCode middleware option +func LoggerWithMinWarnCode(v int) LoggerOption { + return func(o *LoggerOptions) { + o.MinWarnCode = v + } +} + +// LoggerWithMinErrorCode middleware option +func LoggerWithMinErrorCode(v int) LoggerOption { + return func(o *LoggerOptions) { + o.MinErrorCode = v + } +} + // Logger returns a RoundTripware which logs all requests -func Logger() RoundTripware { - msg := "sent request" +func Logger(opts ...LoggerOption) RoundTripware { + o := GetDefaultLoggerOptions() + for _, opt := range opts { + if opt != nil { + opt(&o) + } + } return func(l *zap.Logger, next Handler) Handler { return func(req *http.Request) (*http.Response, error) { start := keeltime.Now() + statusCode := http.StatusTeapot + + // extend logger using local instance + l := log.WithHTTPRequestOut(l, req) + + // execute next handler resp, err := next(req) - statusCode := -1 - contentLength := int64(-1) - if resp != nil { + if err != nil { + l = log.WithError(l, err) + } else if resp != nil { + l = log.With(l, + log.FHTTPStatusCode(resp.StatusCode), + log.FHTTPRequestContentLength(resp.ContentLength), + ) statusCode = resp.StatusCode - contentLength = resp.ContentLength } - log.WithHTTPRequestOut(l, req).Info(msg, - log.FDuration(keeltime.Now().Sub(start)), - log.FHTTPStatusCode(statusCode), - log.FHTTPRequestContentLength(contentLength), - ) + + l = l.With(log.FDuration(keeltime.Now().Sub(start))) + + switch { + case err != nil: + l.Error(o.ErrorMessage) + case o.MinErrorCode > 0 && statusCode >= o.MinErrorCode: + l.Error(o.Message) + case o.MinWarnCode > 0 && statusCode >= o.MinWarnCode: + l.Warn(o.Message) + default: + l.Info(o.Message) + } return resp, err } }