From 0eafb2bde720b08c53eb329304d2730c150ad196 Mon Sep 17 00:00:00 2001 From: Andrew Houts <16907671+ahouts@users.noreply.github.com> Date: Sat, 28 Sep 2019 22:55:49 -0700 Subject: [PATCH] feat: add memory usage module (#403) Adds a module to display system memory and swap usage. --- Cargo.lock | 27 ++++++++++++ Cargo.toml | 2 + docs/config/README.md | 31 +++++++++++++ src/module.rs | 1 + src/modules/memory_usage.rs | 87 +++++++++++++++++++++++++++++++++++++ src/modules/mod.rs | 2 + src/print.rs | 1 + 7 files changed, 151 insertions(+) create mode 100644 src/modules/memory_usage.rs diff --git a/Cargo.lock b/Cargo.lock index 5cab5584..5ca77760 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,6 +108,11 @@ dependencies = [ "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "byte-unit" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "c2-chacha" version = "0.2.2" @@ -242,6 +247,11 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "doc-comment" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "either" version = "1.5.2" @@ -727,6 +737,7 @@ version = "0.19.0" dependencies = [ "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "battery 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-unit 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -738,6 +749,7 @@ dependencies = [ "pretty_env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -769,6 +781,18 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sysinfo" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempfile" version = "3.1.0" @@ -959,6 +983,7 @@ dependencies = [ "checksum battery 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6d6fe5630049e900227cd89afce4c1204b88ec8e61a2581bb96fcce26f047b" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum byte-unit 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6894a79550807490d9f19a138a6da0f8830e70c83e83402dd23f16fd6c479056" "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" @@ -974,6 +999,7 @@ dependencies = [ "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" @@ -1040,6 +1066,7 @@ dependencies = [ "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" +"checksum sysinfo 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d5bd3b813d94552a8033c650691645f8dd5a63d614dddd62428a95d3931ef7b6" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" diff --git a/Cargo.toml b/Cargo.toml index 75b08a2f..303e6f91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,8 @@ unicode-segmentation = "1.3.0" gethostname = "0.2.0" once_cell = "1.2.0" chrono = "0.4" +sysinfo = "0.9.5" +byte-unit = "3.0.3" [dev-dependencies] tempfile = "3.1.0" diff --git a/docs/config/README.md b/docs/config/README.md index e968d156..37cd0e25 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -97,6 +97,7 @@ prompt_order = [ "golang", "java", "nix_shell", + "memory_usage", "aws", "env_var", "cmd_duration", @@ -571,6 +572,36 @@ impure_msg = "impure shell" pure_msg = "pure shell" ``` +## Memory Usage + +The `memory_usage` module shows current system memory and swap usage. + +By default the swap usage is displayed if the total system swap is non-zero. + +### Options + +| Variable | Default | Description | +| ----------------- | ------------------------ | ------------------------------------------------------------- | +| `show_percentage` | `false` | Display memory usage as a percentage of the available memory. | +| `show_swap` | when total swap non-zero | Display swap usage. | +| `threshold` | `75` | Hide the memory usage unless it exceeds this percentage. | +| `symbol` | `"🐏 "` | The symbol used before displaying the memory usage. | +| `style` | `"bold dimmed white"` | The style for the module. | +| `disabled` | `false` | Disables the `memory_usage` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[memory_usage] +show_percentage = true +show_swap = true +threshold = -1 +icon = " " +style = "bold dimmed green" +``` + ## Java The `java` module shows the currently installed version of Java. diff --git a/src/module.rs b/src/module.rs index 7ebfa53e..65e69c36 100644 --- a/src/module.rs +++ b/src/module.rs @@ -21,6 +21,7 @@ pub const ALL_MODULES: &[&str] = &[ "java", "jobs", "line_break", + "memory_usage", "nix_shell", "nodejs", "package", diff --git a/src/modules/memory_usage.rs b/src/modules/memory_usage.rs new file mode 100644 index 00000000..b8fe4fbf --- /dev/null +++ b/src/modules/memory_usage.rs @@ -0,0 +1,87 @@ +use ansi_term::Color; + +use super::{Context, Module}; +use byte_unit::{Byte, ByteUnit}; +use sysinfo::{RefreshKind, SystemExt}; + +/// Creates a module with system memory usage information +pub fn module<'a>(context: &'a Context) -> Option> { + const DEFAULT_THRESHOLD: i64 = 75; + const DEFAULT_SHOW_PERCENTAGE: bool = false; + const RAM_CHAR: &str = "🐏 "; + + let mut module = context.new_module("memory_usage"); + + let module_style = module + .config_value_style("style") + .unwrap_or_else(|| Color::White.bold().dimmed()); + + let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_system()); + + let used_memory_kib = system.get_used_memory(); + let total_memory_kib = system.get_total_memory(); + let used_swap_kib = system.get_used_swap(); + let total_swap_kib = system.get_total_swap(); + + let percent_mem_used = (used_memory_kib as f64 / total_memory_kib as f64) * 100.; + let percent_swap_used = (used_swap_kib as f64 / total_swap_kib as f64) * 100.; + + let threshold = module + .config_value_i64("threshold") + .unwrap_or(DEFAULT_THRESHOLD); + + if percent_mem_used.round() < threshold as f64 { + return None; + } + + let show_percentage = module + .config_value_bool("show_percentage") + .unwrap_or(DEFAULT_SHOW_PERCENTAGE); + + let (display_mem, display_swap) = if show_percentage { + ( + format!("{:.0}%", percent_mem_used), + format!("{:.0}%", percent_swap_used), + ) + } else { + fn format_kib(n_kib: u64) -> String { + let byte = Byte::from_unit(n_kib as f64, ByteUnit::KiB) + .unwrap_or_else(|_| Byte::from_bytes(0)); + let mut display_bytes = byte.get_appropriate_unit(true).format(0); + display_bytes.retain(|c| c != ' '); + display_bytes + } + ( + format!( + "{}/{}", + format_kib(used_memory_kib), + format_kib(total_memory_kib) + ), + format!( + "{}/{}", + format_kib(used_swap_kib), + format_kib(total_swap_kib) + ), + ) + }; + + let show_swap = module + .config_value_bool("show_swap") + .unwrap_or(total_swap_kib != 0); + + module.new_segment("symbol", RAM_CHAR); + + module.set_style(module_style); + if show_swap { + module.new_segment( + "memory_usage", + &format!("{} | {}", display_mem, display_swap), + ); + } else { + module.new_segment("memory_usage", &display_mem); + } + + module.get_prefix().set_value(""); + + Some(module) +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 82d3614a..f073c5a6 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -12,6 +12,7 @@ mod hostname; mod java; mod jobs; mod line_break; +mod memory_usage; mod nix_shell; mod nodejs; mod package; @@ -52,6 +53,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "nix_shell" => nix_shell::module(context), "hostname" => hostname::module(context), "time" => time::module(context), + "memory_usage" => memory_usage::module(context), _ => { eprintln!("Error: Unknown module {}. Use starship module --list to list out all supported modules.", module); diff --git a/src/print.rs b/src/print.rs index 18fe5ea1..eed2ee8b 100644 --- a/src/print.rs +++ b/src/print.rs @@ -26,6 +26,7 @@ const DEFAULT_PROMPT_ORDER: &[&str] = &[ "golang", "java", "nix_shell", + "memory_usage", "aws", "env_var", "cmd_duration",