diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-08 19:43:33 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-08 19:43:33 +0300 |
| commit | f86699a94bdde7d973ba5d6fa3e7ca4ab2f234fb (patch) | |
| tree | c2e11bfa4fdac965623a8058716c514fce507eba /internal/tui/dashboard/treemap.go | |
| parent | c41a38ef55bb80681a6cc0b2161f8e84bfabcf17 (diff) | |
add duration metric, tolerate missing tracepoints, ship el8 build
- Bubbles, treemap, icicle, and the live flamegraph 'b' cycle now include
syscall duration (sum) as a third metric alongside events and bytes.
Statsengine snapshots expose TotalLatencyNs to support this.
- AttachAll takes an optional warn callback. Production passes one so older
kernels that lack newer tracepoints log a warning and keep going instead
of aborting startup.
- Dockerfile.el8 + scripts/build-with-docker-el8.sh + mage buildDockerEl8
produce ior.el8, a static binary built against Rocky Linux 8 glibc for
RHEL/Rocky/Alma 8 hosts.
- README.md documents installing mage and the new el8 target.
Diffstat (limited to 'internal/tui/dashboard/treemap.go')
| -rw-r--r-- | internal/tui/dashboard/treemap.go | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/internal/tui/dashboard/treemap.go b/internal/tui/dashboard/treemap.go index dd62d13..03c2917 100644 --- a/internal/tui/dashboard/treemap.go +++ b/internal/tui/dashboard/treemap.go @@ -17,13 +17,14 @@ import ( const maxSyscallTreemapItems = 20 type syscallTreemapItem struct { - Name string - Count uint64 - Bytes uint64 - Errors uint64 - P95Ns uint64 - Detail string - Value uint64 + Name string + Count uint64 + Bytes uint64 + Duration uint64 + Errors uint64 + P95Ns uint64 + Detail string + Value uint64 } type syscallTreemapTile struct { @@ -111,11 +112,12 @@ func buildSyscallTreemapItems(snap *statsengine.Snapshot, metric bubbleMetric) [ items := make([]syscallTreemapItem, 0, len(syscalls)) for _, syscall := range syscalls { item := syscallTreemapItem{ - Name: syscall.Name, - Count: syscall.Count, - Bytes: syscall.Bytes, - Errors: syscall.Errors, - P95Ns: syscall.LatencyP95Ns, + Name: syscall.Name, + Count: syscall.Count, + Bytes: syscall.Bytes, + Duration: syscall.TotalLatencyNs, + Errors: syscall.Errors, + P95Ns: syscall.LatencyP95Ns, Detail: fmt.Sprintf( "rate %.1f/s, errors %d, p95 %s", syscall.RatePerSec, @@ -154,9 +156,10 @@ func buildFilesTreemapItems(snap *statsengine.Snapshot, metric bubbleMetric) []s pathLabel := rootPathLabelFromFSPath(dir.Dir) totalBytes := dir.BytesRead + dir.BytesWritten item := syscallTreemapItem{ - Name: pathLabel, - Count: dir.Accesses, - Bytes: totalBytes, + Name: pathLabel, + Count: dir.Accesses, + Bytes: totalBytes, + Duration: dir.TotalLatencyNs, Detail: fmt.Sprintf( "dir %s, files %d, read %s, write %s, max %s", dir.Dir, @@ -199,9 +202,10 @@ func buildProcessesTreemapItems(snap *statsengine.Snapshot, metric bubbleMetric) label = fmt.Sprintf("%d:%s", proc.PID, comm) } item := syscallTreemapItem{ - Name: label, - Count: proc.Syscalls, - Bytes: proc.Bytes, + Name: label, + Count: proc.Syscalls, + Bytes: proc.Bytes, + Duration: proc.TotalLatencyNs, Detail: fmt.Sprintf( "pid %d, rate %.1f/s, avg %s", proc.PID, @@ -231,10 +235,14 @@ func buildProcessesTreemapItems(snap *statsengine.Snapshot, metric bubbleMetric) } func treemapValue(item syscallTreemapItem, metric bubbleMetric) uint64 { - if metric == bubbleMetricBytes { + switch metric { + case bubbleMetricBytes: return item.Bytes + case bubbleMetricDuration: + return item.Duration + default: + return item.Count } - return item.Count } func layoutSyscallTreemap(items []syscallTreemapItem, x, y, w, h int) []syscallTreemapTile { @@ -421,13 +429,14 @@ func treemapStatusLine(items []syscallTreemapItem, selected int, metric bubbleMe } selected = clampOffset(selected, len(items)) item := items[selected] - metricValue := item.Count - if metric == bubbleMetricBytes { - metricValue = item.Bytes - } - metricText := fmt.Sprintf("%d", metricValue) - if metric == bubbleMetricBytes { - metricText = formatBytes(float64(metricValue)) + var metricText string + switch metric { + case bubbleMetricBytes: + metricText = formatBytes(float64(item.Bytes)) + case bubbleMetricDuration: + metricText = formatDurationUintNs(item.Duration) + default: + metricText = fmt.Sprintf("%d", item.Count) } status := fmt.Sprintf( "sel:%d/%d %s | %s=%s | bytes=%s", @@ -445,10 +454,14 @@ func treemapStatusLine(items []syscallTreemapItem, selected int, metric bubbleMe } func treemapMetricLabel(metric bubbleMetric) string { - if metric == bubbleMetricBytes { + switch metric { + case bubbleMetricBytes: return "bytes" + case bubbleMetricDuration: + return "duration" + default: + return "events" } - return "events" } func treemapPalette(isDark bool) []color.Color { |
