Skip to content

Commit

Permalink
Make DisableRequestSuccessLog configurable. (#284)
Browse files Browse the repository at this point in the history
- NewLogMiddleware is a public method. Adding a new parameter would make this PR a breaking change one.
- However, the behavior is the same: whatever is configured for the existing DisableRequestSuccessLog,
it will be used by the log middleware.
- Test option to not log successful requests.
  • Loading branch information
DylanGuedes authored May 22, 2023
1 parent 145055d commit 02fefc0
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 15 deletions.
36 changes: 22 additions & 14 deletions middleware/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (

// Log middleware logs http requests
type Log struct {
Log logging.Interface
LogRequestHeaders bool // LogRequestHeaders true -> dump http headers at debug log level
LogRequestAtInfoLevel bool // LogRequestAtInfoLevel true -> log requests at info log level
SourceIPs *SourceIPExtractor
HttpHeadersToExclude map[string]bool
Log logging.Interface
DisableRequestSuccessLog bool
LogRequestHeaders bool // LogRequestHeaders true -> dump http headers at debug log level
LogRequestAtInfoLevel bool // LogRequestAtInfoLevel true -> log requests at info log level
SourceIPs *SourceIPExtractor
HttpHeadersToExclude map[string]bool
}

var defaultExcludedHeaders = map[string]bool{
Expand Down Expand Up @@ -94,20 +95,27 @@ func (l Log) Wrap(next http.Handler) http.Handler {

return
}
if 100 <= statusCode && statusCode < 500 || statusCode == http.StatusBadGateway || statusCode == http.StatusServiceUnavailable {

switch {
// success and shouldn't log successful requests.
case statusCode >= 200 && statusCode < 300 && l.DisableRequestSuccessLog:
return

case 100 <= statusCode && statusCode < 500 || statusCode == http.StatusBadGateway || statusCode == http.StatusServiceUnavailable:
if l.LogRequestAtInfoLevel {
requestLog.Infof("%s %s (%d) %s", r.Method, uri, statusCode, time.Since(begin))
} else {
requestLog.Debugf("%s %s (%d) %s", r.Method, uri, statusCode, time.Since(begin))
}
if l.LogRequestHeaders && headers != nil {
if l.LogRequestAtInfoLevel {

if l.LogRequestHeaders && headers != nil {
requestLog.Infof("ws: %v; %s", IsWSHandshakeRequest(r), string(headers))
} else {
requestLog.Debugf("ws: %v; %s", IsWSHandshakeRequest(r), string(headers))
}
return
}

requestLog.Debugf("%s %s (%d) %s", r.Method, uri, statusCode, time.Since(begin))
if l.LogRequestHeaders && headers != nil {
requestLog.Debugf("ws: %v; %s", IsWSHandshakeRequest(r), string(headers))
}
} else {
default:
requestLog.Warnf("%s %s (%d) %s Response: %q ws: %v; %s",
r.Method, uri, statusCode, time.Since(begin), buf.Bytes(), IsWSHandshakeRequest(r), headers)
}
Expand Down
49 changes: 49 additions & 0 deletions middleware/logging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,55 @@ func TestBadWriteLogging(t *testing.T) {
}
}

func TestDisabledSuccessfulRequestsLogging(t *testing.T) {
for _, tc := range []struct {
err error
disableLog bool
logContains string
}{
{
err: nil,
disableLog: false,
}, {
err: nil,
disableLog: true,
logContains: "",
},
} {
buf := bytes.NewBuffer(nil)
logrusLogger := logrus.New()
logrusLogger.Out = buf
logrusLogger.Level = logrus.DebugLevel

loggingMiddleware := Log{
Log: logging.Logrus(logrusLogger),
DisableRequestSuccessLog: tc.disableLog,
}

handler := func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "<html><body>Hello World!</body></html>") //nolint:errcheck
}
loggingHandler := loggingMiddleware.Wrap(http.HandlerFunc(handler))

req := httptest.NewRequest("GET", "http://example.com/foo", nil)
recorder := httptest.NewRecorder()

w := errorWriter{
err: tc.err,
w: recorder,
}
loggingHandler.ServeHTTP(w, req)
content := buf.String()

if !tc.disableLog {
require.Contains(t, content, "GET http://example.com/foo (200)")
} else {
require.NotContains(t, content, "(200)")
require.Empty(t, content)
}
}
}

func TestLoggingRequestsAtInfoLevel(t *testing.T) {
for _, tc := range []struct {
err error
Expand Down
5 changes: 4 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,15 @@ func New(cfg Config) (*Server, error) {
}
}

defaultLogMiddleware := middleware.NewLogMiddleware(log, cfg.LogRequestHeaders, cfg.LogRequestAtInfoLevel, sourceIPs, strings.Split(cfg.LogRequestExcludeHeadersList, ","))
defaultLogMiddleware.DisableRequestSuccessLog = cfg.DisableRequestSuccessLog

defaultHTTPMiddleware := []middleware.Interface{
middleware.Tracer{
RouteMatcher: router,
SourceIPs: sourceIPs,
},
middleware.NewLogMiddleware(log, cfg.LogRequestHeaders, cfg.LogRequestAtInfoLevel, sourceIPs, strings.Split(cfg.LogRequestExcludeHeadersList, ",")),
defaultLogMiddleware,
middleware.Instrument{
RouteMatcher: router,
Duration: requestDuration,
Expand Down

0 comments on commit 02fefc0

Please sign in to comment.