diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/event/event.go | 18 | ||||
| -rw-r--r-- | internal/flags/flags.go | 4 | ||||
| -rw-r--r-- | internal/flamegraph/collapsed.go | 97 | ||||
| -rw-r--r-- | internal/flamegraph/flamegraph.go | 24 | ||||
| -rw-r--r-- | internal/flamegraph/iordata.go | 23 | ||||
| -rw-r--r-- | internal/flamegraph/iordata_test.go | 4 | ||||
| -rw-r--r-- | internal/flamegraph/worker.go | 60 |
7 files changed, 41 insertions, 189 deletions
diff --git a/internal/event/event.go b/internal/event/event.go index f835aaf..684761a 100644 --- a/internal/event/event.go +++ b/internal/event/event.go @@ -28,9 +28,7 @@ type Pair struct { File file.File Comm string Duration uint64 - - // To calculate the time difference from the previoud event. - DurationToPrev uint64 + DurationToPrev uint64 } func NewPair(enterEv Event) *Pair { @@ -83,6 +81,20 @@ func (e *Pair) String() string { return sb.String() } +func (e *Pair) FlagsString() string { + if e.File == nil { + return "N:flags" + } + return e.File.FlagsString() +} + +func (e *Pair) FileName() string { + if e.File == nil { + return "N:file" + } + return e.File.Name() +} + func (e *Pair) Dump() string { return fmt.Sprintf("%v with enterEv(%v) and exitEv(%v)", e, e.EnterEv, e.ExitEv) } diff --git a/internal/flags/flags.go b/internal/flags/flags.go index c971335..91bceb3 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -33,7 +33,7 @@ type Flags struct { // Flamegraph flags FlamegraphEnable bool - FlamegraphName string // If set, enables new style iorData output, TODO: remove comment once old style collapsed format is retired + FlamegraphName string } func Parse() { @@ -57,7 +57,7 @@ func parse() { tracepointsToExclude := flag.String("tpsExclude", "", "Comma separated list regexes for tracepoints to exclude") flag.BoolVar(&singleton.FlamegraphEnable, "flamegraph", false, "Enable flamegraph builder") - flag.StringVar(&singleton.FlamegraphName, "name", "", "Name of the flamegraph data output") + flag.StringVar(&singleton.FlamegraphName, "name", "foo", "Name of the flamegraph data output") flag.Parse() singleton.TracepointsToAttach = extractTracepointFlags(*tracepointsToAttach) diff --git a/internal/flamegraph/collapsed.go b/internal/flamegraph/collapsed.go deleted file mode 100644 index 60c0b7f..0000000 --- a/internal/flamegraph/collapsed.go +++ /dev/null @@ -1,97 +0,0 @@ -package flamegraph - -import ( - "fmt" - "ior/internal/types" - "os" - "strings" - "sync" -) - -type collapsedCounter struct { - count uint64 - duration uint64 -} - -func (c *collapsedCounter) add(other collapsedCounter) { - c.count += other.count - c.duration += other.duration -} - -// TODO: Clean up all code commented with COLLAPSED once collapsed here retired. -type collapsed map[string]map[types.TraceId]collapsedCounter - -func (c collapsed) merge(other collapsed) (merged int) { - for k, v := range other { - if _, ok := c[k]; !ok { - c[k] = make(map[types.TraceId]collapsedCounter) - } - for traceId, cnt := range v { - if existingCnt, ok := c[k][traceId]; ok { - existingCnt.add(cnt) - merged++ - c[k][traceId] = existingCnt - continue - } - c[k][traceId] = cnt - } - } - return -} - -func (c collapsed) dump() { - var wg sync.WaitGroup - wg.Add(4) - - go c.dumpBy(&wg, "ior-by-path-count-flamegraph.collapsed", true, func(cnt collapsedCounter) uint64 { - return cnt.count - }) - go c.dumpBy(&wg, "ior-by-path-duration-flamegraph.collapsed", true, func(cnt collapsedCounter) uint64 { - return cnt.duration - }) - go c.dumpBy(&wg, "ior-by-syscall-count-flamegraph.collapsed", false, func(cnt collapsedCounter) uint64 { - return cnt.count - }) - go c.dumpBy(&wg, "ior-by-syscall-duration-flamegraph.collapsed", false, func(cnt collapsedCounter) uint64 { - return cnt.duration - }) - - wg.Wait() -} - -func (c collapsed) dumpBy(wg *sync.WaitGroup, outfile string, syscallAtTop bool, by func(collapsedCounter) uint64) { - defer wg.Done() - - defer fmt.Println("Dumping done") - fmt.Println("Dumping", outfile) - - file, err := os.Create(outfile) - if err != nil { - panic(err) - } - defer file.Close() - - for path, value := range c { - var sb strings.Builder - - for i, part := range strings.Split(path, "/") { - if i > 1 { - sb.WriteString(";") - sb.WriteString("/") - } - sb.WriteString(part) - } - - for traceId, cnt := range value { - var err error - if syscallAtTop { - _, err = fmt.Fprintf(file, "%s;syscall`%s %v\n", sb.String(), traceId.Name(), by(cnt)) - } else { - _, err = fmt.Fprintf(file, "syscall`%s;%s %v\n", traceId.Name(), sb.String(), by(cnt)) - } - if err != nil { - panic(err) - } - } - } -} diff --git a/internal/flamegraph/flamegraph.go b/internal/flamegraph/flamegraph.go index aeb5143..9772f0c 100644 --- a/internal/flamegraph/flamegraph.go +++ b/internal/flamegraph/flamegraph.go @@ -5,6 +5,7 @@ import ( "fmt" "ior/internal/event" "ior/internal/flags" + "log" "runtime" "sync" ) @@ -41,24 +42,19 @@ func (f Flamegraph) Start(ctx context.Context) { for i, worker := range f.workers { fmt.Println("Starting flamegraph worker", i) - if flags.Get().FlamegraphName == "" { // Empty string means: old style collapsed - go worker.runCollapsed(ctx, &wg, f.Ch) - } else { - go worker.run(ctx, &wg, f.Ch) - } + go worker.run(ctx, &wg, f.Ch) } wg.Wait() - // COLLAPSED: Will be removed, once migrated to iorData - if f.flags.FlamegraphName == "" { // Empty string means: old style collapsed - collapsed := f.workers[0].collapsed - if len(f.workers) > 1 { - for i, c := range f.workers[1:] { - fmt.Println("Worker", i+1, "merged", collapsed.merge(c.collapsed), - "counters =>", len(collapsed), "total counters") - } + iod := f.workers[0].iod + if len(f.workers) > 1 { + for i, w := range f.workers[1:] { + iod = iod.merge(w.iod) + fmt.Println("Worker", i+1, "merged") } - collapsed.dump() + } + if err := iod.commit(); err != nil { + log.Fatal(err) } }() } diff --git a/internal/flamegraph/iordata.go b/internal/flamegraph/iordata.go index 77b03aa..1cf1f0a 100644 --- a/internal/flamegraph/iordata.go +++ b/internal/flamegraph/iordata.go @@ -24,7 +24,6 @@ type iorData struct { paths pathMap } -// TODO: Flag to enable iorData // TODO: Name flag for iorData (outfile format: hostname-name-timestamp.ior.zst) // TODO: Output path for iorData flag // TODO: Add helper to convert .ior data file to collapsed format @@ -32,25 +31,10 @@ func newIorData() iorData { return iorData{paths: make(pathMap)} } -// TODO: Unit test func (iod iorData) add(ev *event.Pair) { - // type Pair struct { - // EnterEv, ExitEv Event - // File file.File - // Comm string - // Duration uint64 - - // // To calculate the time difference from the previoud event. - // PrevPair *Pair - // durationToPrev uint64 - // } - cnt := counter{ - count: 1, - duration: ev.Duration, - durationToPrev: ev.DurationToPrev, - } - iod.addPath(ev.File.Name(), ev.EnterEv.GetTraceId(), ev.Comm, - ev.EnterEv.GetPid(), ev.EnterEv.GetTid(), ev.File.FlagsString(), cnt) + cnt := counter{count: 1, duration: ev.Duration, durationToPrev: ev.DurationToPrev} + iod.addPath(ev.FileName(), ev.EnterEv.GetTraceId(), ev.Comm, ev.EnterEv.GetPid(), + ev.EnterEv.GetTid(), ev.FlagsString(), cnt) } func (iod iorData) addPath(path pathType, traceId traceIdType, comm commType, @@ -129,6 +113,7 @@ func (iod iorData) commit() error { filename := fmt.Sprintf("%s-%s-%s.ior.zst", hostname, flags.Get().FlamegraphName, time.Now().Format("2006-01-02_15:04:05")) + file, err := os.Create(filename) if err != nil { return err diff --git a/internal/flamegraph/iordata_test.go b/internal/flamegraph/iordata_test.go index 8a6c5e0..f938a49 100644 --- a/internal/flamegraph/iordata_test.go +++ b/internal/flamegraph/iordata_test.go @@ -4,6 +4,10 @@ import ( "testing" ) +func TestAdd(t *testring.T) { + +} + func TestAddPath(t *testing.T) { iod := newIorData() path := pathType("testPath") diff --git a/internal/flamegraph/worker.go b/internal/flamegraph/worker.go index e47329e..a24be6d 100644 --- a/internal/flamegraph/worker.go +++ b/internal/flamegraph/worker.go @@ -2,23 +2,19 @@ package flamegraph import ( "context" + "fmt" "ior/internal/event" - "ior/internal/types" "sync" "time" ) type worker struct { - collapsed collapsed - iod iorData - done chan struct{} + iod iorData + done chan struct{} } func newWorker() worker { - return worker{ - collapsed: make(collapsed), // COLLAPSED: Retire ocne newIorData implemented - iod: newIorData(), // TODO: make flags global, so i don't have to pass them through the whole code base - } + return worker{iod: newIorData()} } func (w worker) run(ctx context.Context, wg *sync.WaitGroup, ch <-chan *event.Pair) { @@ -27,12 +23,8 @@ func (w worker) run(ctx context.Context, wg *sync.WaitGroup, ch <-chan *event.Pa for { select { case ev := <-ch: - // var filePath string - // if ev.File == nil { - // filePath = "N:file" - // } else { - // filePath = ev.File.Name() - // } + fmt.Println("worker got event", ev) + w.iod.add(ev) ev.Recycle() default: @@ -45,43 +37,3 @@ func (w worker) run(ctx context.Context, wg *sync.WaitGroup, ch <-chan *event.Pa } } } - -// TODO: Retire collapsed -func (w worker) runCollapsed(ctx context.Context, wg *sync.WaitGroup, ch <-chan *event.Pair) { - { - defer wg.Done() - - for { - select { - case ev := <-ch: - var filePath string - if ev.File == nil { - filePath = "N:file" - } else { - filePath = ev.File.Name() - } - pathMap, ok := w.collapsed[filePath] - if !ok { - pathMap = make(map[types.TraceId]collapsedCounter) - } - - traceId := ev.EnterEv.GetTraceId() - cnt := pathMap[traceId] - cnt.count++ - cnt.duration += ev.Duration - pathMap[traceId] = cnt - - w.collapsed[filePath] = pathMap - ev.Recycle() - - default: - select { - case <-ctx.Done(): - return - default: - time.Sleep(time.Millisecond * 10) - } - } - } - } -} |
