#process-memory #performance #monitor #cpu-memory #statistics #perf #safe-wrapper

perfmon

A toolkit designed to be a foundation for applications to monitor their performance

2 releases

0.2.2 Apr 9, 2024
0.2.1 Feb 12, 2024

#123 in Profiling


Used in smolscale2

Custom license

76KB
1.5K SLoC

perf-monitor-rs

github minimum rustc 1.31.0 MIT licensed docs.rs crates.io

# Cargo.toml
[dependencies]
perf_monitor = "0.2"

A toolkit designed to be a foundation for applications to monitor their performance. It is:

  • Cross-Platform: perf-monitor supports Windows, macOS, Linux, iOS, and Android.
  • Safe Wrapper: perf-monitor uses many system C interfaces internally but exposes safe wrapper API outside.
  • Effective: perf-monitor is a thin wrapper around underlying APIs, taking care of not introducing unnecessary overhead, choosing the most lightweight method among many homogeneous APIs.

Features

  • CPU
    • Usage of current process
    • Usage of other process (coming soon)
    • Usage of any thread in current process
    • Logic core number
  • Memory
    • A global allocator that tracks rust allocations
    • Process memory info of current process for Windows and MacOS(Linux is conming soon).
  • IO
    • Disk IO
    • Network IO(coming soon)
  • FD
    • FD number

Example

A simple activity monitor:

    use perf_monitor::cpu::{ThreadStat, ProcessStat, processor_numbers};
    use perf_monitor::fd::fd_count_cur;
    use perf_monitor::io::get_process_io_stats;
    use perf_monitor::mem::get_process_memory_info;

    // cpu
    let core_num = processor_numbers().unwrap();
    let mut stat_p = ProcessStat::cur().unwrap();
    let mut stat_t = ThreadStat::cur().unwrap();

    let _ = (0..1_000).into_iter().sum::<i128>();

    let usage_p = stat_p.cpu().unwrap() * 100f64;
    let usage_t = stat_t.cpu().unwrap() * 100f64;

    println!("[CPU] core Number: {}, process usage: {:.2}%, current thread usage: {:.2}%", core_num, usage_p, usage_t);

    // mem
    let mem_info = get_process_memory_info().unwrap();
    println!("[Memory] memory used: {} bytes, virtural memory used: {} bytes ", mem_info.resident_set_size, mem_info.virtual_memory_size);

    // fd
    let fd_num = fd_count_cur().unwrap();
    println!("[FD] fd number: {}", fd_num);

    // io
    let io_stat = get_process_io_stats().unwrap();   
    println!("[IO] io-in: {} bytes, io-out: {} bytes", io_stat.read_bytes, io_stat.write_bytes);

The above code should have the following output:

[CPU] core Number: 12, process usage: 502.16%, current thread usage: 2.91%
[Memory] memory used: 1073152 bytes, virtural memory used: 4405747712 bytes 
[FD] fd number: 7
[IO] io-in: 0 bytes, io-out: 32768 bytes

See examples for details.

Perfomance

We are concerned about the overhead associated with obtaining performance information. We try to use the most efficient methods while ensuring the API usability.

For example, CPU usage and FD number cost on these devices has following result:

  • MacOS: MacBookPro15,1; 6-Core Intel Core i7; 2.6GHz; 16GB
  • Windows: Windows10; Intel Core i3-2310M; 2.10GHz; 64bit; 4GB
  • Andorid: Pixel 2; android 10
profiling Windows MacOS Android
thread CPU usage (ms) 3 0.45 16
FD number (ms) 0.15 0.07 10

Supported Platform

profiling Windows MacOS iOS Android Linux
CPU
Memory
FD count
IO

See documents of each module for usage and more details.

Rust Version

To compile document require the nightly version, others should work both in stable and nightly version.

cargo build

cargo +nightly doc 

cargo +nightly test
cargo test --lib

Contribution

Contributions are welcome!

Open an issue or create a PR to report bugs, add new features or improve documents and tests. If you are a new contributor, see this page for help.

Why perf-monitor-rs?

There are some crates to do similar things, such as spork, procfs, and sysinfo.

Our application needs to monitor itself at runtime to help us find out performance issues. For example, when the CPU usage rises abnormally, we want to figure out which threads cause this.

However, none of the above crates meet our needs.

  • spork can't get other thread information other than the calling thread. Only memory and CPU information can be processed. And it stops updating for years.
  • procfs looks good enough now, but only support the Linux platform. In its early stages, when we developed perf_monitor_rs, there was no way to get thread information.
  • sysinfo support all platform we need, but we think its interface is not elegant, because an explicit refresh is required before each call, otherwise an old value will be retrieved and you are not able to tell from the returning value. More importantly, it lacks some features like fd, CPU usage.

If you are building a cross-platform application and facing the same problem, we hope perf_monitor_rs can be your first choice.

License

perf-monitor is providing under the MIT license. See LICENSE.

Dependencies

~7–21MB
~320K SLoC