github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/pkg/reqid/request_id.go (about) 1 package reqid 2 3 import ( 4 "context" 5 "crypto/rand" 6 "encoding/hex" 7 8 "github.com/ShoshinNikita/budget-manager/internal/logger" 9 ) 10 11 // RequestID is a random hex string. It doesn't correspond to UUID RFC 4122 format because it would be 12 // an overkill for such small project. Also it can be easily modified to match RFC 4122 13 type RequestID string 14 15 func (r RequestID) ToString() string { 16 return string(r) 17 } 18 19 const requestIDLength = 8 20 21 // New creates a new request id 22 func New() RequestID { 23 data := make([]byte, requestIDLength/2) 24 rand.Read(data) //nolint:errcheck 25 return RequestID(hex.EncodeToString(data)) 26 } 27 28 type requestIDContextKey struct{} 29 30 // FromContext extracts request id from context. 31 // If request id doesn't exist, it generates a new one 32 func FromContext(ctx context.Context) RequestID { 33 if reqID, ok := ctx.Value(requestIDContextKey{}).(RequestID); ok { 34 return reqID 35 } 36 return New() 37 } 38 39 // ToContext returns a context based on passed one with injected request id 40 func ToContext(ctx context.Context, reqID RequestID) context.Context { 41 return context.WithValue(ctx, requestIDContextKey{}, reqID) 42 } 43 44 const loggerFieldKey = "request_id" 45 46 // FromContextToLogger extracts request id from context and returns logger with added field 47 func FromContextToLogger(ctx context.Context, log logger.Logger) logger.Logger { 48 reqID := FromContext(ctx) 49 return log.WithField(loggerFieldKey, reqID) 50 }