diff --git a/_example/go.mod b/_example/go.mod index e7ed271..a5509d0 100644 --- a/_example/go.mod +++ b/_example/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/httplog/v3 v3.0.0-00010101000000-000000000000 github.com/go-chi/traceid v0.3.0 - github.com/golang-cz/devslog v0.0.14 + github.com/golang-cz/devslog v0.0.15 ) require github.com/google/uuid v1.6.0 // indirect diff --git a/_example/go.sum b/_example/go.sum index a053810..1d8efbb 100644 --- a/_example/go.sum +++ b/_example/go.sum @@ -2,9 +2,7 @@ github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/traceid v0.3.0 h1:BYITxMnIeQasU7/U7+InZWANWxVZeCUBGTAqWleQOeg= github.com/go-chi/traceid v0.3.0/go.mod h1:XFfEEYZjqgML4ySh+wYBU29eqJkc2um7oEzgIc63e74= -github.com/golang-cz/devslog v0.0.9 h1:GU59V626sUccMjytKhewgN3teduXtx/itoQs78NaPdE= -github.com/golang-cz/devslog v0.0.9/go.mod h1:bSe5bm0A7Nyfqtijf1OMNgVJHlWEuVSXnkuASiE1vV8= -github.com/golang-cz/devslog v0.0.14 h1:hZY6VuZ/+MmG4djP9X1YDSmX/z5zPDDVgFlO0fyb+CY= -github.com/golang-cz/devslog v0.0.14/go.mod h1:bSe5bm0A7Nyfqtijf1OMNgVJHlWEuVSXnkuASiE1vV8= +github.com/golang-cz/devslog v0.0.15 h1:ejoBLTCwJHWGbAmDf2fyTJJQO3AkzcPjw8SC9LaOQMI= +github.com/golang-cz/devslog v0.0.15/go.mod h1:bSe5bm0A7Nyfqtijf1OMNgVJHlWEuVSXnkuASiE1vV8= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/_example/main.go b/_example/main.go index 728573f..76934ed 100644 --- a/_example/main.go +++ b/_example/main.go @@ -85,6 +85,10 @@ func main() { } return nil }, + + LogFormat: func(r *http.Request, statusCode int, d time.Duration) string { + return fmt.Sprintf("%s %s => HTTP %v", r.Method, r.URL, statusCode) + }, })) // Set request log attribute from within middleware. diff --git a/middleware.go b/middleware.go index 1ba74ac..9a419c0 100644 --- a/middleware.go +++ b/middleware.go @@ -35,6 +35,11 @@ func RequestLogger(logger *slog.Logger, o *Options) func(http.Handler) http.Hand s = SchemaECS } + logFormat := o.LogFormat + if logFormat == nil { + logFormat = defaultLogFormat + } + return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := context.WithValue(r.Context(), ctxKeyLogAttrs{}, &[]slog.Attr{}) @@ -166,7 +171,7 @@ func RequestLogger(logger *slog.Logger, o *Options) func(http.Handler) http.Hand logAttrs = groupAttrs(logAttrs, s.GroupDelimiter) } - msg := fmt.Sprintf("%s %s => HTTP %v (%v)", r.Method, r.URL, statusCode, duration) + msg := logFormat(r, statusCode, duration) logger.LogAttrs(ctx, lvl, msg, logAttrs...) }() diff --git a/options.go b/options.go index 6dc7661..89c59d9 100644 --- a/options.go +++ b/options.go @@ -1,6 +1,9 @@ package httplog import ( + "fmt" + "time" + "log/slog" "net/http" ) @@ -95,6 +98,10 @@ type Options struct { // // WARNING: Be careful not to leak any sensitive information in the logs. LogExtraAttrs func(req *http.Request, reqBody string, respStatus int) []slog.Attr + + // LogFormat is a optional function that lets you control the format of the log message + // If not provided, default format will be used + LogFormat func(*http.Request, int, time.Duration) string } var defaultOptions = Options{ @@ -105,4 +112,9 @@ var defaultOptions = Options{ LogResponseHeaders: []string{"Content-Type"}, LogBodyContentTypes: []string{"application/json", "application/xml", "text/plain", "text/csv", "application/x-www-form-urlencoded", ""}, LogBodyMaxLen: 1024, + LogFormat: defaultLogFormat, +} + +func defaultLogFormat(r *http.Request, statusCode int, duration time.Duration) string { + return fmt.Sprintf("%s %s => HTTP %v (%v)", r.Method, r.URL, statusCode, duration) }