mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-26 23:24:20 +02:00
feature: Support memb (mem bytes) searching in processes
Supports searching by the new mem value.
This commit is contained in:
parent
ff15649be7
commit
c82f4d40b4
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -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",
|
||||||
|
17
README.md
17
README.md
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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") {
|
||||||
|
@ -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,
|
||||||
|
@ -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",
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user