diff --git a/config.go b/config.go index 5b58829..cc6aa11 100644 --- a/config.go +++ b/config.go @@ -38,7 +38,7 @@ func WithFilter(f Filter) Option { } // WithAdditionalFieldExtractor takes a function that will be called on every -// request and the returned fields will be added to a log entry. +// request and the returned fields will be added to the log entry. func WithAdditionalFieldExtractor(extractor AdditionalFieldExtractor) Option { return func(c *config) { c.additionalFieldExtractors = append(c.additionalFieldExtractors, extractor) diff --git a/logger.go b/logger.go index 3e81cae..7775229 100644 --- a/logger.go +++ b/logger.go @@ -1,6 +1,7 @@ package chizap import ( + "net" "net/http" "time" @@ -10,10 +11,6 @@ import ( ) // Logger returns a go-chi middleware that logs requests using go.uber.org/zap. -// -// Requests with status code >= 500 are logged using logger.Error. -// Requests with status code >= 400 are logged using logger.Warn. -// Other requests are logged using logger.Info. func Logger(logger *zap.Logger, opts ...Option) func(next http.Handler) http.Handler { cfg := newConfig(opts...) return func(next http.Handler) http.Handler { @@ -34,11 +31,12 @@ func Logger(logger *zap.Logger, opts ...Option) func(next http.Handler) http.Han end := time.Now() statusCode := ww.Status() + ip, _, _ := net.SplitHostPort(r.RemoteAddr) fields := []zap.Field{ zap.Int("statusCode", statusCode), zap.Duration("duration", end.Sub(start)), - zap.String("ip", r.RemoteAddr), + zap.String("ip", ip), zap.String("method", r.Method), zap.String("query", query), zap.String("path", path), diff --git a/logger_test.go b/logger_test.go index c878d9a..807e12d 100644 --- a/logger_test.go +++ b/logger_test.go @@ -1,11 +1,11 @@ package chizap_test import ( + "net" "net/http" "net/http/httptest" "strings" "testing" - "time" "gitea.dwysokinski.me/Kichiyaki/chizap" "github.com/go-chi/chi/v5" @@ -25,28 +25,24 @@ func TestLogger(t *testing.T) { excluded bool expectedLevel zapcore.Level expectedRoutePattern string - expectedTimeFormat string expectedAdditionalFields []zap.Field }{ { name: "/info?test=true", req: httptest.NewRequest(http.MethodGet, "/info?test=true", nil), expectedLevel: zap.InfoLevel, - expectedTimeFormat: time.RFC3339, expectedRoutePattern: "/info", }, { name: "/warn?test=true", req: httptest.NewRequest(http.MethodGet, "/warn?test=true", nil), expectedLevel: zap.WarnLevel, - expectedTimeFormat: time.RFC3339, expectedRoutePattern: "/warn", }, { name: "/error?test=true", req: httptest.NewRequest(http.MethodGet, "/error?test=true", nil), expectedLevel: zap.ErrorLevel, - expectedTimeFormat: time.RFC3339, expectedRoutePattern: "/error", }, { @@ -58,7 +54,6 @@ func TestLogger(t *testing.T) { name: "/delete/123", req: httptest.NewRequest(http.MethodDelete, "/delete/123", nil), expectedLevel: zap.InfoLevel, - expectedTimeFormat: time.RFC3339, expectedRoutePattern: "/delete/{id}", expectedAdditionalFields: []zap.Field{ zap.String("id", "123"), @@ -89,10 +84,15 @@ func TestLogger(t *testing.T) { assert.Equal(t, tt.req.URL.Path, entry.Message) assert.Equal(t, tt.expectedLevel, entry.Level) require.Len(t, entry.Context, 11+len(tt.expectedAdditionalFields)) + ip, _, _ := net.SplitHostPort(tt.req.RemoteAddr) + assert.Contains(t, entry.Context, zap.String("ip", ip)) assert.Contains(t, entry.Context, zap.Int("statusCode", rr.Code)) assert.Contains(t, entry.Context, zap.String("method", tt.req.Method)) assert.Contains(t, entry.Context, zap.String("path", tt.req.URL.Path)) assert.Contains(t, entry.Context, zap.String("query", tt.req.URL.RawQuery)) + assert.Contains(t, entry.Context, zap.String("proto", tt.req.Proto)) + assert.Contains(t, entry.Context, zap.String("referer", tt.req.Referer())) + assert.Contains(t, entry.Context, zap.String("userAgent", tt.req.UserAgent())) assert.Contains(t, entry.Context, zap.String("routePattern", tt.expectedRoutePattern)) for _, f := range tt.expectedAdditionalFields { assert.Contains(t, entry.Context, f)