diff options
| author | Alexander M Pickering <alex@cogarr.net> | 2026-07-21 20:19:46 -0500 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2026-07-21 20:19:46 -0500 |
| commit | 657fb0007f39f07cc0401e0c5d03e25df6234aa4 (patch) | |
| tree | f73fe23232dc80802f39caed738c38464a60ec6d /scripts/lib/trace-extract.awk | |
| download | trbldoc-657fb0007f39f07cc0401e0c5d03e25df6234aa4.tar.gz trbldoc-657fb0007f39f07cc0401e0c5d03e25df6234aa4.tar.bz2 trbldoc-657fb0007f39f07cc0401e0c5d03e25df6234aa4.zip | |
Inital commit.
Diffstat (limited to 'scripts/lib/trace-extract.awk')
| -rw-r--r-- | scripts/lib/trace-extract.awk | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/scripts/lib/trace-extract.awk b/scripts/lib/trace-extract.awk new file mode 100644 index 0000000..7b8682a --- /dev/null +++ b/scripts/lib/trace-extract.awk @@ -0,0 +1,71 @@ +# scripts/lib/trace-extract.awk +# Extract instrumented source locations from xtrace logs produced via +# scripts/lib/trace-init.sh. +# +# Marker lines look like (bash repeats the leading '@' once per nesting level): +# @@TBL@@ /path/to/trbldoc.sh:1234 1712345678.123456 +# +# Variables: +# MODE=cov (default) -> prints "<base>\t<line>" per marker line +# MODE=time -> prints "<total_ms>\t<hits>\t<base>\t<line>" at END, +# computing per-line durations from consecutive markers +# WITHIN each trace file (one file == one process, so +# parallel xargs workers are not cross-attributed). + +function basename(p) { + sub(/.*\//, "", p) # strip up to last forward slash + sub(/.*\\/, "", p) # strip up to last backslash (defensive) + return p +} + +# Parse a marker line into globals g_base and g_line (and g_epoch for time). +# Returns 1 on success, 0 if the line is not a usable marker. +function parse(line, s, n, f, loc, rest) { + if (line !~ /@+TBL@@ /) return 0 + s = line + sub(/^.*TBL@@ /, "", s) # drop marker and everything before it + n = split(s, f, " ") + if (n < 1) return 0 + loc = f[1] # <source>:<lineno> + if (!match(loc, /:[0-9]+$/)) return 0 + g_line = substr(loc, RSTART + 1) + g_base = basename(substr(loc, 1, RSTART - 1)) + if (MODE == "time") { + g_epoch = (n >= 2 ? f[2] : "") + } + return 1 +} + +BEGIN { if (MODE == "") MODE = "cov" } + +# Reset per-process state at the start of each trace file. +FNR == 1 { have_prev = 0 } + +{ + if (!parse($0)) next + if (MODE == "cov") { + print g_base "\t" g_line + next + } + # MODE == time: attribute elapsed time to the PREVIOUS marker. + if (have_prev && g_epoch != "" && prev_epoch != "") { + d = g_epoch - prev_epoch + if (d < 0) d = 0 + key = prev_base SUBSEP prev_line + ms[key] += d * 1000.0 + hits[key] += 1 + base_of[key] = prev_base + line_of[key] = prev_line + } + prev_base = g_base + prev_line = g_line + prev_epoch = g_epoch + have_prev = 1 +} + +END { + if (MODE != "time") exit + for (k in ms) { + printf "%.3f\t%d\t%s\t%s\n", ms[k], hits[k], base_of[k], line_of[k] + } +} |
