Repository navigation
Expand file tree
/
Copy pathcontext.go
More file actions
106 lines (88 loc) · 3.21 KB
/
Copy pathcontext.go
File metadata and controls
106 lines (88 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package hyperfleetlogger
import (
"context"
"log/slog"
)
// Key is a type-safe context key. Use NewKey to create one and
// Set/Get to store and retrieve values without type assertions.
type Key[T any] struct{ name string }
// NewKey creates a named context key for values of type T.
func NewKey[T any](name string) Key[T] { return Key[T]{name: name} }
// Set stores val in ctx under key.
func Set[T any](ctx context.Context, key Key[T], val T) context.Context {
return context.WithValue(ctx, key, val)
}
// Get retrieves the value stored under key, if present.
func Get[T any](ctx context.Context, key Key[T]) (T, bool) {
v, ok := ctx.Value(key).(T)
return v, ok
}
// Exported typed keys for the standard HyperFleet context fields.
var (
TraceIDKey = NewKey[string](FieldTraceID)
SpanIDKey = NewKey[string](FieldSpanID)
ResourceTypeKey = NewKey[string](FieldResourceType)
ResourceIDKey = NewKey[string](FieldResourceID)
)
// ContextField maps a log field name to a function that extracts its
// slog.Value from a context. Register extra fields via WithContextFields.
type ContextField struct {
Getter func(context.Context) (slog.Value, bool)
Name string
}
// FieldFromKey builds a ContextField from a typed Key, using toValue
// to convert the stored value to an slog.Value.
func FieldFromKey[T any](key Key[T], toValue func(T) slog.Value) ContextField {
return ContextField{
Name: key.name,
Getter: func(ctx context.Context) (slog.Value, bool) {
v, ok := Get(ctx, key)
if !ok {
return slog.Value{}, false
}
return toValue(v), true
},
}
}
// StringField builds a ContextField from a Key[string].
func StringField(key Key[string]) ContextField {
return FieldFromKey(key, slog.StringValue)
}
var defaultContextFields = []ContextField{
StringField(TraceIDKey),
StringField(SpanIDKey),
StringField(ResourceTypeKey),
StringField(ResourceIDKey),
}
// WithTraceID returns a context carrying the given trace ID.
func WithTraceID(ctx context.Context, traceID string) context.Context {
return Set(ctx, TraceIDKey, traceID)
}
// TraceIDFromContext extracts the trace ID, if present.
func TraceIDFromContext(ctx context.Context) (string, bool) {
return Get(ctx, TraceIDKey)
}
// WithSpanID returns a context carrying the given span ID.
func WithSpanID(ctx context.Context, spanID string) context.Context {
return Set(ctx, SpanIDKey, spanID)
}
// SpanIDFromContext extracts the span ID, if present.
func SpanIDFromContext(ctx context.Context) (string, bool) {
return Get(ctx, SpanIDKey)
}
// WithResourceType returns a context carrying the given resource type.
func WithResourceType(ctx context.Context, resourceType string) context.Context {
return Set(ctx, ResourceTypeKey, resourceType)
}
// ResourceTypeFromContext extracts the resource type, if present.
func ResourceTypeFromContext(ctx context.Context) (string, bool) {
return Get(ctx, ResourceTypeKey)
}
// WithResourceID returns a context carrying the given resource ID.
func WithResourceID(ctx context.Context, resourceID string) context.Context {
return Set(ctx, ResourceIDKey, resourceID)
}
// ResourceIDFromContext extracts the resource ID, if present.
func ResourceIDFromContext(ctx context.Context) (string, bool) {
return Get(ctx, ResourceIDKey)
}