feat(agent): boucle principale avec timers 2s/10s/60s

This commit is contained in:
Gilles Soulier
2026-05-22 11:42:00 +02:00
parent a85e5cbee2
commit 960fd02fd7
+127 -3
View File
@@ -1,9 +1,133 @@
use nanometrics_agent::config;
use nanometrics_agent::{config, metrics, payload, transport};
use sysinfo::{Components, Disks, Networks, System};
use std::time::{Duration, Instant};
use std::sync::mpsc;
fn get_local_ip() -> String {
use std::net::UdpSocket;
if let Ok(s) = UdpSocket::bind("0.0.0.0:0") {
if s.connect("8.8.8.8:80").is_ok() {
if let Ok(addr) = s.local_addr() {
return addr.ip().to_string();
}
}
}
"0.0.0.0".to_string()
}
fn apply_config_update(cfg: &mut config::Config, data: &[u8]) {
if let Ok(new_cfg) = serde_json::from_slice::<config::Config>(data) {
cfg.metrics = new_cfg.metrics;
eprintln!("[config] mis à jour depuis le serveur");
}
}
fn main() {
let cfg_path = std::env::args()
.nth(1)
.unwrap_or_else(|| "config.toml".to_string());
let _cfg = config::load(std::path::Path::new(&cfg_path));
println!("nanometrics-agent starting");
let mut cfg = config::load(std::path::Path::new(&cfg_path))
.expect("Impossible de charger config.toml");
let hostname = System::host_name().unwrap_or_else(|| "unknown".to_string());
let ip = get_local_ip();
let mut sys = System::new();
let mut networks = Networks::new_with_refreshed_list();
let mut disks = Disks::new_with_refreshed_list();
let mut components = Components::new_with_refreshed_list();
let udp_sender = if cfg.protocols.udp.enabled {
Some(transport::udp::UdpSender::new(&cfg.server.ip, cfg.server.port))
} else {
None
};
let (incoming_tx, incoming_rx) = mpsc::channel::<transport::mqtt::MqttIncoming>();
let mqtt_client = if cfg.protocols.mqtt.enabled {
Some(transport::mqtt::start(&hostname, &cfg.protocols.mqtt, incoming_tx))
} else {
None
};
let mut last_slow = Instant::now();
let mut last_medium = Instant::now();
let mut first_medium = true;
let mut first_slow = true;
loop {
let now = Instant::now();
while let Ok(transport::mqtt::MqttIncoming::ConfigUpdate(data)) = incoming_rx.try_recv() {
apply_config_update(&mut cfg, &data);
}
sys.refresh_cpu_usage();
sys.refresh_memory();
let mut m = payload::AgentMetrics {
hostname: hostname.clone(),
ip: ip.clone(),
status: "online".to_string(),
cpu_percent: Some(metrics::cpu::get(&sys)),
..Default::default()
};
let (mem_used, mem_free, mem_total) = metrics::memory::get(&sys);
m.memory_used = Some(mem_used);
m.memory_free = Some(mem_free);
m.memory_total = Some(mem_total);
if first_medium || now.duration_since(last_medium).as_secs() >= 10 {
networks.refresh();
components.refresh();
let (rx, tx) = metrics::network::get(&networks);
if cfg.metrics.network.udp || cfg.metrics.network.mqtt {
m.network_rx = Some(rx);
m.network_tx = Some(tx);
}
if cfg.metrics.uptime.udp || cfg.metrics.uptime.mqtt {
m.uptime = Some(metrics::uptime::get());
}
if cfg.metrics.temperature.udp || cfg.metrics.temperature.mqtt {
m.temperature = metrics::temperature::get(&components);
}
last_medium = now;
first_medium = false;
}
if first_slow || now.duration_since(last_slow).as_secs() >= 60 {
disks.refresh();
if cfg.metrics.disk.udp || cfg.metrics.disk.mqtt {
let (used, free, total) = metrics::disk::get(&disks);
m.hdd_used = Some(used);
m.hdd_free = Some(free);
m.hdd_total = Some(total);
}
if cfg.metrics.smart.udp || cfg.metrics.smart.mqtt {
m.smart = metrics::smart::collect();
}
last_slow = now;
first_slow = false;
}
let json = serde_json::to_string(&m).expect("sérialisation JSON impossible");
if let Some(ref udp) = udp_sender {
udp.send(&json);
}
if let Some(ref client) = mqtt_client {
if cfg.protocols.mqtt.enabled {
transport::mqtt::publish_metrics(
client,
&cfg.protocols.mqtt.topic_base,
&hostname,
&json,
);
}
}
std::thread::sleep(Duration::from_secs(2));
}
}