use anyhow::Result; use gethostname::gethostname; use std::io; use std::io::Write; use local_ip_address::local_ip; use dns_lookup::lookup_addr; use crate::meta_plugin::MetaPlugin; #[derive(Debug, Clone, Default)] pub struct HostnameMetaPlugin { meta_name: String, } impl HostnameMetaPlugin { pub fn new() -> HostnameMetaPlugin { HostnameMetaPlugin { meta_name: "hostname".to_string(), } } } impl MetaPlugin for HostnameMetaPlugin { fn create(&self) -> Result> { // For meta plugins, we don't actually create a writer since we're buffering data internally Ok(Box::new(DummyWriter)) } fn finalize(&mut self) -> io::Result { match gethostname().into_string() { Ok(hostname) => Ok(hostname), Err(_) => Ok("unknown".to_string()), } } fn update(&mut self, _data: &[u8]) { // No update needed for hostname } fn meta_name(&mut self) -> String { self.meta_name.clone() } } #[derive(Debug, Clone, Default)] pub struct FullHostnameMetaPlugin { meta_name: String, } impl FullHostnameMetaPlugin { pub fn new() -> FullHostnameMetaPlugin { FullHostnameMetaPlugin { meta_name: "full_hostname".to_string(), } } } impl MetaPlugin for FullHostnameMetaPlugin { fn create(&self) -> Result> { // For meta plugins, we don't actually create a writer since we're buffering data internally Ok(Box::new(DummyWriter)) } fn finalize(&mut self) -> io::Result { // Try to get the FQDN through reverse DNS lookup match local_ip() { Ok(my_local_ip) => { match lookup_addr(&my_local_ip) { Ok(hostname) => Ok(hostname), Err(_) => { // Fall back to regular hostname if reverse DNS fails match gethostname().into_string() { Ok(hostname) => Ok(hostname), Err(_) => Ok("unknown".to_string()), } } } } Err(_) => { // Fall back to regular hostname if we can't get local IP match gethostname().into_string() { Ok(hostname) => Ok(hostname), Err(_) => Ok("unknown".to_string()), } } } } fn update(&mut self, _data: &[u8]) { // No update needed for full hostname } fn meta_name(&mut self) -> String { self.meta_name.clone() } } // Dummy writer that implements Write but doesn't do anything // This is needed to satisfy the MetaPlugin trait requirements struct DummyWriter; impl Write for DummyWriter { fn write(&mut self, buf: &[u8]) -> io::Result { Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } }