#![cfg_attr(not(feature = "metrics"), no_std)]
#[cfg(feature = "tracing")]
pub use tracing::{debug, debug_span, error, info, info_span, trace, trace_span, warn};
#[doc(hidden)]
#[cfg(not(feature = "tracing"))]
#[macro_export]
macro_rules! __hick_trace_noop {
(target: $tgt:expr, $($rest:tt)*) => {
{ if false { let _ = &$tgt; } $crate::__hick_trace_noop!($($rest)*) }
};
($key:ident = %$val:expr, $($rest:tt)*) => {
{ if false { let _ = &$val; } $crate::__hick_trace_noop!($($rest)*) }
};
($key:ident = %$val:expr) => {
{ if false { let _ = &$val; } }
};
($key:ident = ?$val:expr, $($rest:tt)*) => {
{ if false { let _ = &$val; } $crate::__hick_trace_noop!($($rest)*) }
};
($key:ident = ?$val:expr) => {
{ if false { let _ = &$val; } }
};
($key:ident = $val:expr, $($rest:tt)*) => {
{ if false { let _ = &$val; } $crate::__hick_trace_noop!($($rest)*) }
};
($key:ident = $val:expr) => {
{ if false { let _ = &$val; } }
};
($key:ident, $($rest:tt)*) => {
{ if false { let _ = &$key; } $crate::__hick_trace_noop!($($rest)*) }
};
($key:ident) => {
{ if false { let _ = &$key; } }
};
(%$val:expr, $($rest:tt)*) => {
{ if false { let _ = &$val; } $crate::__hick_trace_noop!($($rest)*) }
};
(%$val:expr) => {
{ if false { let _ = &$val; } }
};
(?$val:expr, $($rest:tt)*) => {
{ if false { let _ = &$val; } $crate::__hick_trace_noop!($($rest)*) }
};
(?$val:expr) => {
{ if false { let _ = &$val; } }
};
($fmt:literal $(, $arg:expr)* $(,)?) => {
{ if false { let _ = ::core::format_args!($fmt $(, $arg)*); } }
};
() => {{}};
}
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop as trace;
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop as debug;
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop as info;
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop as warn;
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop as error;
#[cfg(not(feature = "tracing"))]
#[derive(Debug)]
pub struct NoopSpan;
#[cfg(not(feature = "tracing"))]
impl NoopSpan {
#[inline]
pub fn entered(self) -> Self {
self
}
#[inline]
pub fn enter(&self) -> Self {
NoopSpan
}
}
#[doc(hidden)]
#[cfg(not(feature = "tracing"))]
#[macro_export]
macro_rules! __hick_trace_noop_span {
(target: $tgt:expr, $($rest:tt)*) => {
{ if false { let _ = &$tgt; } $crate::__hick_trace_noop_span!($($rest)*) }
};
($name:literal, $($fields:tt)*) => {
{ $crate::__hick_trace_noop!($($fields)*); $crate::NoopSpan }
};
($name:literal) => {
$crate::NoopSpan
};
($($tt:tt)*) => {
{ $crate::__hick_trace_noop!($($tt)*); $crate::NoopSpan }
};
}
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop_span as trace_span;
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop_span as debug_span;
#[cfg(not(feature = "tracing"))]
pub use __hick_trace_noop_span as info_span;
#[cfg(feature = "stats")]
pub mod stats {
#[cfg(target_has_atomic = "64")]
use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
#[cfg(not(target_has_atomic = "64"))]
use portable_atomic::{AtomicU64, Ordering::Relaxed};
macro_rules! declare_counters {
($($field:ident => $metric:literal),* $(,)?) => {
$(
#[inline]
pub fn $field(&self, by: u64) {
self.$field.fetch_add(by, Relaxed);
#[cfg(feature = "metrics")]
::metrics::counter!($metric).increment(by);
}
)*
};
}
macro_rules! declare_gauges {
($(
$field:ident => $metric:literal :
incr = $incr:ident,
decr = $decr:ident,
set = $set:ident
),* $(,)?) => {
$(
#[inline]
pub fn $incr(&self, by: u64) {
self.$field.fetch_add(by, Relaxed);
#[cfg(feature = "metrics")]
::metrics::gauge!($metric).increment(by as f64);
}
#[inline]
pub fn $decr(&self, by: u64) {
self.$field.fetch_sub(by, Relaxed);
#[cfg(feature = "metrics")]
::metrics::gauge!($metric).decrement(by as f64);
}
#[inline]
pub fn $set(&self, v: u64) {
self.$field.store(v, Relaxed);
#[cfg(feature = "metrics")]
::metrics::gauge!($metric).set(v as f64);
}
)*
};
}
#[derive(Default, Debug)]
pub struct Stats {
packets_rx: AtomicU64,
packets_tx: AtomicU64,
bytes_rx: AtomicU64,
bytes_tx: AtomicU64,
packets_dropped: AtomicU64,
parse_errors: AtomicU64,
send_errors: AtomicU64,
questions_rx: AtomicU64,
answers_rx: AtomicU64,
answers_collected: AtomicU64,
answers_suppressed_kas: AtomicU64,
duplicate_questions_suppressed: AtomicU64,
responses_tx: AtomicU64,
probes_tx: AtomicU64,
announcements_tx: AtomicU64,
goodbyes_tx: AtomicU64,
conflicts: AtomicU64,
renames: AtomicU64,
cache_inserts: AtomicU64,
cache_refreshes: AtomicU64,
cache_evictions: AtomicU64,
cache_expirations: AtomicU64,
queries_started: AtomicU64,
queries_done: AtomicU64,
queries_timeout: AtomicU64,
services_registered: AtomicU64,
services_established: AtomicU64,
cache_size: AtomicU64,
queries_active: AtomicU64,
services_active: AtomicU64,
}
impl Stats {
declare_counters! {
packets_rx => "mdns_packets_rx",
packets_tx => "mdns_packets_tx",
bytes_rx => "mdns_bytes_rx",
bytes_tx => "mdns_bytes_tx",
packets_dropped => "mdns_packets_dropped",
parse_errors => "mdns_parse_errors",
send_errors => "mdns_send_errors",
questions_rx => "mdns_questions_rx",
answers_rx => "mdns_answers_rx",
answers_collected => "mdns_answers_collected",
answers_suppressed_kas => "mdns_answers_suppressed_kas",
duplicate_questions_suppressed => "mdns_duplicate_questions_suppressed",
responses_tx => "mdns_responses_tx",
probes_tx => "mdns_probes_tx",
announcements_tx => "mdns_announcements_tx",
goodbyes_tx => "mdns_goodbyes_tx",
conflicts => "mdns_conflicts",
renames => "mdns_renames",
cache_inserts => "mdns_cache_inserts",
cache_refreshes => "mdns_cache_refreshes",
cache_evictions => "mdns_cache_evictions",
cache_expirations => "mdns_cache_expirations",
queries_started => "mdns_queries_started",
queries_done => "mdns_queries_done",
queries_timeout => "mdns_queries_timeout",
services_registered => "mdns_services_registered",
services_established => "mdns_services_established",
}
declare_gauges! {
cache_size => "mdns_cache_size" :
incr = incr_cache_size,
decr = decr_cache_size,
set = set_cache_size,
queries_active => "mdns_queries_active" :
incr = incr_queries_active,
decr = decr_queries_active,
set = set_queries_active,
services_active => "mdns_services_active" :
incr = incr_services_active,
decr = decr_services_active,
set = set_services_active,
}
pub fn snapshot(&self) -> StatsSnapshot {
StatsSnapshot {
packets_rx: self.packets_rx.load(Relaxed),
packets_tx: self.packets_tx.load(Relaxed),
bytes_rx: self.bytes_rx.load(Relaxed),
bytes_tx: self.bytes_tx.load(Relaxed),
packets_dropped: self.packets_dropped.load(Relaxed),
parse_errors: self.parse_errors.load(Relaxed),
send_errors: self.send_errors.load(Relaxed),
questions_rx: self.questions_rx.load(Relaxed),
answers_rx: self.answers_rx.load(Relaxed),
answers_collected: self.answers_collected.load(Relaxed),
answers_suppressed_kas: self.answers_suppressed_kas.load(Relaxed),
duplicate_questions_suppressed: self.duplicate_questions_suppressed.load(Relaxed),
responses_tx: self.responses_tx.load(Relaxed),
probes_tx: self.probes_tx.load(Relaxed),
announcements_tx: self.announcements_tx.load(Relaxed),
goodbyes_tx: self.goodbyes_tx.load(Relaxed),
conflicts: self.conflicts.load(Relaxed),
renames: self.renames.load(Relaxed),
cache_inserts: self.cache_inserts.load(Relaxed),
cache_refreshes: self.cache_refreshes.load(Relaxed),
cache_evictions: self.cache_evictions.load(Relaxed),
cache_expirations: self.cache_expirations.load(Relaxed),
queries_started: self.queries_started.load(Relaxed),
queries_done: self.queries_done.load(Relaxed),
queries_timeout: self.queries_timeout.load(Relaxed),
services_registered: self.services_registered.load(Relaxed),
services_established: self.services_established.load(Relaxed),
cache_size: self.cache_size.load(Relaxed),
queries_active: self.queries_active.load(Relaxed),
services_active: self.services_active.load(Relaxed),
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct StatsSnapshot {
pub packets_rx: u64,
pub packets_tx: u64,
pub bytes_rx: u64,
pub bytes_tx: u64,
pub packets_dropped: u64,
pub parse_errors: u64,
pub send_errors: u64,
pub questions_rx: u64,
pub answers_rx: u64,
pub answers_collected: u64,
pub answers_suppressed_kas: u64,
pub duplicate_questions_suppressed: u64,
pub responses_tx: u64,
pub probes_tx: u64,
pub announcements_tx: u64,
pub goodbyes_tx: u64,
pub conflicts: u64,
pub renames: u64,
pub cache_inserts: u64,
pub cache_refreshes: u64,
pub cache_evictions: u64,
pub cache_expirations: u64,
pub queries_started: u64,
pub queries_done: u64,
pub queries_timeout: u64,
pub services_registered: u64,
pub services_established: u64,
pub cache_size: u64,
pub queries_active: u64,
pub services_active: u64,
}
}
#[cfg(test)]
mod tests;