Phase 3: Add wildcard support for service pattern matching
Implement glob pattern matching for service filters: - nginx* matches nginx, nginx-config-reload, etc. - *backup matches any service ending with 'backup' - docker*prune matches docker-weekly-prune, etc. - Exact matches still work as before (backward compatible) Addresses TODO.md requirement for '*' filtering support.
This commit is contained in:
parent
dc11538ae9
commit
174b27f31a
@ -169,9 +169,9 @@ impl SystemdCollector {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this service matches our filter patterns
|
// Check if this service matches our filter patterns (supports wildcards)
|
||||||
for pattern in service_name_filters {
|
for pattern in service_name_filters {
|
||||||
if service_name == pattern {
|
if self.matches_pattern(service_name, pattern) {
|
||||||
debug!(
|
debug!(
|
||||||
"INCLUDING service '{}' because it matches pattern '{}'",
|
"INCLUDING service '{}' because it matches pattern '{}'",
|
||||||
service_name, pattern
|
service_name, pattern
|
||||||
@ -186,6 +186,62 @@ impl SystemdCollector {
|
|||||||
Ok(services)
|
Ok(services)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if service name matches pattern (supports wildcards like nginx*)
|
||||||
|
fn matches_pattern(&self, service_name: &str, pattern: &str) -> bool {
|
||||||
|
if pattern.contains('*') {
|
||||||
|
// Wildcard pattern matching
|
||||||
|
if pattern.ends_with('*') {
|
||||||
|
// Pattern like "nginx*" - match if service starts with "nginx"
|
||||||
|
let prefix = &pattern[..pattern.len() - 1];
|
||||||
|
service_name.starts_with(prefix)
|
||||||
|
} else if pattern.starts_with('*') {
|
||||||
|
// Pattern like "*backup" - match if service ends with "backup"
|
||||||
|
let suffix = &pattern[1..];
|
||||||
|
service_name.ends_with(suffix)
|
||||||
|
} else {
|
||||||
|
// Pattern like "nginx*backup" - simple glob matching
|
||||||
|
self.simple_glob_match(service_name, pattern)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Exact match (existing behavior)
|
||||||
|
service_name == pattern
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simple glob pattern matching for patterns with * in middle
|
||||||
|
fn simple_glob_match(&self, text: &str, pattern: &str) -> bool {
|
||||||
|
let parts: Vec<&str> = pattern.split('*').collect();
|
||||||
|
if parts.is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut pos = 0;
|
||||||
|
for (i, part) in parts.iter().enumerate() {
|
||||||
|
if part.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == 0 {
|
||||||
|
// First part must match at start
|
||||||
|
if !text[pos..].starts_with(part) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pos += part.len();
|
||||||
|
} else if i == parts.len() - 1 {
|
||||||
|
// Last part must match at end
|
||||||
|
return text[pos..].ends_with(part);
|
||||||
|
} else {
|
||||||
|
// Middle part must be found somewhere
|
||||||
|
if let Some(found_pos) = text[pos..].find(part) {
|
||||||
|
pos += found_pos + part.len();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
/// Get service status using systemctl
|
/// Get service status using systemctl
|
||||||
fn get_service_status(&self, service: &str) -> Result<(String, String)> {
|
fn get_service_status(&self, service: &str) -> Result<(String, String)> {
|
||||||
let output = Command::new("systemctl")
|
let output = Command::new("systemctl")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user