forked from sourcegraph/appdash
-
Notifications
You must be signed in to change notification settings - Fork 0
/
trace.go
83 lines (74 loc) · 1.88 KB
/
trace.go
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
package appdash
import (
"bytes"
"encoding/json"
"fmt"
"io"
"strings"
)
// A Trace is a tree of spans.
type Trace struct {
Span // Root span
Sub []*Trace // Children
}
// String returns the Trace as a formatted string.
func (t *Trace) String() string {
b, err := json.MarshalIndent(t, "", " ")
if err != nil {
panic(err)
}
return string(b)
}
// FindSpan recursively searches for a span whose Span ID is spanID in
// t and its descendants. If no such span is found, nil is returned.
func (t *Trace) FindSpan(spanID ID) *Trace {
if t.ID.Span == spanID {
return t
}
for _, sub := range t.Sub {
if s := sub.FindSpan(spanID); s != nil {
return s
}
}
return nil
}
// TreeString returns the Trace as a formatted string that visually
// represents the trace's tree.
func (t *Trace) TreeString() string {
var buf bytes.Buffer
t.treeString(&buf, 0)
return buf.String()
}
func (t *Trace) treeString(w io.Writer, depth int) {
const indent1 = " "
indent := strings.Repeat(indent1, depth)
if depth == 0 {
fmt.Fprintf(w, "+ Trace %x\n", uint64(t.Span.ID.Trace))
} else {
if depth == 1 {
fmt.Fprint(w, "|")
} else {
fmt.Fprint(w, "|", indent[len(indent1):])
}
fmt.Fprintf(w, "%s+ Span %x", strings.Repeat("-", len(indent1)), uint64(t.Span.ID.Span))
if t.Span.ID.Parent != 0 {
fmt.Fprintf(w, " (parent %x)", uint64(t.Span.ID.Parent))
}
fmt.Fprintln(w)
}
for _, a := range t.Span.Annotations {
if depth == 0 {
fmt.Fprint(w, "| ")
} else {
fmt.Fprint(w, "|", indent[1:], " | ")
}
fmt.Fprintf(w, "%s = %s\n", a.Key, a.Value)
}
for _, sub := range t.Sub {
sub.treeString(w, depth+1)
}
}
type tracesByIDSpan []*Trace
func (t tracesByIDSpan) Len() int { return len(t) }
func (t tracesByIDSpan) Less(i, j int) bool { return t[i].Span.ID.Span < t[j].Span.ID.Span }
func (t tracesByIDSpan) Swap(i, j int) { t[i], t[j] = t[j], t[i] }