返回排行榜

GuillaumeGomez/sysinfo

Rust

Cross-platform library to fetch system information

rustsystemunixlinuxraspberrywindowsmacos
Star 增长趋势
Star
2.7k
Forks
417
周增长
Issues
52
1k2k
2015年6月2019年2月2022年11月2026年7月
制品库crates.iocargo add sysinfo
README

sysinfo

sysinfo is a crate used to get a system's information.

Supported OSes

It currently supports the following OSes (alphabetically sorted):

  • Android
  • FreeBSD
  • NetBSD
  • iOS
  • Linux
  • macOS
  • Raspberry Pi
  • Windows

You can still use sysinfo on non-supported OSes, it'll simply do nothing and always return empty values. You can check in your program directly if an OS is supported by checking the [IS_SUPPORTED_SYSTEM] constant.

The minimum-supported version of rustc is 1.95.

Usage

If you want to migrate from an older version, don't hesitate to take a look at the CHANGELOG and at the migration guide.

⚠️ Before any attempt to read the different structs' information, you need to update them to get up-to-date information because for most of them, it works on diff between the current value and the old one.

Which is why, it's much better to keep the same instance of [System] around instead of recreating it multiple times.

You have an example into the examples folder. You can run it with cargo run --example simple.

Otherwise, here is a little code sample:

use sysinfo::{
    Components, Disks, Networks, System,
};

// Please note that we use "new_all" to ensure that all lists of
// CPUs and processes are filled!
println!("=> system:");

// Display system information:
println!("System name:             {:?}", System::name());
println!("System kernel version:   {:?}", System::kernel_version());
println!("System OS version:       {:?}", System::os_version());
println!("System host name:        {:?}", System::host_name());

if let Ok(mut sys) = System::new_all() {
    // First we update all information of our `System` struct.
    sys.refresh_all();

    // RAM and swap information:
    println!("total memory: {} bytes", sys.total_memory());
    println!("used memory : {} bytes", sys.used_memory());
    println!("total swap  : {} bytes", sys.total_swap());
    println!("used swap   : {} bytes", sys.used_swap());

    // Number of CPUs:
    println!("NB CPUs: {}", sys.cpus().len());

    // Display processes ID, name and disk usage:
    for (pid, process) in sys.processes() {
        println!("[{pid}] {:?} {:?}", process.name(), process.disk_usage());
    }
}

// We display all disks' information:
println!("=> disks:");
if let Ok(disks) = Disks::new_with_refreshed_list() {
    for disk in &disks {
        println!("{disk:?}");
    }
}

// Network interfaces name, total data received and total data transmitted:
if let Ok(networks) = Networks::new_with_refreshed_list() {
    println!("=> networks:");
    for (interface_name, data) in &networks {
        println!(
            "{interface_name}: {} B (down) / {} B (up)",
            data.total_received(),
            data.total_transmitted(),
        );
        // If you want the amount of data received/transmitted since last call
        // to `Networks::refresh`, use `received`/`transmitted`.
    }
}

// Components temperature:
if let Ok(components) = Components::new_with_refreshed_list() {
    println!("=> components:");
    for component in &components {
        println!("{component:?}");
    }
}

Please remember that to have some up-to-date information, you need to call the equivalent refresh method. For example, for the CPU usage:

use sysinfo::System;

let Ok(mut sys) = System::new() else { return };

loop {
    sys.refresh_cpu_usage(); // Refreshing CPU usage.
    for cpu in sys.cpus() {
        print!("{}% ", cpu.usage());
    }
    // Sleeping to let time for the system to run for long
    // enough to have useful information.
    std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
}

With the multithread feature (which is not enabled by default), sysinfo uses multiple threads. However, this can increase the memory usage on some platforms (macOS for example).

Good practice / Performance tips

Most of the time, you don't want all information provided by sysinfo but just a subset of it. In this case, it's recommended to use refresh_specifics(...) methods with only what you need to have much better performance.

Another issue frequently encountered: unless you know what you're doing, it's almost all the time better to instantiate the System struct once and use this one instance through your program. The reason is because a lot of information needs a previous measure to be computed (the CPU usage for example). Another example why it's much better: in case you want to list all running processes, sysinfo needs to allocate all memory for the Process struct list, which takes quite some time on the first run.

If your program needs to use a lot of file descriptors, you'd better use:

sysinfo::set_open_files_limit(0);

as sysinfo keeps a number of file descriptors open to have better performance on some targets when refreshing processes.

Running on Raspberry Pi

It'll be difficult to build on Raspberry Pi. A good way-around is to cross-build, then send the executable to your Raspberry Pi.

First install the arm toolchain, for example on Ubuntu:

> sudo apt-get install gcc-multilib-arm-linux-gnueabihf

Then configure cargo to use the corresponding toolchain:

cat << EOF > ~/.cargo/config
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
EOF

Finally, cross compile:

rustup target add armv7-unknown-linux-gnueabihf
cargo build --target=armv7-unknown-linux-gnueabihf

Linux on Docker & Windows Subsystem for Linux (WSL)

Virtual Linux systems, such as those run through Docker and Windows Subsystem for Linux (WSL), do not receive host hardware information via /sys/class/hwmon or /sys/class/thermal. As such, querying for components may return no results (or unexpected results) when using this library on virtual systems.

Use in binaries running inside the macOS or iOS Sandbox/stores

Apple has restrictions as to which APIs can be linked into binaries that are distributed through the app store. By default, sysinfo is not compatible with these restrictions. You can use the apple-app-store feature flag to disable the Apple prohibited features. This also enables the apple-sandbox feature. In the case of applications using the sandbox outside of the app store, the apple-sandbox feature can be used alone to avoid causing policy violations at runtime.

How it works

I wrote a blog post you can find here which explains how sysinfo extracts information on the different systems.

Running tests

Because we're looking at system information, some tests have a better chance to succeed when there is a limited number of parallel running tests. To ensure they all pass, use:

cargo test -- --test-threads=1

C interface

It's possible to use this crate directly from C. Take a look at the Makefile and at the examples/simple.c file.

To build the C example, just run:

> make
> ./simple
# If needed:
> LD_LIBRARY_PATH=target/debug/ ./simple

Benchmarks

You can run the benchmarks locally with rust nightly by doing:

> cargo bench

Donations

If you appreciate my work and want to support me, you can do it with github sponsors or with patreon.

相关仓库
farion1231/cc-switch

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

Rustcrates.ioMIT Licenseai-toolsclaude-code
ccswitch.io
119.8k8k
rustdesk/rustdesk

An open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.

Rustcrates.ioGNU Affero General Public License v3.0remote-controlremote-desktop
rustdesk.com
118.6k18.1k
rust-lang/rust

Empowering everyone to build reliable and efficient software.

Rustcrates.ioApache License 2.0rustcompiler
rust-lang.org
114.8k15.4k
tauri-apps/tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.

Rustcrates.ioApache License 2.0rustwebview
tauri.app
109.3k3.8k
denoland/deno

A modern runtime for JavaScript and TypeScript.

Rustcrates.ioMIT Licensedenotypescript
deno.com
107.8k6.2k
oven-sh/bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one

Rustcrates.ioOtherbunbundler
bun.com
95k4.9k
unionlabs/union

The trust-minimized, zero-knowledge bridging protocol, designed for censorship resistance, extremely high security, and usage in decentralized finance.

Rustcrates.ioApache License 2.0blockchaincosmos
union.build
73.9k3.9k
rtk-ai/rtk

CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies

Rustcrates.ioApache License 2.0agentic-codingai-coding
rtk-ai.app
72.4k4.5k
toeverything/AFFiNE

There can be more than Notion and Miro. AFFiNE(pronounced [ə‘fain]) is a next-gen knowledge base that brings planning, sorting and creating all together. Privacy first, open-source, customizable and ready to use.

TypeScriptnpmOthereditorcrdt
affine.pro
70.7k5.1k
openinterpreter/openinterpreter

A coding agent for open models like Kimi K3

Rustcrates.ioApache License 2.0coding-agentdeepseek
openinterpreter.com
67.1k5.8k
BurntSushi/ripgrep

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

Rustcrates.ioThe Unlicenseripgreprecursively-search
66.4k2.7k
alacritty/alacritty

A cross-platform, OpenGL terminal emulator.

Rustcrates.ioApache License 2.0terminal-emulatorsopengl
alacritty.org
65k3.5k