use tracing::{error, info, warn}; use super::Sink; use crate::event::{Event, RoundReport, describe}; /// Writes every round to the log (journald under systemd). pub struct LogSink; impl Sink for LogSink { async fn handle(&mut self, r: &RoundReport) { let g = &r.group; let kind = r.record_type; let tag = if r.dry_run { " (dry run)" } else { "" }; if !r.ips.is_empty() { let summary: Vec = r .ips .iter() .map(|s| format!("{}={}/{}", s.ip, if s.up { "UP" } else { "DOWN" }, describe(&s.probe))) .collect(); info!("{g}: {}", summary.join(" ")); } for event in &r.events { match event { Event::Started { missing } => { info!("{g}: started"); for m in missing { warn!("{g}: member {m} has no {kind} record"); } } Event::MemberChanged { member, old, new } => info!("{g}: {member} changed {old:?} -> {new:?}"), Event::HealthChanged { ip, members, up: true, probe } => { info!("{g}: {ip} ({}) is UP [{}]", members.join(", "), describe(probe)) } Event::HealthChanged { ip, members, up: false, probe } => { warn!("{g}: {ip} ({}) is DOWN [{}]", members.join(", "), describe(probe)) } Event::DnsUpdated { added, removed } => { for ip in added { info!("{g}: + {kind} {ip}{tag}"); } for ip in removed { info!("{g}: - {kind} {ip}{tag}"); } } Event::NoHealthyMembers => error!("{g}: no member is healthy, leaving DNS unchanged"), // The error itself is logged below, on every failing round. Event::CheckFailed { .. } => {} Event::CheckRecovered => info!("{g}: check recovered"), } } if let Some(err) = &r.error { error!("{g}: {err}"); } } }