1 // Package reqid creates request IDs and stores them in Contexts.
10 log "github.com/sirupsen/logrus"
13 // key is an unexported type for keys defined in this package.
14 // This prevents collisions with keys defined in other packages.
18 // reqIDKey is the key for request IDs in Contexts. It is
19 // unexported; clients use NewContext and FromContext
20 // instead of using this key directly.
22 // subReqIDKey is the key for sub-request IDs in Contexts. It is
23 // unexported; clients use NewSubContext and FromSubContext
24 // instead of using this key directly.
26 // coreIDKey is the key for Chain-Core-ID request header field values.
27 // It is only for statistics; don't use it for authorization.
29 // pathKey is the key for the request path being handled.
33 // New generates a random request ID.
35 // Given n IDs of length b bits, the probability that there will be a collision is bounded by
36 // the number of pairs of IDs multiplied by the probability that any pair might collide:
37 // p ≤ n(n - 1)/2 * 1/(2^b)
39 // We assume an upper bound of 1000 req/sec, which means that in a week there will be
40 // n = 1000 * 604800 requests. If l = 10, b = 8*10, then p ≤ 1.512e-7, which is a suitably
44 _, err := rand.Read(b)
46 log.WithField("error", err).Info("error making reqID")
48 return hex.EncodeToString(b)
51 // NewContext returns a new Context that carries reqid.
52 // It also adds a log prefix to print the request ID using
54 func NewContext(ctx context.Context, reqid string) context.Context {
55 ctx = context.WithValue(ctx, reqIDKey, reqid)
59 // FromContext returns the request ID stored in ctx,
61 func FromContext(ctx context.Context) string {
62 reqID, _ := ctx.Value(reqIDKey).(string)
66 // CoreIDFromContext returns the Chain-Core-ID stored in ctx,
67 // or the empty string.
68 func CoreIDFromContext(ctx context.Context) string {
69 id, _ := ctx.Value(coreIDKey).(string)
73 // PathFromContext returns the HTTP path stored in ctx,
74 // or the empty string.
75 func PathFromContext(ctx context.Context) string {
76 path, _ := ctx.Value(pathKey).(string)
80 func NewSubContext(ctx context.Context, reqid string) context.Context {
81 ctx = context.WithValue(ctx, subReqIDKey, reqid)
85 // FromSubContext returns the sub-request ID stored in ctx,
87 func FromSubContext(ctx context.Context) string {
88 subReqID, _ := ctx.Value(subReqIDKey).(string)
92 func Handler(handler http.Handler) http.Handler {
93 return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {