tsweb: change RequestID format to have a date in it

So we can locate them in logs more easily.

Updates tailscale/corp#24721

Change-Id: Ia766c75608050dde7edc99835979a6e9bb328df2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2024-11-20 14:19:59 -08:00
committed by Brad Fitzpatrick
parent ebaf33a80c
commit 02cafbe1ca
5 changed files with 35 additions and 13 deletions

View File

@@ -6,9 +6,10 @@ package tsweb
import (
"context"
"net/http"
"time"
"tailscale.com/util/ctxkey"
"tailscale.com/util/fastuuid"
"tailscale.com/util/rands"
)
// RequestID is an opaque identifier for a HTTP request, used to correlate
@@ -41,10 +42,12 @@ const RequestIDHeader = "X-Tailscale-Request-Id"
// GenerateRequestID generates a new request ID with the current format.
func GenerateRequestID() RequestID {
// REQ-1 indicates the version of the RequestID pattern. It is
// currently arbitrary but allows for forward compatible
// transitions if needed.
return RequestID("REQ-1" + fastuuid.NewUUID().String())
// Return a string of the form "REQ-<VersionByte><...>"
// Previously we returned "REQ-1<UUIDString>".
// Now we return "REQ-2" version, where the "2" doubles as the year 2YYY
// in a leading date.
now := time.Now().UTC()
return RequestID("REQ-" + now.Format("20060102150405") + rands.HexString(16))
}
// SetRequestID is an HTTP middleware that injects a RequestID in the

View File

@@ -1307,6 +1307,28 @@ func TestBucket(t *testing.T) {
}
}
func TestGenerateRequestID(t *testing.T) {
t0 := time.Now()
got := GenerateRequestID()
t.Logf("Got: %q", got)
if !strings.HasPrefix(string(got), "REQ-2") {
t.Errorf("expect REQ-2 prefix; got %q", got)
}
const wantLen = len("REQ-2024112022140896f8ead3d3f3be27")
if len(got) != wantLen {
t.Fatalf("len = %d; want %d", len(got), wantLen)
}
d := got[len("REQ-"):][:14]
timeBack, err := time.Parse("20060102150405", string(d))
if err != nil {
t.Fatalf("parsing time back: %v", err)
}
elapsed := timeBack.Sub(t0)
if elapsed > 3*time.Second { // allow for slow github actions runners :)
t.Fatalf("time back was %v; want within 3s", elapsed)
}
}
func ExampleMiddlewareStack() {
// setHeader returns a middleware that sets header k = vs.
setHeader := func(k string, vs ...string) Middleware {