Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add disk I/O stats #1376

Merged
merged 8 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,13 @@ core-foundation-sys = "0.8"
[target.'cfg(all(target_os = "linux", not(target_os = "android")))'.dev-dependencies]
tempfile = "3.9"

[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
procfs = "0.17.0"

[dev-dependencies]
serde_json = "1.0" # Used in documentation tests.
bstr = "1.9.0"
tempfile = "3.9"

[[example]]
name = "simple"
Expand Down
22 changes: 19 additions & 3 deletions src/common/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::ffi::OsStr;
use std::fmt;
use std::path::Path;

use crate::DiskUsage;

/// Struct containing a disk information.
///
/// ```no_run
Expand Down Expand Up @@ -144,6 +146,22 @@ impl Disk {
pub fn refresh(&mut self) -> bool {
self.inner.refresh()
}

/// Returns number of bytes read and written by the disk
samin-cf marked this conversation as resolved.
Show resolved Hide resolved
///
/// ⚠️ Note that FreeBSD is not yet supported
///
/// ```no_run
/// use sysinfo::Disks;
///
/// let disks = Disks::new_with_refreshed_list();
/// for disk in disks.list() {
/// println!("[{:?}] disk usage: {:?}", disk.name(), disk.usage());
/// }
/// ```
pub fn usage(&self) -> DiskUsage {
self.inner.usage()
}
}

/// Disks interface.
Expand Down Expand Up @@ -289,9 +307,7 @@ impl Disks {
/// disks.refresh();
/// ```
pub fn refresh(&mut self) {
for disk in self.list_mut() {
disk.refresh();
}
self.inner.refresh();
}

/// The disk list will be emptied then completely recomputed.
Expand Down
41 changes: 41 additions & 0 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@ pub(crate) mod system;
#[cfg(feature = "user")]
pub(crate) mod user;

/// Type containing read and written bytes.
///
/// It is returned by [`Process::disk_usage`][crate::Process::disk_usage] and [`Disk::usage`][crate::Disk::usage].
///
#[cfg_attr(not(all(feature = "system", feature = "disk")), doc = "```ignore")]
/// ```no_run
/// use sysinfo::{Disks, System};
///
/// let s = System::new_all();
/// for (pid, process) in s.processes() {
/// let disk_usage = process.disk_usage();
/// println!("[{}] read bytes : new/total => {}/{} B",
/// pid,
/// disk_usage.read_bytes,
/// disk_usage.total_read_bytes,
/// );
/// println!("[{}] written bytes: new/total => {}/{} B",
/// pid,
/// disk_usage.written_bytes,
/// disk_usage.total_written_bytes,
/// );
/// }
///
/// let disks = Disks::new_with_refreshed_list();
/// for disk in disks.list() {
/// println!("[{:?}] disk usage: {:?}", disk.name(), disk.usage());
/// }
/// ```
#[cfg(any(feature = "disk", feature = "system"))]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd)]
pub struct DiskUsage {
samin-cf marked this conversation as resolved.
Show resolved Hide resolved
/// Total number of written bytes.
pub total_written_bytes: u64,
/// Number of written bytes since the last refresh.
pub written_bytes: u64,
/// Total number of read bytes.
pub total_read_bytes: u64,
/// Number of read bytes since the last refresh.
pub read_bytes: u64,
}

macro_rules! xid {
($(#[$outer:meta])+ $name:ident, $type:ty $(, $trait:ty)?) => {
#[cfg(any(feature = "system", feature = "user"))]
Expand Down
39 changes: 1 addition & 38 deletions src/common/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::fmt;
use std::path::Path;
use std::str::FromStr;

use crate::common::DiskUsage;
use crate::{CpuInner, Gid, ProcessInner, SystemInner, Uid};

/// Structs containing system's information such as processes, memory and CPU.
Expand Down Expand Up @@ -938,44 +939,6 @@ pub struct CGroupLimits {
pub rss: u64,
}

/// Type containing read and written bytes.
///
/// It is returned by [`Process::disk_usage`][crate::Process::disk_usage].
///
/// ⚠️ Files might be cached in memory by your OS, meaning that reading/writing them might not
/// increase the `read_bytes`/`written_bytes` values. You can find more information about it
/// in the `proc_pid_io` manual (`man proc_pid_io` on unix platforms).
///
/// ```no_run
/// use sysinfo::System;
///
/// let s = System::new_all();
/// for (pid, process) in s.processes() {
/// let disk_usage = process.disk_usage();
/// println!("[{}] read bytes : new/total => {}/{} B",
/// pid,
/// disk_usage.read_bytes,
/// disk_usage.total_read_bytes,
/// );
/// println!("[{}] written bytes: new/total => {}/{} B",
/// pid,
/// disk_usage.written_bytes,
/// disk_usage.total_written_bytes,
/// );
/// }
/// ```
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd)]
pub struct DiskUsage {
/// Total number of written bytes.
pub total_written_bytes: u64,
/// Number of written bytes since the last refresh.
pub written_bytes: u64,
/// Total number of read bytes.
pub total_read_bytes: u64,
/// Number of read bytes since the last refresh.
pub read_bytes: u64,
}

/// Enum describing the different status of a process.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ProcessStatus {
Expand Down
3 changes: 2 additions & 1 deletion src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ impl std::fmt::Debug for crate::Disk {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
fmt,
"Disk({:?})[FS: {:?}][Type: {:?}][removable: {}] mounted on {:?}: {}/{} B",
"Disk({:?})[FS: {:?}][Type: {:?}][removable: {}][I/O: {:?}] mounted on {:?}: {}/{} B",
self.name(),
self.file_system(),
self.kind(),
if self.is_removable() { "yes" } else { "no" },
self.usage(),
self.mount_point(),
self.available_space(),
self.total_space(),
Expand Down
9 changes: 6 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ pub use crate::common::disk::{Disk, DiskKind, Disks};
pub use crate::common::network::{IpNetwork, MacAddr, NetworkData, Networks};
#[cfg(feature = "system")]
pub use crate::common::system::{
get_current_pid, CGroupLimits, Cpu, CpuRefreshKind, DiskUsage, LoadAvg, MemoryRefreshKind, Pid,
Process, ProcessRefreshKind, ProcessStatus, ProcessesToUpdate, RefreshKind, Signal, System,
ThreadKind, UpdateKind,
get_current_pid, CGroupLimits, Cpu, CpuRefreshKind, LoadAvg, MemoryRefreshKind, Pid, Process,
ProcessRefreshKind, ProcessStatus, ProcessesToUpdate, RefreshKind, Signal, System, ThreadKind,
UpdateKind,
};
#[cfg(feature = "user")]
pub use crate::common::user::{Group, Groups, User, Users};
Expand All @@ -87,6 +87,9 @@ pub use crate::common::{Gid, Uid};
#[cfg(feature = "system")]
pub use crate::sys::{MINIMUM_CPU_UPDATE_INTERVAL, SUPPORTED_SIGNALS};

#[cfg(any(feature = "system", feature = "disk"))]
pub use crate::common::DiskUsage;

#[cfg(feature = "user")]
pub(crate) use crate::common::user::GroupInner;
#[cfg(feature = "user")]
Expand Down
Loading