samply icon indicating copy to clipboard operation
samply copied to clipboard

Idea: A companion crate for markers

Open nordzilla opened this issue 1 year ago • 1 comments

Background

This issue is inspired by this conversation in Mozilla's Firefox Profiler Matrix channel.

It would be amazing to have a companion crate, e.g. samply-markers, that one could add to their project as a dependency. This crate would expose an API where the programmer could create new markers directly in their code that are compatible the the Firefox Profiler.

The crate would be responsible for recording the markers and persisting them in such a way that samply can locate them and insert them into the resulting profile.json.

@gregtatum presented an interesting thought on the idea:

"Ok, here's an idea if I'm understanding mmap correctly, which I haven't ever used in practice myself. The user's program imports the marker Rust crate. The marker crate mmaps a file at some kind of known path. As it collects markers from the user program, it writes them into the mmaped space. I believe this will lazily be persisted to file so shouldn't cause a performance problem. When the user program exits, samply reads in that file and pulls out all the markers. Samply is then in charge of persisting that data into the profile JSON format and joining it to the sampled data."

nordzilla avatar Sep 06 '24 16:09 nordzilla

There's actually already support on mac/linux for parsing a marker-{pid}.txt file that a process opens, however the file format is extremely simple (literally "[time] [name]"), which is not good for anything but low frequency markers and doesn't support ranges. Needs some care to do things like define markers up front and then refer to them by ID + provide binary payload in the actual marker stream.

vvuk avatar Sep 16 '24 19:09 vvuk

There's actually already support on mac/linux for parsing a marker-{pid}.txt file that a process opens, however the file format is extremely simple (literally "[time] [name]"), which is not good for anything but low frequency markers and doesn't support ranges. Needs some care to do things like define markers up front and then refer to them by ID + provide binary payload in the actual marker stream.

@vvuk the format is simple but the timestamp seems tricky, how can i align the timestamp with samply's internal timeline, is there any public api for generate timestamp which align with internal timeline?

hardfist avatar Mar 19 '25 03:03 hardfist

@vvuk the format is simple but the timestamp seems tricky, how can i align the timestamp with samply's internal timeline, is there any public api for generate timestamp which align with internal timeline?

At least on Linux, the timestamps are from the kernel's monotonic clock. You can get appropriate values with the nix crate:

use nix::time::{clock_gettime, ClockId};

let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap();
now.tv_sec() as i64 * 1_000_000_000 + now.tv_nsec() as i64

blp avatar Aug 19 '25 15:08 blp

There's actually already support on mac/linux for parsing a marker-{pid}.txt file that a process opens, however the file format is extremely simple (literally "[time] [name]"), which is not good for anything but low frequency markers and doesn't support ranges. Needs some care to do things like define markers up front and then refer to them by ID + provide binary payload in the actual marker stream.

The file format is start end name, specifying a range. (I've been using it the last few days.)

blp avatar Aug 19 '25 15:08 blp