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}