Add user service discovery to systemd collector
- Use systemctl --user commands to discover user-level services - Include both user unit files and loaded user units - Gracefully handle cases where user commands fail (no user session) - Treat user services same as system services in filtering - Enables monitoring of user-level Docker, development servers, etc.
This commit is contained in:
parent
1cc31ec26a
commit
1e8da8c187
@ -128,12 +128,45 @@ impl SystemdCollector {
|
|||||||
.arg("--plain")
|
.arg("--plain")
|
||||||
.output()?;
|
.output()?;
|
||||||
|
|
||||||
|
// Also get user unit files (user-level services)
|
||||||
|
let user_unit_files_output = Command::new("systemctl")
|
||||||
|
.arg("--user")
|
||||||
|
.arg("list-unit-files")
|
||||||
|
.arg("--type=service")
|
||||||
|
.arg("--no-pager")
|
||||||
|
.arg("--plain")
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
// And user loaded units
|
||||||
|
let user_units_output = Command::new("systemctl")
|
||||||
|
.arg("--user")
|
||||||
|
.arg("list-units")
|
||||||
|
.arg("--type=service")
|
||||||
|
.arg("--all")
|
||||||
|
.arg("--no-pager")
|
||||||
|
.arg("--plain")
|
||||||
|
.output()?;
|
||||||
|
|
||||||
if !unit_files_output.status.success() || !units_output.status.success() {
|
if !unit_files_output.status.success() || !units_output.status.success() {
|
||||||
return Err(anyhow::anyhow!("systemctl command failed"));
|
return Err(anyhow::anyhow!("systemctl system command failed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User commands might fail if no user session, so check individually
|
||||||
|
let user_unit_files_success = user_unit_files_output.status.success();
|
||||||
|
let user_units_success = user_units_output.status.success();
|
||||||
|
|
||||||
let unit_files_str = String::from_utf8(unit_files_output.stdout)?;
|
let unit_files_str = String::from_utf8(unit_files_output.stdout)?;
|
||||||
let units_str = String::from_utf8(units_output.stdout)?;
|
let units_str = String::from_utf8(units_output.stdout)?;
|
||||||
|
let user_unit_files_str = if user_unit_files_success {
|
||||||
|
String::from_utf8(user_unit_files_output.stdout).ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let user_units_str = if user_units_success {
|
||||||
|
String::from_utf8(user_units_output.stdout).ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let mut services = Vec::new();
|
let mut services = Vec::new();
|
||||||
|
|
||||||
// Skip setup/certificate services that don't need monitoring (from legacy)
|
// Skip setup/certificate services that don't need monitoring (from legacy)
|
||||||
@ -220,6 +253,28 @@ impl SystemdCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse user unit files if available
|
||||||
|
if let Some(user_unit_files_str) = &user_unit_files_str {
|
||||||
|
for line in user_unit_files_str.lines() {
|
||||||
|
let fields: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
if fields.len() >= 2 && fields[0].ends_with(".service") {
|
||||||
|
let service_name = fields[0].trim_end_matches(".service");
|
||||||
|
all_service_names.insert(service_name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse user loaded units if available
|
||||||
|
if let Some(user_units_str) = &user_units_str {
|
||||||
|
for line in user_units_str.lines() {
|
||||||
|
let fields: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
if fields.len() >= 4 && fields[0].ends_with(".service") {
|
||||||
|
let service_name = fields[0].trim_end_matches(".service");
|
||||||
|
all_service_names.insert(service_name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now process all discovered services
|
// Now process all discovered services
|
||||||
for service_name in &all_service_names {
|
for service_name in &all_service_names {
|
||||||
debug!("Processing service: '{}'", service_name);
|
debug!("Processing service: '{}'", service_name);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user