Merge branch 'feat/memory' into dev
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 106 KiB |
@@ -343,8 +343,7 @@ impl fmt::Display for ByteStats {
|
|||||||
let p = match as_f64 {
|
let p = match as_f64 {
|
||||||
x if x >= ONE_GB => format!("{y:.2} GB", y = as_f64 / ONE_GB),
|
x if x >= ONE_GB => format!("{y:.2} GB", y = as_f64 / ONE_GB),
|
||||||
x if x >= ONE_MB => format!("{y:.2} MB", y = as_f64 / ONE_MB),
|
x if x >= ONE_MB => format!("{y:.2} MB", y = as_f64 / ONE_MB),
|
||||||
x if x >= ONE_KB => format!("{y:.2} kB", y = as_f64 / ONE_KB),
|
_ => format!("{y:.2} kB", y = as_f64 / ONE_KB),
|
||||||
_ => format!("{} B", self.0),
|
|
||||||
};
|
};
|
||||||
write!(f, "{p:>x$}", x = f.width().unwrap_or(1))
|
write!(f, "{p:>x$}", x = f.width().unwrap_or(1))
|
||||||
}
|
}
|
||||||
@@ -463,15 +462,15 @@ impl ContainerItem {
|
|||||||
/// Container information panel headings + widths, for nice pretty formatting
|
/// Container information panel headings + widths, for nice pretty formatting
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Columns {
|
pub struct Columns {
|
||||||
pub state: (Header, usize),
|
pub state: (Header, u8),
|
||||||
pub status: (Header, usize),
|
pub status: (Header, u8),
|
||||||
pub cpu: (Header, usize),
|
pub cpu: (Header, u8),
|
||||||
pub mem: (Header, usize),
|
pub mem: (Header, u8, u8),
|
||||||
pub id: (Header, usize),
|
pub id: (Header, u8),
|
||||||
pub name: (Header, usize),
|
pub name: (Header, u8),
|
||||||
pub image: (Header, usize),
|
pub image: (Header, u8),
|
||||||
pub net_rx: (Header, usize),
|
pub net_rx: (Header, u8),
|
||||||
pub net_tx: (Header, usize),
|
pub net_tx: (Header, u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Columns {
|
impl Columns {
|
||||||
@@ -482,7 +481,7 @@ impl Columns {
|
|||||||
status: (Header::Status, 16),
|
status: (Header::Status, 16),
|
||||||
// 7 to allow for "100.00%"
|
// 7 to allow for "100.00%"
|
||||||
cpu: (Header::Cpu, 7),
|
cpu: (Header::Cpu, 7),
|
||||||
mem: (Header::Memory, 12),
|
mem: (Header::Memory, 6, 6),
|
||||||
id: (Header::Id, 8),
|
id: (Header::Id, 8),
|
||||||
name: (Header::Name, 4),
|
name: (Header::Name, 4),
|
||||||
image: (Header::Image, 5),
|
image: (Header::Image, 5),
|
||||||
|
|||||||
+8
-8
@@ -364,7 +364,7 @@ impl AppData {
|
|||||||
/// So can display nicely and evenly
|
/// So can display nicely and evenly
|
||||||
pub fn get_width(&self) -> Columns {
|
pub fn get_width(&self) -> Columns {
|
||||||
let mut output = Columns::new();
|
let mut output = Columns::new();
|
||||||
let count = |x: &String| x.chars().count();
|
let count = |x: &String| u8::try_from(x.chars().count()).unwrap_or(12);
|
||||||
|
|
||||||
// Should probably find a refactor here somewhere
|
// Should probably find a refactor here somewhere
|
||||||
for container in &self.containers.items {
|
for container in &self.containers.items {
|
||||||
@@ -375,11 +375,6 @@ impl AppData {
|
|||||||
.unwrap_or(&CpuStats::default())
|
.unwrap_or(&CpuStats::default())
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
let mem_count = count(&format!(
|
|
||||||
"{} / {}",
|
|
||||||
container.mem_stats.back().unwrap_or(&ByteStats::default()),
|
|
||||||
container.mem_limit
|
|
||||||
));
|
|
||||||
|
|
||||||
let rx_count = count(&container.rx.to_string());
|
let rx_count = count(&container.rx.to_string());
|
||||||
let tx_count = count(&container.tx.to_string());
|
let tx_count = count(&container.tx.to_string());
|
||||||
@@ -387,6 +382,8 @@ impl AppData {
|
|||||||
let name_count = count(&container.name);
|
let name_count = count(&container.name);
|
||||||
let state_count = count(&container.state.to_string());
|
let state_count = count(&container.state.to_string());
|
||||||
let status_count = count(&container.status);
|
let status_count = count(&container.status);
|
||||||
|
let mem_current_count = count(&container.mem_stats.back().unwrap_or(&ByteStats::default()).to_string());
|
||||||
|
let mem_limit_count= count(&container.mem_limit.to_string());
|
||||||
|
|
||||||
if cpu_count > output.cpu.1 {
|
if cpu_count > output.cpu.1 {
|
||||||
output.cpu.1 = cpu_count;
|
output.cpu.1 = cpu_count;
|
||||||
@@ -394,8 +391,11 @@ impl AppData {
|
|||||||
if image_count > output.image.1 {
|
if image_count > output.image.1 {
|
||||||
output.image.1 = image_count;
|
output.image.1 = image_count;
|
||||||
};
|
};
|
||||||
if mem_count > output.mem.1 {
|
if mem_current_count > output.mem.1 {
|
||||||
output.mem.1 = mem_count;
|
output.mem.1 = mem_current_count;
|
||||||
|
};
|
||||||
|
if mem_limit_count > output.mem.2 {
|
||||||
|
output.mem.2 = mem_limit_count;
|
||||||
};
|
};
|
||||||
if name_count > output.name.1 {
|
if name_count > output.name.1 {
|
||||||
output.name.1 = name_count;
|
output.name.1 = name_count;
|
||||||
|
|||||||
+10
-28
@@ -40,59 +40,41 @@ async fn main() {
|
|||||||
let app_data = Arc::new(Mutex::new(AppData::default(args)));
|
let app_data = Arc::new(Mutex::new(AppData::default(args)));
|
||||||
let gui_state = Arc::new(Mutex::new(GuiState::default()));
|
let gui_state = Arc::new(Mutex::new(GuiState::default()));
|
||||||
let is_running = Arc::new(AtomicBool::new(true));
|
let is_running = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
let docker_app_data = Arc::clone(&app_data);
|
|
||||||
let docker_gui_state = Arc::clone(&gui_state);
|
|
||||||
|
|
||||||
let (docker_sx, docker_rx) = tokio::sync::mpsc::channel(16);
|
let (docker_sx, docker_rx) = tokio::sync::mpsc::channel(16);
|
||||||
|
let (input_sx, input_rx) = tokio::sync::mpsc::channel(16);
|
||||||
|
|
||||||
// Create docker daemon handler, and only spawn up the docker data handler if ping returns non-error
|
// Create docker daemon handler, and only spawn up the docker data handler if ping returns non-error
|
||||||
if let Ok(docker) = Docker::connect_with_socket_defaults() {
|
if let Ok(docker) = Docker::connect_with_socket_defaults() {
|
||||||
if docker.ping().await.is_ok() {
|
if docker.ping().await.is_ok() {
|
||||||
let docker = Arc::new(docker);
|
let app_data = Arc::clone(&app_data);
|
||||||
|
let gui_state = Arc::clone(&gui_state);
|
||||||
let is_running = Arc::clone(&is_running);
|
let is_running = Arc::clone(&is_running);
|
||||||
tokio::spawn(DockerData::init(
|
tokio::spawn(DockerData::init(
|
||||||
docker_app_data,
|
app_data, docker, gui_state, docker_rx, is_running,
|
||||||
docker,
|
|
||||||
docker_gui_state,
|
|
||||||
docker_rx,
|
|
||||||
is_running,
|
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
app_data.lock().set_error(AppError::DockerConnect);
|
app_data.lock().set_error(AppError::DockerConnect);
|
||||||
docker_gui_state.lock().status_push(Status::DockerConnect);
|
gui_state.lock().status_push(Status::DockerConnect);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
app_data.lock().set_error(AppError::DockerConnect);
|
app_data.lock().set_error(AppError::DockerConnect);
|
||||||
docker_gui_state.lock().status_push(Status::DockerConnect);
|
gui_state.lock().status_push(Status::DockerConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
let input_app_data = Arc::clone(&app_data);
|
let input_app_data = Arc::clone(&app_data);
|
||||||
|
|
||||||
let (input_sx, input_rx) = tokio::sync::mpsc::channel(16);
|
|
||||||
|
|
||||||
let input_is_running = Arc::clone(&is_running);
|
|
||||||
let input_gui_state = Arc::clone(&gui_state);
|
let input_gui_state = Arc::clone(&gui_state);
|
||||||
let input_docker_sender = docker_sx.clone();
|
let input_is_running = Arc::clone(&is_running);
|
||||||
|
|
||||||
// Spawn input handling into own tokio thread
|
// Spawn input handling into own tokio thread
|
||||||
tokio::spawn(input_handler::InputHandler::init(
|
tokio::spawn(input_handler::InputHandler::init(
|
||||||
input_app_data,
|
input_app_data,
|
||||||
input_rx,
|
input_rx,
|
||||||
input_docker_sender,
|
docker_sx.clone(),
|
||||||
input_gui_state,
|
input_gui_state,
|
||||||
input_is_running,
|
input_is_running,
|
||||||
));
|
));
|
||||||
|
|
||||||
if args.gui {
|
if args.gui {
|
||||||
let update_duration = std::time::Duration::from_millis(u64::from(args.docker_interval));
|
create_ui(app_data, input_sx, is_running, gui_state, docker_sx)
|
||||||
create_ui(
|
|
||||||
app_data,
|
|
||||||
input_sx,
|
|
||||||
is_running,
|
|
||||||
gui_state,
|
|
||||||
docker_sx,
|
|
||||||
update_duration,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap_or(());
|
.unwrap_or(());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+16
-16
@@ -136,19 +136,19 @@ pub fn containers<B: Backend>(
|
|||||||
let state_style = Style::default().fg(i.state.get_color());
|
let state_style = Style::default().fg(i.state.get_color());
|
||||||
let blue = Style::default().fg(Color::Blue);
|
let blue = Style::default().fg(Color::Blue);
|
||||||
|
|
||||||
let mems = format!(
|
// let mems = format!(
|
||||||
"{:>1} / {:>1}",
|
// "{:>1} / {:>1}",
|
||||||
i.mem_stats.back().unwrap_or(&ByteStats::default()),
|
// i.mem_stats.back().unwrap_or(&ByteStats::default()),
|
||||||
i.mem_limit
|
// i.mem_limit
|
||||||
);
|
// );
|
||||||
|
|
||||||
let lines = Spans::from(vec![
|
let lines = Spans::from(vec![
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{:<width$}", i.state.to_string(), width = widths.state.1),
|
format!("{:<width$}", i.state.to_string(), width = widths.state.1.into()),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width$}", i.status, width = &widths.status.1),
|
format!("{MARGIN}{:>width$}", i.status, width = &widths.status.1.into()),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
@@ -156,12 +156,12 @@ pub fn containers<B: Backend>(
|
|||||||
"{}{:>width$}",
|
"{}{:>width$}",
|
||||||
MARGIN,
|
MARGIN,
|
||||||
i.cpu_stats.back().unwrap_or(&CpuStats::default()),
|
i.cpu_stats.back().unwrap_or(&CpuStats::default()),
|
||||||
width = &widths.cpu.1
|
width = &widths.cpu.1.into()
|
||||||
),
|
),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{mems:>width$}", width = &widths.mem.1),
|
format!("{MARGIN}{:>width_current$} / {:>width_limit$}", i.mem_stats.back().unwrap_or(&ByteStats::default()), i.mem_limit, width_current = &widths.mem.1.into(), width_limit = &widths.mem.2.into()),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
@@ -169,24 +169,24 @@ pub fn containers<B: Backend>(
|
|||||||
"{}{:>width$}",
|
"{}{:>width$}",
|
||||||
MARGIN,
|
MARGIN,
|
||||||
i.id.get().chars().take(8).collect::<String>(),
|
i.id.get().chars().take(8).collect::<String>(),
|
||||||
width = &widths.id.1
|
width = &widths.id.1.into()
|
||||||
),
|
),
|
||||||
blue,
|
blue,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width$}", i.name, width = widths.name.1),
|
format!("{MARGIN}{:>width$}", i.name, width = widths.name.1.into()),
|
||||||
blue,
|
blue,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width$}", i.image, width = widths.image.1),
|
format!("{MARGIN}{:>width$}", i.image, width = widths.image.1.into()),
|
||||||
blue,
|
blue,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width$}", i.rx, width = widths.net_rx.1),
|
format!("{MARGIN}{:>width$}", i.rx, width = widths.net_rx.1.into()),
|
||||||
Style::default().fg(Color::Rgb(255, 233, 193)),
|
Style::default().fg(Color::Rgb(255, 233, 193)),
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width$}", i.tx, width = widths.net_tx.1),
|
format!("{MARGIN}{:>width$}", i.tx, width = widths.net_tx.1.into()),
|
||||||
Style::default().fg(Color::Rgb(205, 140, 140)),
|
Style::default().fg(Color::Rgb(205, 140, 140)),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
@@ -415,7 +415,7 @@ pub fn heading_bar<B: Backend>(
|
|||||||
(Header::State, columns.state.1),
|
(Header::State, columns.state.1),
|
||||||
(Header::Status, columns.status.1),
|
(Header::Status, columns.status.1),
|
||||||
(Header::Cpu, columns.cpu.1),
|
(Header::Cpu, columns.cpu.1),
|
||||||
(Header::Memory, columns.mem.1),
|
(Header::Memory, columns.mem.1 + columns.mem.2 + 3),
|
||||||
(Header::Id, columns.id.1),
|
(Header::Id, columns.id.1),
|
||||||
(Header::Name, columns.name.1),
|
(Header::Name, columns.name.1),
|
||||||
(Header::Image, columns.image.1),
|
(Header::Image, columns.image.1),
|
||||||
@@ -426,7 +426,7 @@ pub fn heading_bar<B: Backend>(
|
|||||||
let header_data = header_meta
|
let header_data = header_meta
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let header_block = gen_header(&i.0, i.1);
|
let header_block = gen_header(&i.0, i.1.into());
|
||||||
(header_block.0, i.0, Constraint::Max(header_block.1))
|
(header_block.0, i.0, Constraint::Max(header_block.1))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|||||||
Reference in New Issue
Block a user