1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! A small library to get memory usage and elapsed CPU time.
//!
//! * Supports Windows and Linux.
//! * Async interface, uses `tokio::fs` for file operations
//!
//! ```
//! use simple_process_stats::ProcessStats;
//!
//! # #[tokio::main]
//! # async fn main() {
//! let process_stats = ProcessStats::get().await.expect("could not get stats for running process");
//! println!("{:?}", process_stats);
//! // ProcessStats {
//! //     cpu_time_user: 421.875ms,
//! //     cpu_time_kernel: 102.332ms,
//! //     memory_usage_bytes: 3420160,
//! // }
//! # }
//! ```
//!
//! On Linux, this library reads `/proc/self/stat` and uses the `sysconf` libc function.
//!
//! On Windows, the library uses `GetCurrentProcess` combined with `GetProcessTimes` and `K32GetProcessMemoryInfo`.

#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "windows")]
mod windows;

use std::path::PathBuf;
use std::time::Duration;
use thiserror::Error;

/// Holds the retrieved basic statistics about the running process.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ProcessStats {
    /// How much time this process has spent executing in user mode since it was started
    pub cpu_time_user: Duration,
    /// How much time this process has spent executing in kernel mode since it was started
    pub cpu_time_kernel: Duration,
    /// Size of the "resident" memory the process has allocated, in bytes.
    pub memory_usage_bytes: u64,
}

impl ProcessStats {
    /// Get the statistics using the OS-specific method.
    #[cfg(target_os = "windows")]
    pub async fn get() -> Result<ProcessStats, Error> {
        windows::get_info()
    }

    /// Get the statistics using the OS-specific method.
    #[cfg(target_os = "linux")]
    pub async fn get() -> Result<ProcessStats, Error> {
        linux::get_info().await
    }
}

/// An error that occurred while trying to get the process stats.
#[derive(Error, Debug)]
pub enum Error {
    /// A file's contents could not be read successfully. The file that could not be read is specified by
    /// the `PathBuf` parameter.
    #[error("Failed to read from file `{0}`: {1}")]
    FileRead(PathBuf, std::io::Error),
    /// A file's contents were in an unexpected format
    #[error("File contents are in unexpected format")]
    FileContentsMalformed,

    /// A system-native function returned an error code.
    #[error("Call to system-native API errored: {0}")]
    SystemCall(std::io::Error),
}