diff --git a/src/interpreter/query_process.rs b/src/interpreter/query_process.rs index fe838b4..d160f52 100644 --- a/src/interpreter/query_process.rs +++ b/src/interpreter/query_process.rs @@ -98,6 +98,39 @@ impl QueryProcess { return (ms as f64) / 1e6 / self.elapsed * 100.; } + pub fn cpu_wait(&self) -> f64 { + if !self.running { + let ms = *self + .profile_events + .get("OSCPUWaitMicroseconds") + .unwrap_or(&0); + return (ms as f64) / 1e6 * 100.; + } + + if let Some(prev_profile_events) = &self.prev_profile_events { + let ms_prev = *prev_profile_events + .get("OSCPUWaitMicroseconds") + .unwrap_or(&0); + let ms_now = *self + .profile_events + .get("OSCPUWaitMicroseconds") + .unwrap_or(&0); + let elapsed = self.elapsed - self.prev_elapsed.unwrap(); + if elapsed > 0. { + // It is possible to overflow, at least because metrics for initial queries is + // summarized, and when query on some node will be finished (non initial), then initial + // query will have less data. + return ms_now.saturating_sub(ms_prev) as f64 / 1e6 / elapsed * 100.; + } + } + + let ms = *self + .profile_events + .get("OSCPUWaitMicroseconds") + .unwrap_or(&0); + return (ms as f64) / 1e6 / self.elapsed * 100.; + } + pub fn net_io(&self) -> f64 { let network_events = [ "NetworkSendBytes", diff --git a/src/view/processes_view.rs b/src/view/processes_view.rs index 8107d30..f121a6f 100644 --- a/src/view/processes_view.rs +++ b/src/view/processes_view.rs @@ -25,6 +25,7 @@ pub enum QueryProcessesColumn { SubQueries, Cpu, IOWait, + CPUWait, User, Threads, Memory, @@ -57,6 +58,7 @@ impl TableViewItem for QueryProcess { } QueryProcessesColumn::Cpu => format!("{:.1} %", self.cpu()), QueryProcessesColumn::IOWait => format!("{:.1} %", self.io_wait()), + QueryProcessesColumn::CPUWait => format!("{:.1} %", self.cpu_wait()), QueryProcessesColumn::User => self.user.clone(), QueryProcessesColumn::Threads => self.threads.to_string(), QueryProcessesColumn::Memory => formatter.format(self.memory), @@ -83,6 +85,7 @@ impl TableViewItem for QueryProcess { QueryProcessesColumn::SubQueries => self.subqueries.cmp(&other.subqueries), QueryProcessesColumn::Cpu => self.cpu().total_cmp(&other.cpu()), QueryProcessesColumn::IOWait => self.io_wait().total_cmp(&other.io_wait()), + QueryProcessesColumn::CPUWait => self.cpu_wait().total_cmp(&other.cpu_wait()), QueryProcessesColumn::User => self.user.cmp(&other.user), QueryProcessesColumn::Threads => self.threads.cmp(&other.threads), QueryProcessesColumn::Memory => self.memory.cmp(&other.memory), @@ -266,6 +269,7 @@ impl ProcessesView { inner_table.add_column(QueryProcessesColumn::QueryId, "query_id", |c| c.width(12)); inner_table.add_column(QueryProcessesColumn::Cpu, "cpu", |c| c.width(8)); inner_table.add_column(QueryProcessesColumn::IOWait, "io_wait", |c| c.width(11)); + inner_table.add_column(QueryProcessesColumn::CPUWait, "cpu_wait", |c| c.width(12)); inner_table.add_column(QueryProcessesColumn::User, "user", |c| c.width(8)); inner_table.add_column(QueryProcessesColumn::Threads, "thr", |c| c.width(6)); inner_table.add_column(QueryProcessesColumn::Memory, "mem", |c| c.width(6));