-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathtracer.go
More file actions
97 lines (85 loc) · 2.23 KB
/
tracer.go
File metadata and controls
97 lines (85 loc) · 2.23 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
package gotaskflow
import (
"encoding/json"
"io"
"sync"
"sync/atomic"
"time"
)
// tracer records task execution events and exports them in Chrome Trace Event Format.
// The output can be visualized in Chrome's chrome://tracing or Perfetto UI (https://ui.perfetto.dev).
type tracer struct {
events []chromeTraceEvent
mu sync.Mutex
start time.Time
tidGen atomic.Int64
}
// chromeTraceEvent represents a single trace event following Chrome Trace Event Format.
type chromeTraceEvent struct {
Name string `json:"name"`
Cat string `json:"cat"`
Ph string `json:"ph"`
Ts int64 `json:"ts"`
Dur int64 `json:"dur"`
Pid int `json:"pid"`
Tid int64 `json:"tid"`
Args map[string]string `json:"args,omitempty"`
}
func newTracer() *tracer {
return &tracer{
events: make([]chromeTraceEvent, 0, 64),
start: time.Now(),
}
}
// AddEvent records a task execution event from the given span.
func (t *tracer) AddEvent(s *span) {
t.mu.Lock()
defer t.mu.Unlock()
ev := chromeTraceEvent{
Name: s.extra.name,
Cat: string(s.extra.typ),
Ph: "X",
Ts: s.begin.Sub(t.start).Microseconds(),
Dur: s.cost.Microseconds(),
Pid: 0,
Tid: t.tidGen.Add(1),
}
// Build args with optional parent and dependents
args := make(map[string]string)
if s.parent != nil {
args["parent"] = s.parent.extra.name
}
if len(s.dependents) > 0 {
// Store as comma-separated string for simplicity
deps := ""
for i, d := range s.dependents {
if i > 0 {
deps += ","
}
deps += d
}
args["dependents"] = deps
}
if len(args) > 0 {
ev.Args = args
}
t.events = append(t.events, ev)
}
func (t *tracer) draw(w io.Writer) error {
t.mu.Lock()
defer t.mu.Unlock()
encoder := json.NewEncoder(w)
encoder.SetIndent("", " ")
return encoder.Encode(t.events)
}
// traceRecord is an immutable snapshot of task execution events produced by a tracer.
// It represents the observed execution result of a TaskFlow run.
type traceRecord []chromeTraceEvent
// snapshot returns an immutable copy of all recorded trace events.
func (t *tracer) snapshot() traceRecord {
t.mu.Lock()
defer t.mu.Unlock()
cp := make(traceRecord, len(t.events))
copy(cp, t.events)
return cp
}