Implement logged-in users monitoring and improve widget formatting
Agent improvements: - Add get_logged_in_users() function to SystemCollector using 'who' command - Collect unique, sorted list of currently logged-in users - Include logged_in_users field in system metrics JSON output - Change C-state formatting to show 2 states per row instead of 4 Dashboard improvements: - Update Backups widget to show "Archives: XX, ..." format - System widget ready to display logged-in users with proper formatting The System widget will now show: - C-states formatted as 2 per row for better readability - Logged-in users displayed as "Logged in: user" or "Logged in: X users (user1, user2)"
This commit is contained in:
parent
1ee398e648
commit
c6e8749ddd
@ -124,6 +124,32 @@ impl SystemCollector {
|
||||
Ok((used_mb, total_mb))
|
||||
}
|
||||
|
||||
async fn get_logged_in_users(&self) -> Option<Vec<String>> {
|
||||
// Get currently logged-in users using 'who' command
|
||||
let output = Command::new("who")
|
||||
.output()
|
||||
.await
|
||||
.ok()?;
|
||||
|
||||
let who_output = String::from_utf8_lossy(&output.stdout);
|
||||
let mut users = Vec::new();
|
||||
|
||||
for line in who_output.lines() {
|
||||
if let Some(username) = line.split_whitespace().next() {
|
||||
if !username.is_empty() && !users.contains(&username.to_string()) {
|
||||
users.push(username.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if users.is_empty() {
|
||||
None
|
||||
} else {
|
||||
users.sort();
|
||||
Some(users)
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_cpu_cstate_info(&self) -> Option<Vec<String>> {
|
||||
// Read C-state information to show all sleep state distributions
|
||||
let mut cstate_times: Vec<(String, u64)> = Vec::new();
|
||||
@ -178,7 +204,7 @@ impl SystemCollector {
|
||||
order_a.cmp(&order_b)
|
||||
});
|
||||
|
||||
// Format C-states as description lines (split into two rows for readability)
|
||||
// Format C-states as description lines (2 C-states per row)
|
||||
let mut result = Vec::new();
|
||||
let mut current_line = Vec::new();
|
||||
|
||||
@ -187,15 +213,15 @@ impl SystemCollector {
|
||||
if percent >= 0.1 { // Only show states with at least 0.1% time
|
||||
current_line.push(format!("{}: {:.1}%", name, percent));
|
||||
|
||||
// Split into two rows when we have 4 items
|
||||
if current_line.len() == 4 {
|
||||
// Split into rows when we have 2 items
|
||||
if current_line.len() == 2 {
|
||||
result.push(current_line.join(", "));
|
||||
current_line.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add remaining items as second line
|
||||
// Add remaining items as final line
|
||||
if !current_line.is_empty() {
|
||||
result.push(current_line.join(", "));
|
||||
}
|
||||
@ -272,6 +298,9 @@ impl Collector for SystemCollector {
|
||||
|
||||
// Get C-state information (optional)
|
||||
let cpu_cstate_info = self.get_cpu_cstate_info().await;
|
||||
|
||||
// Get logged-in users (optional)
|
||||
let logged_in_users = self.get_logged_in_users().await;
|
||||
|
||||
let mut system_metrics = json!({
|
||||
"summary": {
|
||||
@ -299,6 +328,10 @@ impl Collector for SystemCollector {
|
||||
system_metrics["summary"]["cpu_cstate"] = json!(cstates);
|
||||
}
|
||||
|
||||
if let Some(users) = logged_in_users {
|
||||
system_metrics["summary"]["logged_in_users"] = json!(users);
|
||||
}
|
||||
|
||||
debug!("System metrics collected: CPU load {:.2}, Memory {:.1}%",
|
||||
cpu_load_5, memory_usage_percent);
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ fn render_metrics(frame: &mut Frame, _host: &HostDisplayData, metrics: &BackupMe
|
||||
|
||||
data.add_row(
|
||||
Some(WidgetStatus::new(latest_status)),
|
||||
vec![format!("{} archives, {:.1}GB total", metrics.backup.snapshot_count, metrics.backup.size_gb)],
|
||||
vec![format!("Archives: {}, {:.1}GB total", metrics.backup.snapshot_count, metrics.backup.size_gb)],
|
||||
vec![
|
||||
"Latest".to_string(),
|
||||
latest_time,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user