From a9228d40cb4bfc210148b2f931f7f287515bfa5e Mon Sep 17 00:00:00 2001 From: Hank Donnay Date: Tue, 6 Dec 2022 10:00:15 -0600 Subject: [PATCH] httptransport: add a `request_id` to logs This re-uses any trace ID that OpenTelemetry supports, or generates a random one. Closes: #1547 Signed-off-by: Hank Donnay --- httptransport/common.go | 33 ++++++++++++++++++++++++++++++++ httptransport/indexer_v1.go | 2 +- httptransport/matcher_v1.go | 2 +- httptransport/notification_v1.go | 2 +- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/httptransport/common.go b/httptransport/common.go index 4931194f60..227a54d1e7 100644 --- a/httptransport/common.go +++ b/httptransport/common.go @@ -1,14 +1,21 @@ package httptransport import ( + crand "crypto/rand" + "encoding/binary" "errors" "fmt" + "math/rand" "mime" "net/http" "path" "sort" "strconv" "strings" + "sync" + + "github.com/quay/zlog" + "go.opentelemetry.io/otel/trace" "github.com/quay/claircore" ) @@ -106,3 +113,29 @@ func (a *accept) Match(mt string) bool { t, s := mt[:i], mt[i+1:] return a.Type == t && (a.Subtype == s || a.Subtype == "*") } + +var idPool = sync.Pool{ + New: func() interface{} { + b := make([]byte, 8) + if _, err := crand.Read(b); err != nil { + panic(err) // ??? + } + s := binary.LittleEndian.Uint64(b) + src := rand.NewSource(int64(s)) + return rand.New(src) + }, +} + +func withRequestID(r *http.Request) *http.Request { + const key = `request_id` + ctx := r.Context() + sctx := trace.SpanContextFromContext(ctx) + if sctx.HasTraceID() { + ctx = zlog.ContextWithValues(ctx, key, sctx.TraceID().String()) + } else { + rng := idPool.Get().(*rand.Rand) + ctx = zlog.ContextWithValues(ctx, key, fmt.Sprintf("%016x", rng.Uint64())) + idPool.Put(rng) + } + return r.WithContext(ctx) +} diff --git a/httptransport/indexer_v1.go b/httptransport/indexer_v1.go index 43b46b618b..c9c71561c9 100644 --- a/httptransport/indexer_v1.go +++ b/httptransport/indexer_v1.go @@ -68,7 +68,7 @@ func (h *IndexerV1) ServeHTTP(w http.ResponseWriter, r *http.Request) { Dur("duration", time.Since(start)). Msg("handled HTTP request") }() - h.inner.ServeHTTP(wr, r) + h.inner.ServeHTTP(wr, withRequestID(r)) } func (h *IndexerV1) indexReport(w http.ResponseWriter, r *http.Request) { diff --git a/httptransport/matcher_v1.go b/httptransport/matcher_v1.go index 8d6751ad54..494a18a8cf 100644 --- a/httptransport/matcher_v1.go +++ b/httptransport/matcher_v1.go @@ -76,7 +76,7 @@ func (h *MatcherV1) ServeHTTP(w http.ResponseWriter, r *http.Request) { Dur("duration", time.Since(start)). Msg("handled HTTP request") }() - h.inner.ServeHTTP(wr, r) + h.inner.ServeHTTP(wr, withRequestID(r)) } func (h *MatcherV1) vulnerabilityReport(w http.ResponseWriter, r *http.Request) { diff --git a/httptransport/notification_v1.go b/httptransport/notification_v1.go index 968aaab34e..4e4b5e86bf 100644 --- a/httptransport/notification_v1.go +++ b/httptransport/notification_v1.go @@ -68,7 +68,7 @@ func (h *NotificationV1) ServeHTTP(w http.ResponseWriter, r *http.Request) { Dur("duration", time.Since(start)). Msg("handled HTTP request") }() - h.inner.ServeHTTP(wr, r) + h.inner.ServeHTTP(wr, withRequestID(r)) } func (h *NotificationV1) serveHTTP(w http.ResponseWriter, r *http.Request) {