parallel_processor/
simple_process_stats.rs

1#![deny(clippy::all)]
2#![deny(clippy::cargo)]
3
4//! A small library to get memory usage and elapsed CPU time.
5//!
6//! * Supports Windows, Linux and macOS.
7//! * Async interface, uses `tokio::fs` for file operations
8//!
9//! ```rust
10//! use crate::parallel_processor::simple_process_stats::ProcessStats;
11//!
12//! # #[tokio::main]
13//! # async fn main() {
14//! let process_stats = ProcessStats::get().expect("could not get stats for running process");
15//! crate::log_info!("{:?}", process_stats);
16//! // ProcessStats {
17//! //     cpu_time_user: 421.875ms,
18//! //     cpu_time_kernel: 102.332ms,
19//! //     memory_usage_bytes: 3420160,
20//! // }
21//! # }
22//! ```
23//!
24//! On Linux, this library reads `/proc/self/stat` and uses the `sysconf` libc function.
25//!
26//! On Windows, the library uses `GetCurrentProcess` combined with `GetProcessTimes` and `K32GetProcessMemoryInfo`.
27//!
28//! On macOS, this library uses `proc_pidinfo` from `libproc` (and current process ID is determined via `libc`).
29
30#[cfg(target_os = "linux")]
31mod linux;
32#[cfg(target_os = "macos")]
33mod macos;
34#[cfg(target_os = "windows")]
35mod windows;
36
37use std::path::PathBuf;
38use std::time::Duration;
39use thiserror::Error;
40
41/// Holds the retrieved basic statistics about the running process.
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43pub struct ProcessStats {
44    /// How much time this process has spent executing in user mode since it was started
45    pub cpu_time_user: Duration,
46    /// How much time this process has spent executing in kernel mode since it was started
47    pub cpu_time_kernel: Duration,
48    /// Size of the "resident" memory the process has allocated, in bytes.
49    pub memory_usage_bytes: u64,
50}
51
52impl ProcessStats {
53    /// Get the statistics using the OS-specific method.
54    #[cfg(target_os = "windows")]
55    pub fn get() -> Result<ProcessStats, Error> {
56        windows::get_info()
57    }
58
59    /// Get the statistics using the OS-specific method.
60    #[cfg(target_os = "linux")]
61    pub fn get() -> Result<ProcessStats, Error> {
62        linux::get_info()
63    }
64
65    /// Get the statistics using the OS-specific method.
66    #[cfg(target_os = "macos")]
67    pub fn get() -> Result<ProcessStats, Error> {
68        macos::get_info()
69    }
70}
71
72/// An error that occurred while trying to get the process stats.
73#[derive(Error, Debug)]
74pub enum Error {
75    /// A file's contents could not be read successfully. The file that could not be read is specified by
76    /// the `PathBuf` parameter.
77    #[error("Failed to read from file `{0}`: {1}")]
78    FileRead(PathBuf, std::io::Error),
79    /// A file's contents were in an unexpected format
80    #[error("File contents are in unexpected format")]
81    FileContentsMalformed,
82
83    /// A system-native function returned an error code.
84    #[error("Call to system-native API errored: {0}")]
85    SystemCall(std::io::Error),
86}