1
0
Fork 0

add RetryAttempts to AccessLog in JSON format

This commit is contained in:
Marco Jantke 2017-08-28 12:50:02 +02:00 committed by Traefiker
parent 23cdb37165
commit dae7e7a80a
11 changed files with 130 additions and 90 deletions

View file

@ -68,6 +68,8 @@ const (
GzipRatio = "GzipRatio"
// Overhead is the map key used for the processing time overhead caused by Traefik.
Overhead = "Overhead"
// RetryAttempts is the map key used for the amount of attempts the request was retried.
RetryAttempts = "RetryAttempts"
)
// These are written out in the default case when no config is provided to specify keys of interest.
@ -110,6 +112,7 @@ func init() {
allCoreKeys[GzipRatio] = struct{}{}
allCoreKeys[StartLocal] = struct{}{}
allCoreKeys[Overhead] = struct{}{}
allCoreKeys[RetryAttempts] = struct{}{}
}
// CoreLogData holds the fields computed from the request/response.

View file

@ -180,9 +180,11 @@ func usernameIfPresent(theURL *url.URL) string {
// Logging handler to log frontend name, backend name, and elapsed time
func (l *LogHandler) logTheRoundTrip(logDataTable *LogData, crr *captureRequestReader, crw *captureResponseWriter) {
core := logDataTable.Core
if core[RetryAttempts] == nil {
core[RetryAttempts] = 0
}
if crr != nil {
core[RequestContentSize] = crr.count
}

View file

@ -33,6 +33,7 @@ var (
testMethod = "POST"
testReferer = "testReferer"
testUserAgent = "testUserAgent"
testRetryAttempts = 2
)
func TestLoggerCLF(t *testing.T) {
@ -91,6 +92,7 @@ func TestLoggerJSON(t *testing.T) {
RequestCount,
Duration,
Overhead,
RetryAttempts,
"time",
"StartLocal",
"StartUTC",
@ -150,6 +152,8 @@ func TestLoggerJSON(t *testing.T) {
assertCount++
assert.NotZero(t, jsonData[Overhead].(float64))
assertCount++
assert.Equal(t, float64(testRetryAttempts), jsonData[RetryAttempts].(float64))
assertCount++
assert.NotEqual(t, "", jsonData["time"].(string))
assertCount++
assert.NotEqual(t, "", jsonData["StartLocal"].(string))
@ -275,4 +279,5 @@ func logWriterTestHandlerFunc(rw http.ResponseWriter, r *http.Request) {
logDataTable.Core[BackendURL] = testBackendName
logDataTable.Core[OriginStatus] = testStatus
logDataTable.Core[OriginContentSize] = testContentSize
logDataTable.Core[RetryAttempts] = testRetryAttempts
}

View file

@ -0,0 +1,19 @@
package accesslog
import (
"net/http"
)
// SaveRetries is an implementation of RetryListener that stores RetryAttempts in the LogDataTable.
type SaveRetries struct{}
// Retried implements the RetryListener interface and will be called for each retry that happens.
func (s *SaveRetries) Retried(req *http.Request, attempt int) {
// it is the request attempt x, but the retry attempt is x-1
if attempt > 0 {
attempt--
}
table := GetLogDataTable(req)
table.Core[RetryAttempts] = attempt
}

View file

@ -0,0 +1,48 @@
package accesslog
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestSaveRetries(t *testing.T) {
tests := []struct {
requestAttempt int
wantRetryAttemptsInLog int
}{
{
requestAttempt: 0,
wantRetryAttemptsInLog: 0,
},
{
requestAttempt: 1,
wantRetryAttemptsInLog: 0,
},
{
requestAttempt: 3,
wantRetryAttemptsInLog: 2,
},
}
for _, test := range tests {
test := test
t.Run(fmt.Sprintf("%d retries", test.requestAttempt), func(t *testing.T) {
t.Parallel()
saveRetries := &SaveRetries{}
logDataTable := &LogData{Core: make(CoreLogData)}
req := httptest.NewRequest(http.MethodGet, "/some/path", nil)
reqWithDataTable := req.WithContext(context.WithValue(req.Context(), DataTableKey, logDataTable))
saveRetries.Retried(reqWithDataTable, test.requestAttempt)
if logDataTable.Core[RetryAttempts] != test.wantRetryAttemptsInLog {
t.Errorf("got %v in logDataTable, want %v", logDataTable.Core[RetryAttempts], test.wantRetryAttemptsInLog)
}
})
}
}