-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscope.go
More file actions
70 lines (63 loc) · 2.25 KB
/
scope.go
File metadata and controls
70 lines (63 loc) · 2.25 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
package stepmark
import "context"
// Scope provides a convenient way to track multiple entities of the
// same kind without repeating [WithKind] on every call.
//
// products := stepmark.NewScope(ctx, "product")
// for _, p := range results {
// products.Track(p.ID, map[string]any{"name": p.Name})
// products.RecordEvent(p.ID, "ranking", "scored", map[string]any{"score": p.Score})
// }
type Scope struct {
ctx context.Context
kind string
}
// NewScope creates a [Scope] for tracking entities of the given kind.
// The scope uses the provided context for all operations.
func NewScope(ctx context.Context, kind string) Scope {
return Scope{ctx: ctx, kind: kind}
}
// Track registers an entity within this scope, automatically setting
// its [EntityTrace.Kind]. Equivalent to calling the package-level
// [Track] with [WithKind].
func (s Scope) Track(entityID string, meta map[string]any) {
Track(s.ctx, entityID, meta, WithKind(s.kind))
}
// RecordEvent appends an event to the named entity's trace.
// Equivalent to calling the package-level [RecordEntity].
func (s Scope) RecordEvent(entityID, stage, action string, meta map[string]any) {
RecordEntity(s.ctx, entityID, stage, action, meta)
}
// Step records an entity event using the caller's function name as the
// stage. Equivalent to calling the package-level [StepEntity].
func (s Scope) Step(entityID, action string, meta map[string]any) {
t, _ := s.ctx.Value(contextKey{}).(*tracer)
if t == nil {
return
}
if t.entityFilter != nil && !t.entityFilter(entityID) {
return
}
t.recordEntity(entityID, resolveCallerName(2), action, meta)
}
// Enter records a function entry for a specific entity and returns a
// function that records the exit with duration. Equivalent to calling
// the package-level [EnterEntity].
func (s Scope) Enter(entityID string, meta map[string]any) func() {
t, _ := s.ctx.Value(contextKey{}).(*tracer)
if t == nil {
return noop
}
if t.entityFilter != nil && !t.entityFilter(entityID) {
return noop
}
stage := resolveCallerName(2)
t.recordEntity(entityID, stage, "entered", meta)
start := t.clock()
return func() {
elapsed := t.clock().Sub(start)
t.recordEntity(entityID, stage, "exited", map[string]any{
"duration_ms": float64(elapsed.Microseconds()) / 1000.0,
})
}
}