// PROJECT · DEVELOPER TOOLING

PerfLens

Remote Linux perf profiling with a real-time web UI. Drop a dependency-free agent on any ARM or x86 device, point it at a PID, and watch flame graphs, function tables, and line-level annotated source update live in the browser.

  • C
  • Python
  • Linux
  • perf
  • SSE
  • zstd

The pipeline in one sentence: perf record → agent → TCP+zstd → server → parser → source mapper → SSE → browser. The agent runs perf record and perf stat in ~8-second rounds, flattens each round with perf script, compresses it 20–40× with zstd, and streams it over a 5-byte framed TCP protocol. The server parses samples, maps them back to source lines with addr2line, and pushes function tables, interactive SVG flame graphs, and heat-colored source to the browser over Server-Sent Events — no polling.

The constraints were the interesting part. Embedded targets don’t ship a modern Python, so the agent is written for Python 3.5 — no f-strings, no dataclasses — and there’s a single static C binary (~1.8 MB, vendored zstd) for targets with no Python at all. The server is pure stdlib, the UI is vanilla HTML/CSS/JS with hand-rolled flame graphs (no d3, no bundler). The agent probes perf_event_paranoid, enumerates which events the kernel actually supports, and tries call-graph modes (fp, dwarf, lbr) until one produces non-empty stacks — because on real devices, half of them don’t.

Cross-compilation is first-class: --toolchain-prefix derives the right addr2line and readelf, --sysroot resolves shared libraries and source trees, and the same agent code runs on aarch64, aarch64_be, armv7l, and x86_64. Sessions are saved as raw chunks and can be replayed lazily from the UI.

SOURCE CODEgithub.com/harshithsunku/perflensOpen on GitHub ↗

// MORE IN DEVELOPER TOOLING

Tools that make other code easier to see and understand.

All projects →
DEVELOPER TOOLINGC · C++

callsight

Exact per-call timing for the C/C++ code you choose — and zero cost for the code you don't. One config file picks what gets instrumented at compile time; everything else emits no hook at all. No source changes.

CC++PythonGCCMake