mirror of
https://github.com/ClementTsang/bottom.git
synced 2026-07-08 13:40:53 +00:00
feature: FreeBSD add ufs disk io counters (#2055)
This PR adds ufs disk io counters on freebsd by using sysinfo. This PR also updates the Cargo.toml to use the dep syntax for the unused feature flags starship-battery and nvml-wrapper.
This commit is contained in:
Generated
+26
-3
@@ -160,7 +160,6 @@ version = "0.13.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
"cfg-if",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
@@ -1144,6 +1143,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"dispatch2",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1152,6 +1153,16 @@ version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
|
||||
|
||||
[[package]]
|
||||
name = "objc2-foundation"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.2"
|
||||
@@ -1162,6 +1173,17 @@ dependencies = [
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-open-directory"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb82bed227edf5201dfedf072bba4015a33d3d4a98519837295a90f0a23f676d"
|
||||
dependencies = [
|
||||
"objc2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@@ -1910,15 +1932,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.38.4"
|
||||
version = "0.39.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f"
|
||||
checksum = "21d0d938c10fcda3e897e28aaddf4ab462375d411f4378cd63b1c945f69aba96"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"objc2-open-directory",
|
||||
"windows",
|
||||
]
|
||||
|
||||
|
||||
+5
-6
@@ -62,11 +62,11 @@ required-features = ["generate_schema"]
|
||||
|
||||
[features]
|
||||
# Used for general builds.
|
||||
battery = ["starship-battery"]
|
||||
nvidia = ["nvml-wrapper"]
|
||||
gpu = ["nvidia"]
|
||||
battery = ["dep:starship-battery"]
|
||||
nvidia = ["gpu", "dep:nvml-wrapper"]
|
||||
gpu = []
|
||||
zfs = []
|
||||
deploy = ["battery", "gpu", "zfs"]
|
||||
deploy = ["battery", "nvidia", "zfs"]
|
||||
default = ["deploy"]
|
||||
|
||||
# Should not be included in builds.
|
||||
@@ -75,7 +75,6 @@ generate_schema = ["schemars", "serde_json", "strum"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.101"
|
||||
cfg-if = "1.0.4"
|
||||
clap = { version = "4.5.57", features = ["default", "cargo", "wrap_help", "derive"] }
|
||||
concat-string = "1.0.1"
|
||||
crossterm = "0.29.0"
|
||||
@@ -91,7 +90,7 @@ regex = "1.12.3"
|
||||
rustc-hash = "2.1.1"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
starship-battery = { version = "0.10.3", optional = true }
|
||||
sysinfo = "=0.38.4"
|
||||
sysinfo = "=0.39.3"
|
||||
timeless = "0.0.14-alpha"
|
||||
toml_edit = { version = "0.24.0", features = ["serde"] }
|
||||
tui = { version = "0.30.0", package = "ratatui", features = [
|
||||
|
||||
@@ -379,6 +379,10 @@
|
||||
|
||||
# Network widget configuration
|
||||
#[network_graph]
|
||||
|
||||
# Whether to display packet rate and average packet size info. Defaults to false.
|
||||
#show_packets = false
|
||||
|
||||
# By default, there are no network interface filters enabled. An example use case is provided below.
|
||||
#[network_graph.interface_filter]
|
||||
# Whether to ignore any matches. Defaults to true.
|
||||
|
||||
+7
-6
@@ -994,12 +994,13 @@ impl App {
|
||||
let current_process = (id, pids);
|
||||
|
||||
let use_simple_selection = {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] {
|
||||
!self.app_config_fields.is_advanced_kill
|
||||
} else {
|
||||
true
|
||||
}
|
||||
cfg_select! {
|
||||
any(target_os = "linux", target_os = "macos", target_os = "freebsd") => {
|
||||
!self.app_config_fields.is_advanced_kill
|
||||
}
|
||||
_ => {
|
||||
true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+11
-5
@@ -204,16 +204,22 @@ impl StoredData {
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
#[cfg(feature = "zfs")]
|
||||
#[cfg(any(feature = "zfs", target_os = "freebsd"))]
|
||||
{
|
||||
if !device.name.starts_with('/') {
|
||||
Some(device.name.as_str()) // use the whole zfs
|
||||
// dataset name
|
||||
Some(device.name.as_str()) // use the whole name
|
||||
} else {
|
||||
device.name.split('/').next_back()
|
||||
#[cfg(target_os = "freebsd")]
|
||||
{
|
||||
Some(device.mount_point.as_str()) // use mount_point for sysinfo
|
||||
}
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
{
|
||||
device.name.split('/').next_back() // use device name
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "zfs"))]
|
||||
#[cfg(not(any(feature = "zfs", target_os = "freebsd")))]
|
||||
{
|
||||
device.name.split('/').next_back()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use std::time::Instant;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))]
|
||||
use tui::widgets::ListState;
|
||||
use tui::{
|
||||
@@ -21,8 +20,8 @@ use crate::{
|
||||
};
|
||||
|
||||
// Configure signal text based on the target OS.
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
const DEFAULT_KILL_SIGNAL: usize = 15;
|
||||
const SIGNAL_TEXT: [&str; 63] = [
|
||||
"0: Cancel",
|
||||
@@ -89,7 +88,8 @@ cfg_if! {
|
||||
"63: RTMAX-1",
|
||||
"64: RTMAX",
|
||||
];
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
}
|
||||
target_os = "macos" => {
|
||||
const DEFAULT_KILL_SIGNAL: usize = 15;
|
||||
const SIGNAL_TEXT: [&str; 32] = [
|
||||
"0: Cancel",
|
||||
@@ -125,7 +125,8 @@ cfg_if! {
|
||||
"30: USR1",
|
||||
"31: USR2",
|
||||
];
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
const DEFAULT_KILL_SIGNAL: usize = 15;
|
||||
const SIGNAL_TEXT: [&str; 34] = [
|
||||
"0: Cancel",
|
||||
@@ -164,6 +165,7 @@ cfg_if! {
|
||||
"33: LIBRT",
|
||||
];
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
/// Button state type for a [`ProcessKillDialog`].
|
||||
@@ -267,8 +269,8 @@ impl ProcessKillDialog {
|
||||
}
|
||||
ButtonState::Simple { yes, .. } => {
|
||||
if yes {
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "windows")] {
|
||||
cfg_select! {
|
||||
target_os = "windows" => {
|
||||
use crate::utils::process_killer;
|
||||
|
||||
for pid in pids {
|
||||
@@ -277,7 +279,8 @@ impl ProcessKillDialog {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] {
|
||||
}
|
||||
any(target_os = "linux", target_os = "macos", target_os = "freebsd") => {
|
||||
use crate::utils::process_killer;
|
||||
|
||||
for pid in pids {
|
||||
@@ -287,7 +290,8 @@ impl ProcessKillDialog {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
self.state = ProcessKillDialogState::Error { process_name, pid: None, err: "Killing processes is not supported on this platform.".into() };
|
||||
|
||||
}
|
||||
@@ -582,10 +586,11 @@ impl ProcessKillDialog {
|
||||
last_no_button_area: Rect::default(),
|
||||
}
|
||||
} else {
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] {
|
||||
cfg_select! {
|
||||
any(target_os = "linux", target_os = "macos", target_os = "freebsd") => {
|
||||
ButtonState::Signals { state: ListState::default().with_selected(Some(DEFAULT_KILL_SIGNAL)), last_button_draw_area: Rect::default() }
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
ButtonState::Simple { yes: false, last_yes_button_area: Rect::default(), last_no_button_area: Rect::default()}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,10 +176,11 @@ impl Painter {
|
||||
// TODO: [MOUSE] Mouse support for these in search
|
||||
// TODO: [MOVEMENT] Movement support for these in search
|
||||
let (case, whole, regex) = {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "macos")] {
|
||||
cfg_select! {
|
||||
target_os = "macos" => {
|
||||
("Case(F1)", "Whole(F2)", "Regex(F3)")
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
("Case(Alt+C)", "Whole(Alt+W)", "Regex(Alt+R)")
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -126,7 +126,7 @@ pub struct SysinfoSource {
|
||||
pub(crate) network: sysinfo::Networks,
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub(crate) temps: sysinfo::Components,
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd")))]
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
pub(crate) disks: sysinfo::Disks,
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) users: sysinfo::Users,
|
||||
@@ -141,7 +141,7 @@ impl Default for SysinfoSource {
|
||||
network: Networks::new(),
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
temps: Components::new(),
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd")))]
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
disks: Disks::new(),
|
||||
#[cfg(target_os = "windows")]
|
||||
users: Users::new(),
|
||||
@@ -306,7 +306,7 @@ impl DataCollector {
|
||||
/// - Memory usage
|
||||
/// - Network usage
|
||||
/// - Processes (non-Linux)
|
||||
/// - Disk (Windows)
|
||||
/// - Disk (Windows, FreeBSD)
|
||||
/// - Temperatures (non-Linux)
|
||||
fn refresh_sysinfo_data(&mut self) {
|
||||
// Refresh the list of objects once every minute. If it's too frequent it can
|
||||
@@ -326,7 +326,7 @@ impl DataCollector {
|
||||
|
||||
// sysinfo is used on non-Linux systems for the following:
|
||||
// - Processes (users list as well for Windows)
|
||||
// - Disks (Windows only)
|
||||
// - Disks (Windows/FreeBSD)
|
||||
// - Temperatures and temperature components list.
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
@@ -357,7 +357,7 @@ impl DataCollector {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(any(target_os = "windows", target_os = "freebsd"))]
|
||||
if self.widgets_to_harvest.use_disk {
|
||||
if self.should_run_less_routine_tasks {
|
||||
self.sys.disks.refresh(true);
|
||||
@@ -635,7 +635,7 @@ impl DataCollector {
|
||||
fn update_disks(&mut self) {
|
||||
if self.widgets_to_harvest.use_disk || self.widgets_to_harvest.use_disk_io_graph {
|
||||
self.data.disks = disks::get_disk_usage(self).ok();
|
||||
self.data.io = disks::get_io_usage().ok();
|
||||
self.data.io = disks::get_io_usage(self).ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@ pub fn get_cpu_data_list(collector: &DataCollector) -> CollectionResult<CpuHarve
|
||||
let mut cpus = vec![];
|
||||
|
||||
if show_average_cpu {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
cpus.push(CpuData {
|
||||
data_type: CpuDataType::Avg,
|
||||
usage: collector.cgroup_cpu_data.avg_cpu_percent.unwrap_or_else(|| sys.global_cpu_usage()),
|
||||
});
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
cpus.push(CpuData {
|
||||
data_type: CpuDataType::Avg,
|
||||
usage: sys.global_cpu_usage(),
|
||||
|
||||
+20
-12
@@ -1,7 +1,7 @@
|
||||
//! Data collection about disks (e.g. I/O, usage, space).
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "freebsd")] {
|
||||
cfg_select! {
|
||||
target_os = "freebsd" => {
|
||||
mod freebsd;
|
||||
#[cfg(feature = "zfs")]
|
||||
mod io_counters;
|
||||
@@ -10,24 +10,27 @@ cfg_if! {
|
||||
#[cfg(feature = "zfs")]
|
||||
pub use io_counters::IoCounters;
|
||||
pub(crate) use self::freebsd::*;
|
||||
} else if #[cfg(target_os = "windows")] {
|
||||
}
|
||||
target_os = "windows" => {
|
||||
mod windows;
|
||||
pub(crate) use self::windows::*;
|
||||
} else if #[cfg(target_os = "linux")] {
|
||||
}
|
||||
target_os = "linux" => {
|
||||
mod unix;
|
||||
#[cfg(feature = "zfs")]
|
||||
mod zfs_io_counters;
|
||||
pub(crate) use self::unix::*;
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
}
|
||||
target_os = "macos" => {
|
||||
mod unix;
|
||||
pub(crate) use self::unix::*;
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
mod other;
|
||||
pub(crate) use self::other::*;
|
||||
}
|
||||
}
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use rustc_hash::FxHashMap as HashMap;
|
||||
|
||||
use crate::app::filter::Filter;
|
||||
@@ -57,15 +60,17 @@ pub struct IoData {
|
||||
|
||||
pub type IoHarvest = HashMap<String, Option<IoData>>;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] {
|
||||
cfg_select! {
|
||||
any(target_os = "linux", target_os = "macos", target_os = "windows") => {
|
||||
mod io_counters;
|
||||
pub use io_counters::IoCounters;
|
||||
use crate::collection::DataCollector;
|
||||
|
||||
/// Returns the I/O usage of certain mount points.
|
||||
pub fn get_io_usage() -> anyhow::Result<IoHarvest> {
|
||||
pub fn get_io_usage(_collector: &DataCollector) -> anyhow::Result<IoHarvest> {
|
||||
let mut io_hash: HashMap<String, Option<IoData>> = HashMap::default();
|
||||
|
||||
|
||||
// TODO: Maybe rewrite this to not do a result of vec of result...
|
||||
for io in io_stats()?.into_iter() {
|
||||
let mount_point = io.device_name().to_string_lossy();
|
||||
@@ -81,11 +86,14 @@ cfg_if! {
|
||||
|
||||
Ok(io_hash)
|
||||
}
|
||||
} else if #[cfg(not(target_os = "freebsd"))] {
|
||||
pub fn get_io_usage() -> anyhow::Result<IoHarvest> {
|
||||
}
|
||||
not(target_os = "freebsd") => {
|
||||
use crate::collection::DataCollector;
|
||||
pub fn get_io_usage(_collector: &DataCollector) -> anyhow::Result<IoHarvest> {
|
||||
anyhow::bail!("Unsupported OS");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
/// Whether to keep the current disk entry given the filters, disk name, and
|
||||
|
||||
@@ -24,18 +24,23 @@ struct FileSystem {
|
||||
mounted_on: String,
|
||||
}
|
||||
|
||||
pub fn get_io_usage() -> CollectionResult<IoHarvest> {
|
||||
// TODO: Should this (and other I/O collectors) fail fast? In general, should
|
||||
// collection ever fail fast?
|
||||
pub fn get_io_usage(collector: &DataCollector) -> CollectionResult<IoHarvest> {
|
||||
#[cfg_attr(not(feature = "zfs"), expect(unused_mut))]
|
||||
let mut io_harvest: HashMap<String, Option<IoData>> =
|
||||
get_disk_info().map(|storage_system_information| {
|
||||
storage_system_information
|
||||
.filesystem
|
||||
.into_iter()
|
||||
.map(|disk| (disk.name, None))
|
||||
.collect()
|
||||
})?;
|
||||
let mut io_harvest: HashMap<String, Option<IoData>> = collector
|
||||
.sys
|
||||
.disks
|
||||
.iter()
|
||||
.map(|disk| {
|
||||
let usage = disk.usage();
|
||||
(
|
||||
disk.mount_point().to_string_lossy().to_string(),
|
||||
Some(IoData {
|
||||
read_bytes: usage.read_bytes,
|
||||
write_bytes: usage.written_bytes,
|
||||
}),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
|
||||
@@ -5,17 +5,19 @@ mod file_systems;
|
||||
|
||||
mod usage;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
mod linux;
|
||||
pub use linux::*;
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
}
|
||||
target_os = "macos" => {
|
||||
mod other;
|
||||
use other::*;
|
||||
|
||||
mod macos;
|
||||
pub use macos::*;
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
mod other;
|
||||
use other::*;
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ pub(crate) use self::sysinfo::get_ram_usage;
|
||||
|
||||
pub mod sysinfo;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "windows")] {
|
||||
cfg_select! {
|
||||
target_os = "windows" => {
|
||||
mod windows;
|
||||
pub(crate) use self::windows::get_swap_usage;
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
pub(crate) use self::sysinfo::{get_cache_usage, get_swap_usage};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ pub(crate) fn get_arc_usage() -> Option<(MemData, u64)> {
|
||||
use std::num::NonZeroU64;
|
||||
|
||||
let (mem_total, mem_used, mem_min) = {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
// TODO: [OPT] is this efficient?
|
||||
use std::fs::read_to_string;
|
||||
if let Ok(arc_stats) = read_to_string("/proc/spl/kstat/zfs/arcstats") {
|
||||
@@ -45,7 +45,8 @@ pub(crate) fn get_arc_usage() -> Option<(MemData, u64)> {
|
||||
} else {
|
||||
(0, 0, 0)
|
||||
}
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
use sysctl::Sysctl;
|
||||
if let (Ok(mem_arc_value), Ok(mem_sys_value), Ok(mem_min_value)) = (
|
||||
sysctl::Ctl::new("kstat.zfs.misc.arcstats.size"),
|
||||
@@ -62,7 +63,8 @@ pub(crate) fn get_arc_usage() -> Option<(MemData, u64)> {
|
||||
} else {
|
||||
(0, 0, 0)
|
||||
}
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
(0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ fn get_usage(used: u64, total: u64) -> Option<MemData> {
|
||||
pub(crate) fn get_ram_usage(collector: &DataCollector) -> Option<MemData> {
|
||||
let sys = &collector.sys.system;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
use crate::collection::linux::cgroups;
|
||||
|
||||
let base_used = sys.used_memory();
|
||||
@@ -40,7 +40,8 @@ pub(crate) fn get_ram_usage(collector: &DataCollector) -> Option<MemData> {
|
||||
};
|
||||
|
||||
get_usage(used, total)
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
get_usage(sys.used_memory(), sys.total_memory())
|
||||
}
|
||||
}
|
||||
@@ -53,8 +54,8 @@ pub(crate) fn get_ram_usage(collector: &DataCollector) -> Option<MemData> {
|
||||
pub(crate) fn get_swap_usage(collector: &DataCollector) -> Option<MemData> {
|
||||
let sys = &collector.sys.system;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
use crate::collection::linux::cgroups;
|
||||
|
||||
let base_used = sys.used_swap();
|
||||
@@ -75,7 +76,8 @@ pub(crate) fn get_swap_usage(collector: &DataCollector) -> Option<MemData> {
|
||||
};
|
||||
|
||||
get_usage(used, total)
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
get_usage(sys.used_swap(), sys.total_swap())
|
||||
}
|
||||
}
|
||||
|
||||
+35
-22
@@ -3,47 +3,54 @@
|
||||
//! For Linux, this is handled by a custom set of functions.
|
||||
//! For Windows, macOS, FreeBSD, Android, and Linux, this is handled by sysinfo.
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use sysinfo::ProcessStatus;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
pub mod linux;
|
||||
pub use self::linux::*;
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
}
|
||||
target_os = "macos" => {
|
||||
pub mod macos;
|
||||
pub(crate) use self::macos::*;
|
||||
} else if #[cfg(target_os = "windows")] {
|
||||
}
|
||||
target_os = "windows" => {
|
||||
pub mod windows;
|
||||
pub use self::windows::*;
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
pub mod freebsd;
|
||||
pub(crate) use self::freebsd::*;
|
||||
} else if #[cfg(unix)] {
|
||||
}
|
||||
unix => {
|
||||
pub(crate) struct GenericProcessExt;
|
||||
impl UnixProcessExt for GenericProcessExt {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
cfg_select! {
|
||||
unix => {
|
||||
pub mod unix;
|
||||
pub use self::unix::*;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use super::{DataCollector, error::CollectionResult};
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_family = "windows")] {
|
||||
cfg_select! {
|
||||
target_family = "windows" => {
|
||||
/// A Windows process ID.
|
||||
pub type Pid = usize;
|
||||
} else if #[cfg(unix)] {
|
||||
}
|
||||
unix => {
|
||||
/// A UNIX process ID.
|
||||
pub type Pid = libc::pid_t;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
pub type Bytes = u64;
|
||||
@@ -163,8 +170,8 @@ pub struct ProcessHarvest {
|
||||
|
||||
impl DataCollector {
|
||||
pub(crate) fn get_processes(&mut self) -> CollectionResult<Vec<ProcessHarvest>> {
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
let time_diff = self.data.collection_time
|
||||
.duration_since(self.last_collection_time)
|
||||
.as_secs();
|
||||
@@ -173,9 +180,11 @@ impl DataCollector {
|
||||
self,
|
||||
time_diff,
|
||||
)
|
||||
} else if #[cfg(any(target_os = "freebsd", target_os = "macos", target_os = "windows", target_os = "android", target_os = "ios"))] {
|
||||
}
|
||||
any(target_os = "freebsd", target_os = "macos", target_os = "windows", target_os = "android", target_os = "ios") => {
|
||||
sysinfo_process_data(self)
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
Err(crate::collection::error::CollectionError::Unsupported)
|
||||
}
|
||||
}
|
||||
@@ -184,8 +193,8 @@ impl DataCollector {
|
||||
|
||||
/// Pulled from [`ProcessStatus::to_string`] to avoid an alloc.
|
||||
pub(super) fn process_status_str(status: ProcessStatus) -> &'static str {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
match status {
|
||||
ProcessStatus::Idle => "Idle",
|
||||
ProcessStatus::Run => "Runnable",
|
||||
@@ -200,12 +209,14 @@ pub(super) fn process_status_str(status: ProcessStatus) -> &'static str {
|
||||
ProcessStatus::UninterruptibleDiskSleep => "UninterruptibleDiskSleep",
|
||||
_ => "Unknown",
|
||||
}
|
||||
} else if #[cfg(target_os = "windows")] {
|
||||
}
|
||||
target_os = "windows" => {
|
||||
match status {
|
||||
ProcessStatus::Run => "Runnable",
|
||||
_ => "Unknown",
|
||||
}
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
}
|
||||
target_os = "macos" => {
|
||||
match status {
|
||||
ProcessStatus::Idle => "Idle",
|
||||
ProcessStatus::Run => "Runnable",
|
||||
@@ -214,7 +225,8 @@ pub(super) fn process_status_str(status: ProcessStatus) -> &'static str {
|
||||
ProcessStatus::Zombie => "Zombie",
|
||||
_ => "Unknown",
|
||||
}
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
match status {
|
||||
ProcessStatus::Idle => "Idle",
|
||||
ProcessStatus::Run => "Runnable",
|
||||
@@ -225,7 +237,8 @@ pub(super) fn process_status_str(status: ProcessStatus) -> &'static str {
|
||||
ProcessStatus::LockBlocked => "LockBlocked",
|
||||
_ => "Unknown",
|
||||
}
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
"Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
mod user_table;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
pub use user_table::*;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(all(target_family = "unix", not(target_os = "linux")))] {
|
||||
cfg_select! {
|
||||
all(target_family = "unix", not(target_os = "linux")) => {
|
||||
mod process_ext;
|
||||
pub(crate) use process_ext::*;
|
||||
|
||||
@@ -22,16 +21,19 @@ cfg_if! {
|
||||
let total_memory = collector.total_memory();
|
||||
let user_table = &mut collector.user_table;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "macos")] {
|
||||
cfg_select! {
|
||||
target_os = "macos" => {
|
||||
MacOSProcessExt::sysinfo_process_data(sys, use_current_cpu_total, unnormalized_cpu, total_memory, user_table)
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
FreeBSDProcessExt::sysinfo_process_data(sys, use_current_cpu_total, unnormalized_cpu, total_memory, user_table)
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
GenericProcessExt::sysinfo_process_data(sys, use_current_cpu_total, unnormalized_cpu, total_memory, user_table)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use std::{io, time::Duration};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use itertools::Itertools;
|
||||
use sysinfo::{ProcessStatus, System};
|
||||
|
||||
@@ -17,26 +16,29 @@ use crate::{
|
||||
fn get_nice(pid: Pid) -> i32 {
|
||||
// SAFETY: getpriority takes no user pointers; pid is passed as a value
|
||||
// and errors are reported via the return value.
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "freebsd")] {
|
||||
cfg_select! {
|
||||
target_os = "freebsd" => {
|
||||
unsafe { libc::getpriority(libc::PRIO_PROCESS, pid) }
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
}
|
||||
target_os = "macos" => {
|
||||
unsafe { libc::getpriority(libc::PRIO_PROCESS, pid as u32) }
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_priority(pid: Pid) -> i32 {
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "macos")] {
|
||||
cfg_select! {
|
||||
target_os = "macos" => {
|
||||
if let Ok(kinfo) = sysctl_bindings::kinfo_process(pid) {
|
||||
kinfo.kp_proc.p_priority as i32
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
use libc::{c_int, c_void};
|
||||
use std::{mem, ptr};
|
||||
|
||||
@@ -60,7 +62,8 @@ fn get_priority(pid: Pid) -> i32 {
|
||||
};
|
||||
|
||||
if ret == 0 { kp.ki_pri.pri_level as i32 } else { 0 }
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
0
|
||||
}
|
||||
}
|
||||
@@ -204,8 +207,8 @@ pub(crate) trait UnixProcessExt {
|
||||
|
||||
fn convert_process_status_to_char(status: ProcessStatus) -> char {
|
||||
// TODO: Based on https://github.com/GuillaumeGomez/sysinfo/blob/baa46efb46d82f21b773088603720262f4a34646/src/unix/freebsd/process.rs#L13?
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "macos")] {
|
||||
cfg_select! {
|
||||
target_os = "macos" => {
|
||||
// SAFETY: These are all const and should be valid characters.
|
||||
const SIDL: char = unsafe { char::from_u32_unchecked(libc::SIDL) };
|
||||
|
||||
@@ -229,7 +232,8 @@ fn convert_process_status_to_char(status: ProcessStatus) -> char {
|
||||
ProcessStatus::Zombie => SZOMB,
|
||||
_ => '?'
|
||||
}
|
||||
} else if #[cfg(target_os = "freebsd")] {
|
||||
}
|
||||
target_os = "freebsd" => {
|
||||
const fn assert_u8(val: libc::c_char) -> u8 {
|
||||
if val < 0 { panic!("there was an invalid i8 constant that is supposed to be a char") } else { val as u8 }
|
||||
}
|
||||
@@ -252,7 +256,8 @@ fn convert_process_status_to_char(status: ProcessStatus) -> char {
|
||||
ProcessStatus::LockBlocked => SLOCK as char,
|
||||
_ => '?'
|
||||
}
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
'?'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
//! For Linux, this is handled by custom code.
|
||||
//! For everything else, this is handled by sysinfo.
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "linux")] {
|
||||
cfg_select! {
|
||||
target_os = "linux" => {
|
||||
pub mod linux;
|
||||
pub use self::linux::*;
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
pub mod sysinfo;
|
||||
pub use self::sysinfo::*;
|
||||
}
|
||||
|
||||
@@ -628,6 +628,10 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
|
||||
# Network widget configuration
|
||||
#[network_graph]
|
||||
|
||||
# Whether to display packet rate and average packet size info. Defaults to false.
|
||||
#show_packets = false
|
||||
|
||||
# By default, there are no network interface filters enabled. An example use case is provided below.
|
||||
#[network_graph.interface_filter]
|
||||
# Whether to ignore any matches. Defaults to true.
|
||||
|
||||
Reference in New Issue
Block a user