From 8cb2faeeaa9e694530523893379d49a59ede9f36 Mon Sep 17 00:00:00 2001 From: Bernhard Barker <36070131+bernhardbarker@users.noreply.github.com> Date: Thu, 1 Oct 2020 11:44:03 +0200 Subject: [PATCH] logger, tracking: use X-Tracking-Id header and add tracking_id log field * use X-Tracking-Id as default tracking header, falls back to X-Request_Id * add both tracking_id and request_id to logger context --- logger/internal/constants.go | 1 + logger/middleware/http.go | 7 ++--- tracking/internal/constants/headers.go | 1 + tracking/middleware/events.go | 15 ++++++----- tracking/middleware/events_test.go | 37 +++++++++++++------------- tracking/middleware/http.go | 18 ++++++++----- 6 files changed, 45 insertions(+), 34 deletions(-) diff --git a/logger/internal/constants.go b/logger/internal/constants.go index 6e7dbda..058d70d 100644 --- a/logger/internal/constants.go +++ b/logger/internal/constants.go @@ -35,5 +35,6 @@ const ( HeaderForwardedFor = "X-Forwarded-For" HeaderRequestID = "X-Request-Id" HeaderRequestDepth = "X-Request-Depth" + HeaderTrackingID = "X-Tracking-Id" HeaderTreePath = "X-Tree-Path" ) diff --git a/logger/middleware/http.go b/logger/middleware/http.go index 713a242..aa89c10 100644 --- a/logger/middleware/http.go +++ b/logger/middleware/http.go @@ -39,12 +39,13 @@ func HTTPRequestLogger(skipRoutes []string) func(http.Handler) http.Handler { ctx := r.Context() log := *logger.FromContext(ctx) + trackingID := tracking.IDFromContext(ctx) logFields := map[string]interface{}{ internal.FieldEntryPoint: isEntryPoint(r), // TODO double check if they are a must and make them optional if not internal.FieldRequestDepth: tracking.RequestDepthFromCtx(ctx), - internal.FieldTrackingID: tracking.IDFromContext(ctx), - internal.FieldRequestID: tracking.IDFromContext(ctx), + internal.FieldTrackingID: trackingID, + internal.FieldRequestID: trackingID, internal.FieldTreePath: tracking.TreePathFromCtx(ctx), internal.FieldRoute: tracking.RequestRouteFromCtx(ctx), internal.FieldParams: r.URL.RawQuery, @@ -99,7 +100,7 @@ func ipAddress(r *http.Request) string { } func isEntryPoint(r *http.Request) bool { - return len(r.Header.Get(internal.HeaderRequestID)) == 0 + return r.Header.Get(internal.HeaderRequestID) == "" && r.Header.Get(internal.HeaderTrackingID) == "" } type responseWriter struct { diff --git a/tracking/internal/constants/headers.go b/tracking/internal/constants/headers.go index 8df5eb3..d4cba26 100644 --- a/tracking/internal/constants/headers.go +++ b/tracking/internal/constants/headers.go @@ -7,5 +7,6 @@ const ( HeaderForwardedFor = "X-Forwarded-For" HeaderRequestID = "X-Request-Id" HeaderRequestDepth = "X-Request-Depth" + HeaderTrackingID = "X-Tracking-Id" HeaderTreePath = "X-Tree-Path" ) diff --git a/tracking/middleware/events.go b/tracking/middleware/events.go index efd78cc..54ff74d 100644 --- a/tracking/middleware/events.go +++ b/tracking/middleware/events.go @@ -15,14 +15,17 @@ import ( // if it does it sets it on the context, if it does not it generates a new one to set on the context func EventsAddTrackingID(next events.Handler) events.Handler { return events.HandlerFunc(func(ctx context.Context, e events.Event) error { - trackingID := e.Headers[constants.HeaderRequestID] + trackingID := e.Headers[constants.HeaderTrackingID] if trackingID == "" { - uuid, err := uuid.NewUUID() - if err != nil { - logger.FromContext(ctx).Err(err).Msg("could not generate uuid not setting trackingID in context") - return next.Handle(ctx, e) + trackingID = e.Headers[constants.HeaderRequestID] + if trackingID == "" { + uuid, err := uuid.NewUUID() + if err != nil { + logger.FromContext(ctx).Err(err).Msg("could not generate uuid, not setting trackingID in context") + return next.Handle(ctx, e) + } + trackingID = uuid.String() } - trackingID = uuid.String() } ctx = tracking.SetContextID(ctx, trackingID) return next.Handle(ctx, e) diff --git a/tracking/middleware/events_test.go b/tracking/middleware/events_test.go index 4330d78..968ed30 100644 --- a/tracking/middleware/events_test.go +++ b/tracking/middleware/events_test.go @@ -26,28 +26,29 @@ func TestEventsAddTrackingIDCreatesIDWhenEventHeaderEmpty(t *testing.T) { err := testHandler.Handle(context.Background(), e) if err != nil { - t.Errorf("could not succesfully handle: %v", err) + t.Errorf("could not successfully handle: %v", err) } } func TestEventsAddTrackingIDDoesNotChangeTrackingIDIfAlreadyPresent(t *testing.T) { testId := "goodid" - - e := events.Event{ - Headers: events.Header(map[string]string{constants.HeaderRequestID: testId}), - } - - testHandler := EventsAddTrackingID(events.Handler( - events.HandlerFunc(func(ctx context.Context, e events.Event) error { - got := tracking.IDFromContext(ctx) - if !cmp.Equal(got, testId) { - t.Errorf("want: %v, got: %v", testId, got) - } - return nil - }))) - - err := testHandler.Handle(context.Background(), e) - if err != nil { - t.Errorf("could not succesfully handle: %v", err) + for _, headerName := range []string{constants.HeaderRequestID, constants.HeaderTrackingID} { + e := events.Event{ + Headers: events.Header(map[string]string{headerName: testId}), + } + + testHandler := EventsAddTrackingID(events.Handler( + events.HandlerFunc(func(ctx context.Context, e events.Event) error { + got := tracking.IDFromContext(ctx) + if !cmp.Equal(got, testId) { + t.Errorf("field name: %s, want: %v, got: %v", headerName, testId, got) + } + return nil + }))) + + err := testHandler.Handle(context.Background(), e) + if err != nil { + t.Errorf("field name: %s, could not successfully handle: %v", headerName, err) + } } } diff --git a/tracking/middleware/http.go b/tracking/middleware/http.go index 17c86ce..5729068 100644 --- a/tracking/middleware/http.go +++ b/tracking/middleware/http.go @@ -10,23 +10,27 @@ import ( "github.com/blacklane/go-libs/tracking/internal/constants" ) -func RequestID(next http.Handler) http.Handler { +func TrackingID(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - requestID := ExtractRequestID(r) + trackingID := ExtractTrackingID(r) - ctx := tracking.SetContextID(r.Context(), requestID) + ctx := tracking.SetContextID(r.Context(), trackingID) rr := r.WithContext(ctx) next.ServeHTTP(w, rr) }) } -func ExtractRequestID(r *http.Request) string { +func ExtractTrackingID(r *http.Request) string { + trackingID := r.Header.Get(constants.HeaderTrackingID) + if trackingID != "" { + return trackingID + } requestID := r.Header.Get(constants.HeaderRequestID) - if requestID == "" { - requestID = uuid.New().String() + if requestID != "" { + return requestID } - return requestID + return uuid.New().String() } // ExtractRequestDepth returns the request depth extracted from the header added of 1 or