add RetryAttempts to AccessLog in JSON format
This commit is contained in:
parent
23cdb37165
commit
dae7e7a80a
11 changed files with 130 additions and 90 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
19
middlewares/accesslog/save_retries.go
Normal file
19
middlewares/accesslog/save_retries.go
Normal 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
|
||||
}
|
48
middlewares/accesslog/save_retries_test.go
Normal file
48
middlewares/accesslog/save_retries_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue