## perf-event: a Rust interface to Linux performance monitoring This crate is a wrapper around the Linux [`perf_event_open`][man] API. It allows you to access a wide variety of the performance monitoring counters that are available in Linux. > This crate is a fork of Jim Blandy's [perf-event crate][jb-perf-event] that > has been updated to support more features of the [`perf_event_open`][man] > API. [man]:https://www.mankier.com/2/perf_event_open [jb-perf-event]: https://github.com/jimblandy/perf-event ## Getting Started Add the following to your `Cargo.toml` ```toml perf-event2 = "0.7" ``` Use `Builder` to create a perf counter, then use `enable` and `disable` to stop and start countinng. Call `read` to get your count. If you need to use multiple counters at once you can use `Group`. If you want to sample events from the kernel, check out `Sampler`. ## Examples For example, this counts the number of cycles used by the call to `println!`. Try adjusting the length of the vector to see the cycle count change. ```rust use perf_event::Builder; use perf_event::events::Hardware; fn main() -> std::io::Result<()> { let mut counter = Builder::new(Hardware::INSTRUCTIONS).build()?; let vec = (0..=51).collect::>(); counter.enable()?; println!("{:?}", vec); counter.disable()?; println!("{} instructions retired", counter.read()?); Ok(()) } ``` The `examples` directory includes programs that count other sorts of events. ## Differences between perf-event2 and perf-event `perf-event2` supports all the same features that `perf-event` does but it also supports the following: - All counter options introduced up to linux kernel 6.0. - Creating a `Group` to monitor anything other than all threads in the current process. - Sampled events via the kernel (e.g. gathering stack traces, etc.). Parsing the records emitted by the kernel is supported via the [`perf-event-data`] crate. - Direct access to the underlying `perf_event_attr` struct exposed by the kernel. [`perf-event-data`]: https://crates.io/crates/perf-event-data ## Migrating From perf-event `perf-event2` v0.4.8 is exactly the same as `perf-event` v0.4.8. You should be to just replace `perf-event -> perf_event2` in your `Cargo.toml` and continue going with no changes. To get the new features, however, you will need to upgrade to v0.5 or later. The main change to be aware of is that `Builder::new` now takes an event directly. Where you would previously do this ```rust,ignore let counter = Builder::new() .kind(some_event) // ... .build()? ``` you will now need to do this instead ```rust,ignore let counter = Builder::new(some_event) // ... .build()?; ``` Note that if you didn't call `kind` the default event type was `Hardware::INSTRUCTIONS`. ## See also - The original [`perf-event`][jb-perf-event] crate is still perfectly workable depending on your use case. - Markus Stange's [`linux-perf-event-reader`][lper] allows you to parse records emitted by perf and should allow you to parse those emitted directly by the kernel as well. - The [`perfcnt`] crate provides similar coverage of the `perf_event_open` API and appears to support parsing samples emitted by the kernel as well. - The [`not-perf`] project is a rewrite of `perf` in Rust, and has a bunch of code for dealing with the Linux perf API. [`perfcnt`]: https://crates.io/crates/perfcnt [lper]: https://crates.io/crates/linux-perf-event-reader [`not-perf`]: https://github.com/koute/not-perf