From e5a7d2e063b77ea43eb2d33f1b9c6474e8ffdef8 Mon Sep 17 00:00:00 2001
From: harshithsunku
-
+
-
Sample counts climb live as perf record rounds stream in. Flip to flame graph, click a function, drop into source with line-level heat. Zero polling — Server-Sent Events.
+
Sample counts climb live as chunks stream in from a continuous perf record pipeline. Flip to flame graph, click a function, drop into source with line-level heat. Zero polling — Server-Sent Events.
/proc/sys/kernel/perf_event_paranoid and warns if > 1.cycles, instructions, cache-misses, cache-references, branch-misses, branch-instructions, page-faults, context-switches, cpu-migrations) and keeps only the ones perf record/perf stat actually accepts.cycles, instructions, cache-misses, cache-references, branch-misses, branch-instructions, the cpu-clock and task-clock software events that targets without a hardware PMU sample on, page-faults, context-switches, cpu-migrations) and keeps only the ones perf record/perf stat actually accepts.fp → dwarf → lbr, picks the first that produces non-empty stacks.perf script -F is supported (perf ≥ ~3.12) and falls back to the default output format on older kernels.
- This costs roughly 6–12 seconds on first connection
- and is a one-time hit.
+ The probe is batched — one perf stat over every candidate, one
+ perf record over the survivors — and took
+ 10.8 s on a hybrid x86_64 container and 12.7 s on an
+ 8-core ARM64 board when measured for 0.12.0. It runs once per
+ connection; switching to another process only re-checks that the new
+ pid can be recorded.
- Each round runs perf record and perf stat in parallel for
- N seconds (default 8), then perf script flattens the trace.
- The result — perf script text optionally followed by a
- ### PERF_STAT ### section — is compressed with
- in-process zstd (level 1, vendored in the agent) and pushed over TCP
- with a 5-byte header. Typical compression: 20–40×.
+ Collection is one long-lived pipeline, perf record -o - | perf script -i -,
+ so there is no sampling dead time and symbol tables are parsed once. The agent
+ cuts its output into chunks at sample boundaries every N seconds
+ (default 8) or every 16 MB of text, whichever comes first, and runs
+ perf stat rounds back to back so every interval is counted. Each
+ chunk — perf script text optionally followed by a
+ ### PERF_STAT ### section — is compressed with in-process
+ zstd (level 1, vendored in the agent) and pushed over TCP with a 5-byte
+ header. Measured compression on device captures: about 20×.
+
+ Some old perf builds produce samples through a pipe but drop
+ their call chains (measured on perf 4.4). The capability probe detects
+ that, and the agent falls back to discrete rounds: perf record
+ to a file for N seconds, then perf script on it, with the
+ next round's perf record started while the previous round's
+ perf script runs. perf script runs at
+ nice 5 in both modes, so the profiler yields to the workload.
- Counts update as each perf record round streams in. Flip to flame graph, click a function, land in source with line-level heat. Zero polling — Server-Sent Events.
+ Counts update as each chunk streams in from a continuous perf record pipeline. Flip to flame graph, click a function, land in source with line-level heat. Zero polling — Server-Sent Events.
perf pipeline.The agent runs perf record in 8-second rounds. Each round is zstd-compressed and pushed over TCP. Browser sees flame graphs update as new data arrives.
The agent runs one continuous perf record pipeline and cuts it into chunks every interval or every 16 MB. Each chunk is zstd-compressed and pushed over TCP, and the browser sees flame graphs update as new data arrives.
Single static C agent binary (~2 MB, vendored zstd, zero runtime deps) — runs on anything from bare-metal embedded boards to servers. One-line curl install, built-in self-update.
+Single static C agent binary (about 0.6 MB, vendored zstd, zero runtime deps) — runs on anything from bare-metal embedded boards to servers. One-line curl install, built-in self-update.
- Typical zstd ratio on real perf script output: 20–40×. + Measured zstd ratio on real perf script output from devices: about 20×.
Read the architecture →--pid PID--output; set via UI wizard in daemon modes).--port PORT9999--frequency HZ99perf record -F sampling frequency.--duration SECS8--duration SECS8--output.--rounds N1--output mode).--bind ADDR0.0.0.0--listen mode.--token SECRETPERFLENS_TOKEN). Generated and written to the agent log in --listen mode when not supplied. Never sent over the wire.perf record modes fail
Capability probing tests fp, dwarf, then lbr in sequence — this adds ~10–20 s on a typical target (longer on slow or hybrid-CPU hardware) on first connection. One-time cost; subsequent rounds skip probing.
Capability probing checks events in one batched perf stat and one perf record, then tries fp, dwarf and lbr call graphs and the pipe mode — about 11–13 s on the devices measured for 0.12.0, longer on slow single-core targets. It runs once per connection, and the agent answers status (reporting probing) and stop while it runs; the agent log ends it with Probe finished in N s. Switching process only re-checks the new pid.
perflens/
diff --git a/docs/wire-protocol.svg b/docs/wire-protocol.svg
index 09a58e3..4c7ed4a 100644
--- a/docs/wire-protocol.svg
+++ b/docs/wire-protocol.svg
@@ -102,7 +102,7 @@
bytes 5 … N+4
payload body
- flags 0/1: perf script output (+ optional `### PERF_STAT ###` section) · typical ratio 20-40x with zstd
+ flags 0/1: perf script output (+ optional `### PERF_STAT ###` section) · about 20x with zstd on device captures
flags 2-4: UTF-8 JSON
diff --git a/frontend/src/components/docsContent.ts b/frontend/src/components/docsContent.ts
index 912983d..adf9160 100644
--- a/frontend/src/components/docsContent.ts
+++ b/frontend/src/components/docsContent.ts
@@ -95,7 +95,7 @@ perflens serve --source-dir /path/to/src --binary /path/to/binary
--pid PID--output; set via wizard in daemon modes)--port PORT--frequency HZ--duration SECS--duration SECS--rounds N--output mode only)--bind ADDR0.0.0.0--listen mode--token SECRET--listen mode if not given; never sent over the wireSome containers strip perf capabilities. System-wide perf record -a usually works as a fallback.
Call-graph probing tests fp, dwarf, then lbr sequentially. Normal on first connection.
The capability probe runs once per connection: one batched perf stat, one perf record, the call-graph modes and the pipe mode. It took about 11–13 s on the devices measured for 0.12.0, longer on slow single-core targets. The agent answers status and stop meanwhile, and the control bar shows Probing with a counter. Switching process only re-checks the new pid.
Zstd compression ratio: typically 20–40× on real perf script output.
+Zstd compression ratio: typically about 20× on real perf script output.