-
Notifications
You must be signed in to change notification settings - Fork 0
/
process.go
109 lines (100 loc) · 2.33 KB
/
process.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
import (
"fmt"
"github.com/pkg/errors"
"os"
"path/filepath"
"strings"
)
type Processor struct {
Path string `arg:""`
FilterFile string `arg:""`
ProcessTags bool `help:"print out process tags"`
FullPath bool `help:"print out full path of the input file"`
}
func (a Processor) Run() error {
stat, err := os.Stat(a.Path)
if err != nil {
return errors.WithStack(err)
}
if stat.IsDir() {
entries, err := os.ReadDir(a.Path)
if err != nil {
return errors.WithStack(err)
}
for _, e := range entries {
if !e.IsDir() && strings.HasSuffix(e.Name(), "json") {
err := a.processFile(filepath.Join(a.Path, e.Name()))
if err != nil {
return err
}
fmt.Println()
}
}
} else {
err := a.processFile(a.Path)
if err != nil {
return err
}
}
return nil
}
func (a Processor) processFile(path string) error {
trace, err := load(path)
if err != nil {
return errors.WithStack(err)
}
tags := ""
var filters []SpanFilter
lines, err := os.ReadFile(a.FilterFile)
if err != nil {
return errors.WithStack(err)
}
for _, line := range strings.Split(string(lines), "\n") {
line = strings.TrimSpace(line)
switch line {
case "":
continue
case "@root":
filters = append(filters, FilterRoot())
default:
filters = append(filters, FilterByName(line))
}
}
return trace.Tree.RootSpans.Walk(func(parent *TreeSpan, span *TreeSpan) (bool, error) {
for _, f := range filters {
if f(parent, span) {
if a.ProcessTags && tags == "" {
k := []string{}
for _, t := range span.Process.Tags {
k = append(k, fmt.Sprintf("%s=%s", t.Key, t.Value))
}
tags = " " + strings.Join(k, ",")
}
var f string
if a.FullPath {
f = path
} else {
f = filepath.Base(path)
}
fmt.Printf("%s %s%s %d\n", f, span.OperationName, tags, span.Duration)
}
}
return true, nil
})
}
type SpanFilter func(parent *TreeSpan, span *TreeSpan) bool
func FilterByName(pattern string) SpanFilter {
return func(parent *TreeSpan, span *TreeSpan) bool {
if pattern[len(pattern)-1] == '$' {
return strings.HasSuffix(span.OperationName, pattern[:len(pattern)-1])
} else {
return strings.Contains(span.OperationName, pattern)
}
}
}
func FilterRoot() SpanFilter {
return func(parent *TreeSpan, span *TreeSpan) bool {
return parent.OperationName == ""
}
}