|
1 | 1 | # flame_on_processor |
2 | 2 |
|
3 | | -A Zig library that processes flame graph profiling data into [pprof](https://github.com/google/pprof) protobuf format. |
| 3 | +[](https://github.com/DockYard/flame_on_processor/actions/workflows/ci.yml) |
| 4 | +[](LICENSE) |
4 | 5 |
|
5 | | -Takes semicolon-delimited stack paths with durations, filters out functions below a configurable time threshold, and encodes the result as a pprof `Profile` protobuf. |
| 6 | +A Zig library that transforms flame graph profiling data into the [pprof](https://github.com/google/pprof) protobuf format. |
6 | 7 |
|
7 | | -## Usage |
| 8 | +It takes semicolon-delimited stack paths paired with durations, filters out functions that fall below a configurable time threshold, and encodes the result as a pprof `Profile` protobuf — ready for visualization in tools like [pprof](https://github.com/google/pprof) and [speedscope](https://www.speedscope.app). |
| 9 | + |
| 10 | +## Installation |
| 11 | + |
| 12 | +Requires **Zig 0.15.2+**. |
| 13 | + |
| 14 | +```sh |
| 15 | +zig fetch --save git+https://github.com/DockYard/flame_on_processor.git |
| 16 | +``` |
| 17 | + |
| 18 | +Then add the dependency in your `build.zig`: |
| 19 | + |
| 20 | +```zig |
| 21 | +const flame_on_processor = b.dependency("flame_on_processor", .{ |
| 22 | + .target = target, |
| 23 | +}); |
| 24 | +exe.root_module.addImport("flame_on_processor", flame_on_processor.module("flame_on_processor")); |
| 25 | +``` |
8 | 26 |
|
9 | | -Add as a Zig package dependency, then import: |
| 27 | +## Usage |
10 | 28 |
|
11 | 29 | ```zig |
12 | 30 | const processor = @import("flame_on_processor").processor; |
13 | 31 |
|
14 | 32 | const encoded = try processor.process( |
15 | 33 | allocator, |
16 | | - &.{ "main;compute", "main;render" }, |
17 | | - &.{ 3000, 4000 }, |
| 34 | + &.{ "main;compute", "main;render", "main;idle" }, |
| 35 | + &.{ 3000, 4000, 200 }, |
18 | 36 | 0.01, // filter threshold: fraction of total time |
19 | 37 | ); |
20 | 38 | defer allocator.free(encoded); |
21 | | -// `encoded` is pprof protobuf bytes |
| 39 | +// `encoded` contains pprof protobuf bytes |
22 | 40 | ``` |
23 | 41 |
|
24 | | -## Modules |
| 42 | +### Parameters |
25 | 43 |
|
26 | | -- **processor** — top-level API: filter then encode in one call |
27 | | -- **profile_filter** — removes functions whose inclusive time falls below a threshold fraction, consolidating small subtrees |
28 | | -- **pprof_encoder** — encodes filtered samples into pprof protobuf wire format |
29 | | -- **protobuf** — low-level protobuf encoding primitives |
| 44 | +| Parameter | Type | Description | |
| 45 | +|-------------|-------------------------|-----------------------------------------------------------------------------| |
| 46 | +| `allocator` | `std.mem.Allocator` | Allocator for all internal and returned memory | |
| 47 | +| `paths` | `[]const []const u8` | Semicolon-delimited stack traces (e.g. `"main;compute;render"`) | |
| 48 | +| `durations` | `[]const u64` | Duration in microseconds for each path (parallel array) | |
| 49 | +| `threshold` | `f64` | Fraction of total time below which functions are filtered out (min `0.005`) | |
| 50 | + |
| 51 | +Returns an allocated `[]u8` containing the protobuf-encoded pprof Profile. Caller owns the memory. |
| 52 | + |
| 53 | +## Architecture |
| 54 | + |
| 55 | +``` |
| 56 | + paths + durations |
| 57 | + │ |
| 58 | + ▼ |
| 59 | + ┌─────────────────┐ |
| 60 | + │ processor │ top-level API |
| 61 | + └────────┬────────┘ |
| 62 | + │ |
| 63 | + ┌───────┴───────┐ |
| 64 | + ▼ ▼ |
| 65 | +┌──────────────┐ ┌──────────────┐ |
| 66 | +│profile_filter│ │pprof_encoder │ |
| 67 | +└──────────────┘ └──────┬───────┘ |
| 68 | + │ |
| 69 | + ▼ |
| 70 | + ┌──────────────┐ |
| 71 | + │ protobuf │ |
| 72 | + └──────────────┘ |
| 73 | +``` |
30 | 74 |
|
31 | | -## Building |
| 75 | +- **processor** — top-level API: filter then encode in one call |
| 76 | +- **profile_filter** — removes functions whose inclusive time falls below the threshold, consolidating small subtrees into placeholder entries |
| 77 | +- **pprof_encoder** — encodes filtered samples into pprof protobuf wire format with proper string table deduplication |
| 78 | +- **protobuf** — low-level protobuf encoding primitives (varints, length-delimited fields, packed arrays) |
32 | 79 |
|
33 | | -Requires Zig 0.15+. |
| 80 | +## Development |
34 | 81 |
|
35 | 82 | ```sh |
36 | | -zig build # build the library |
37 | | -zig build test # run tests |
| 83 | +zig build # build the library |
| 84 | +zig build test # run all tests |
38 | 85 | ``` |
| 86 | + |
| 87 | +## License |
| 88 | + |
| 89 | +[MIT](LICENSE) - Copyright (c) 2025 DockYard, Inc. |
0 commit comments