feature: Support memb (mem bytes) searching in processes

Supports searching by the new mem value.
This commit is contained in:
Clement Tsang 2020-08-21 19:59:49 -07:00 committed by GitHub
parent ff15649be7
commit c82f4d40b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 37 deletions

View File

@ -28,10 +28,12 @@
"hjkl", "hjkl",
"libc", "libc",
"markdownlint", "markdownlint",
"memb",
"minwindef", "minwindef",
"noheader", "noheader",
"ntdef", "ntdef",
"paren", "paren",
"pmem",
"processthreadsapi", "processthreadsapi",
"regexes", "regexes",
"rsplitn", "rsplitn",

View File

@ -269,7 +269,7 @@ Run using `btm`.
### Process searching keywords ### Process searching keywords
- Note none of the keywords are case sensitive. - None of the keywords are case sensitive.
- Use brackets to logically group together parts of the search. - Use brackets to logically group together parts of the search.
- Furthermore, if you want to search a reserved keyword, surround the text in quotes - for example, `"or" or "(sd-pam)"` would be a valid search: - Furthermore, if you want to search a reserved keyword, surround the text in quotes - for example, `"or" or "(sd-pam)"` would be a valid search:
@ -277,15 +277,18 @@ Run using `btm`.
#### Supported keywords #### Supported keywords
Searching without a keyword will search by process or command name (depends on what column is being shown by the current process widget).
| Keywords | Example | Description | | Keywords | Example | Description |
| -------- | --------------- | ------------------------------------------------------------------------------- | | -------- | ------------------ | ------------------------------------------------------------------------------------------------- |
| `pid` | `pid: 1044` | Matches by PID; supports regex and requiring matching the entire PID | | `pid` | `pid: 1044` | Matches by PID; supports regex and requiring matching the entire PID |
| `cpu` | `cpu > 0.5` | Matches the condition for the CPU column; supports comparison operators | | `cpu` | `cpu > 0.5` | Matches the condition for the CPU column; supports comparison operators |
| `mem` | `mem < 0.5` | Matches the condition for the memory column; supports comparison operators | | `memb` | `memb > 1000 b` | Matches the condition for the memory column in terms of bytes; supports comparison operators |
| `read` | `read = 1` | Matches the condition for the read/s column; supports comparison operators | | `mem` | `mem < 0.5` | Matches the condition for the memory column in terms of percent; supports comparison operators |
| `write` | `write >= 1` | Matches the condition for the write/s column; supports comparison operators | | `read` | `read = 1 mb` | Matches the condition for the read/s column in terms of bytes; supports comparison operators |
| `tread` | `tread <= 1024` | Matches the condition for the total read column; supports comparison operators | | `write` | `write >= 1 kb` | Matches the condition for the write/s column in terms of bytes; supports comparison operators |
| `twrite` | `twrite > 1024` | Matches the condition for the total write column; supports comparison operators | | `tread` | `tread <= 1024 gb` | Matches the condition for the total read column in terms of bytes; supports comparison operators |
| `twrite` | `twrite > 1024 tb` | Matches the condition for the total write column in terms of bytes; supports comparison operators |
#### Supported comparison operators #### Supported comparison operators

View File

@ -60,7 +60,7 @@ pub struct ProcessHarvest {
pub pid: u32, pub pid: u32,
pub cpu_usage_percent: f64, pub cpu_usage_percent: f64,
pub mem_usage_percent: f64, pub mem_usage_percent: f64,
pub mem_usage_kb: u64, pub mem_usage_bytes: u64,
// pub rss_kb: u64, // pub rss_kb: u64,
// pub virt_kb: u64, // pub virt_kb: u64,
pub name: String, pub name: String,
@ -282,7 +282,8 @@ fn read_proc<S: core::hash::BuildHasher>(
)?; )?;
let (_vsize, rss) = get_linux_process_vsize_rss(&stat); let (_vsize, rss) = get_linux_process_vsize_rss(&stat);
let mem_usage_kb = rss * page_file_kb; let mem_usage_kb = rss * page_file_kb;
let mem_usage_percent = mem_usage_kb as f64 * 100.0 / mem_total_kb as f64; let mem_usage_percent = mem_usage_kb as f64 / mem_total_kb as f64 * 100.0;
let mem_usage_bytes = mem_usage_kb * 1024;
// This can fail if permission is denied! // This can fail if permission is denied!
let (total_read_bytes, total_write_bytes, read_bytes_per_sec, write_bytes_per_sec) = let (total_read_bytes, total_write_bytes, read_bytes_per_sec, write_bytes_per_sec) =
@ -320,7 +321,7 @@ fn read_proc<S: core::hash::BuildHasher>(
name, name,
command, command,
mem_usage_percent, mem_usage_percent,
mem_usage_kb, mem_usage_bytes,
cpu_usage_percent, cpu_usage_percent,
total_read_bytes, total_read_bytes,
total_write_bytes, total_write_bytes,
@ -429,7 +430,7 @@ pub fn windows_macos_get_processes_list(
} else { } else {
0.0 0.0
}, },
mem_usage_kb: process_val.memory(), mem_usage_bytes: process_val.memory() * 1024,
cpu_usage_percent: process_cpu_usage, cpu_usage_percent: process_cpu_usage,
read_bytes_per_sec: disk_usage.read_bytes, read_bytes_per_sec: disk_usage.read_bytes,
write_bytes_per_sec: disk_usage.written_bytes, write_bytes_per_sec: disk_usage.written_bytes,

View File

@ -46,11 +46,17 @@ pub fn kill_process_given_pid(pid: u32) -> crate::utils::error::Result<()> {
_ => "Unknown error occurred." _ => "Unknown error occurred."
}; };
return Err(BottomError::GenericError(format!( return if let Some(err_code) = err_code {
Err(BottomError::GenericError(format!(
"Error code {} - {}", "Error code {} - {}",
err_code.unwrap_or(-1), err_code, err,
)))
} else {
Err(BottomError::GenericError(format!(
"Error code ??? - {}",
err, err,
))); )))
};
} }
} }
} else if cfg!(target_os = "windows") { } else if cfg!(target_os = "windows") {

View File

@ -334,7 +334,8 @@ impl ProcessQuery for ProcWidgetState {
let mut value = read_value; let mut value = read_value;
match prefix_type { match prefix_type {
PrefixType::Rps PrefixType::MemBytes
| PrefixType::Rps
| PrefixType::Wps | PrefixType::Wps
| PrefixType::TRead | PrefixType::TRead
| PrefixType::TWrite => { | PrefixType::TWrite => {
@ -562,8 +563,9 @@ impl Debug for And {
#[derive(Debug)] #[derive(Debug)]
pub enum PrefixType { pub enum PrefixType {
Pid, Pid,
Cpu, PCpu,
Mem, MemBytes,
PMem,
Rps, Rps,
Wps, Wps,
TRead, TRead,
@ -579,9 +581,12 @@ impl std::str::FromStr for PrefixType {
use PrefixType::*; use PrefixType::*;
let lower_case = s.to_lowercase(); let lower_case = s.to_lowercase();
// Didn't add %cpu, %mem, mem_bytes, total_read, and total_write
// for now as it causes help to be clogged.
match lower_case.as_str() { match lower_case.as_str() {
"cpu" => Ok(Cpu), "cpu" => Ok(PCpu),
"mem" => Ok(Mem), "mem" => Ok(PMem),
"memb" => Ok(MemBytes),
"read" => Ok(Rps), "read" => Ok(Rps),
"write" => Ok(Wps), "write" => Ok(Wps),
"tread" => Ok(TRead), "tread" => Ok(TRead),
@ -669,17 +674,21 @@ impl Prefix {
} }
} else if let Some((prefix_type, numerical_query)) = &self.compare_prefix { } else if let Some((prefix_type, numerical_query)) = &self.compare_prefix {
match prefix_type { match prefix_type {
PrefixType::Cpu => matches_condition( PrefixType::PCpu => matches_condition(
&numerical_query.condition, &numerical_query.condition,
process.cpu_percent_usage, process.cpu_percent_usage,
numerical_query.value, numerical_query.value,
), ),
// FIXME: This doesn't work with mem values! PrefixType::PMem => matches_condition(
PrefixType::Mem => matches_condition(
&numerical_query.condition, &numerical_query.condition,
process.mem_percent_usage, process.mem_percent_usage,
numerical_query.value, numerical_query.value,
), ),
PrefixType::MemBytes => matches_condition(
&numerical_query.condition,
process.mem_usage_bytes as f64,
numerical_query.value,
),
PrefixType::Rps => matches_condition( PrefixType::Rps => matches_condition(
&numerical_query.condition, &numerical_query.condition,
process.rps_f64, process.rps_f64,

View File

@ -107,7 +107,7 @@ pub const PROCESS_HELP_TEXT: [&str; 12] = [
"% Toggle between values and percentages for memory usage", "% Toggle between values and percentages for memory usage",
]; ];
pub const SEARCH_HELP_TEXT: [&str; 43] = [ pub const SEARCH_HELP_TEXT: [&str; 44] = [
"4 - Process search widget\n", "4 - Process search widget\n",
"Tab Toggle between searching for PID and name\n", "Tab Toggle between searching for PID and name\n",
"Esc Close the search widget (retains the filter)\n", "Esc Close the search widget (retains the filter)\n",
@ -126,6 +126,7 @@ pub const SEARCH_HELP_TEXT: [&str; 43] = [
"pid ex: pid 825\n", "pid ex: pid 825\n",
"cpu ex: cpu > 4.2\n", "cpu ex: cpu > 4.2\n",
"mem ex: mem < 4.2\n", "mem ex: mem < 4.2\n",
"memb ex: memb < 100 kb\n",
"read ex: read >= 1 b\n", "read ex: read >= 1 b\n",
"write ex: write <= 1 tb\n", "write ex: write <= 1 tb\n",
"tread ex: tread = 1\n", "tread ex: tread = 1\n",

View File

@ -36,7 +36,7 @@ pub struct ConvertedProcessData {
pub name: String, pub name: String,
pub cpu_percent_usage: f64, pub cpu_percent_usage: f64,
pub mem_percent_usage: f64, pub mem_percent_usage: f64,
pub mem_usage_kb: u64, pub mem_usage_bytes: u64,
pub mem_usage_str: (f64, String), pub mem_usage_str: (f64, String),
pub group_pids: Vec<u32>, pub group_pids: Vec<u32>,
pub read_per_sec: String, pub read_per_sec: String,
@ -55,7 +55,7 @@ pub struct SingleProcessData {
pub pid: u32, pub pid: u32,
pub cpu_percent_usage: f64, pub cpu_percent_usage: f64,
pub mem_percent_usage: f64, pub mem_percent_usage: f64,
pub mem_usage_kb: u64, pub mem_usage_bytes: u64,
pub group_pids: Vec<u32>, pub group_pids: Vec<u32>,
pub read_per_sec: u64, pub read_per_sec: u64,
pub write_per_sec: u64, pub write_per_sec: u64,
@ -402,8 +402,8 @@ pub fn convert_process_data(
}, },
cpu_percent_usage: process.cpu_usage_percent, cpu_percent_usage: process.cpu_usage_percent,
mem_percent_usage: process.mem_usage_percent, mem_percent_usage: process.mem_usage_percent,
mem_usage_kb: process.mem_usage_kb, mem_usage_bytes: process.mem_usage_bytes,
mem_usage_str: get_exact_byte_values(process.mem_usage_kb * 1024, false), mem_usage_str: get_exact_byte_values(process.mem_usage_bytes, false),
group_pids: vec![process.pid], group_pids: vec![process.pid],
read_per_sec, read_per_sec,
write_per_sec, write_per_sec,
@ -434,7 +434,7 @@ pub fn convert_process_data(
(*entry).cpu_percent_usage += process.cpu_usage_percent; (*entry).cpu_percent_usage += process.cpu_usage_percent;
(*entry).mem_percent_usage += process.mem_usage_percent; (*entry).mem_percent_usage += process.mem_usage_percent;
(*entry).mem_usage_kb += process.mem_usage_kb; (*entry).mem_usage_bytes += process.mem_usage_bytes;
(*entry).group_pids.push(process.pid); (*entry).group_pids.push(process.pid);
(*entry).read_per_sec += process.read_bytes_per_sec; (*entry).read_per_sec += process.read_bytes_per_sec;
(*entry).write_per_sec += process.write_bytes_per_sec; (*entry).write_per_sec += process.write_bytes_per_sec;
@ -465,8 +465,8 @@ pub fn convert_process_data(
name: identifier.to_string(), name: identifier.to_string(),
cpu_percent_usage: p.cpu_percent_usage, cpu_percent_usage: p.cpu_percent_usage,
mem_percent_usage: p.mem_percent_usage, mem_percent_usage: p.mem_percent_usage,
mem_usage_kb: p.mem_usage_kb, mem_usage_bytes: p.mem_usage_bytes,
mem_usage_str: get_exact_byte_values(p.mem_usage_kb * 1024, false), mem_usage_str: get_exact_byte_values(p.mem_usage_bytes, false),
group_pids: p.group_pids, group_pids: p.group_pids,
read_per_sec, read_per_sec,
write_per_sec, write_per_sec,

View File

@ -524,8 +524,8 @@ pub fn sort_process_data(
ProcessSorting::Mem => { ProcessSorting::Mem => {
to_sort_vec.sort_by(|a, b| { to_sort_vec.sort_by(|a, b| {
utils::gen_util::get_ordering( utils::gen_util::get_ordering(
a.mem_usage_kb, a.mem_usage_bytes,
b.mem_usage_kb, b.mem_usage_bytes,
proc_widget_state.process_sorting_reverse, proc_widget_state.process_sorting_reverse,
) )
}); });