diff --git a/src/log_throttle.rs b/src/log_throttle.rs index 02bb7f208..b8043ff93 100644 --- a/src/log_throttle.rs +++ b/src/log_throttle.rs @@ -9,6 +9,10 @@ use std::time::{Duration, Instant}; /// hide real faults, so keep one line per interval and carry the count of everything /// suppressed since the last one. /// +/// Prefer the [`throttled_log!`](crate::throttled_log) macro, which declares the static for +/// you. Reach for this type directly only when the count belongs somewhere other than the end +/// of the line, or when the decision drives more than a log call. +/// /// Declare one per site (they do not share counts): /// /// ```ignore @@ -67,6 +71,33 @@ impl LogThrottle { } } +/// Log at most one line per interval from this call site, suffixed with the number of +/// occurrences it stands for. +/// +/// Each expansion declares its own hidden static, so two sites never share a count and +/// adding one is a single line: +/// +/// ```ignore +/// throttled_log!(Duration::from_secs(5), warn, "rejected ipc peer {peer_pid:?}"); +/// ``` +/// +/// An isolated event logs unchanged; a burst collapses to `... (x47)`. The count includes +/// the occurrence being reported, so it reads as a total rather than as "and N more". +#[macro_export] +macro_rules! throttled_log { + ($interval:expr, $level:ident, $($arg:tt)+) => {{ + static THROTTLE: $crate::log_throttle::LogThrottle = + $crate::log_throttle::LogThrottle::new($interval); + if let Some(n) = THROTTLE.due() { + if n > 1 { + $crate::log::$level!("{} (x{})", format_args!($($arg)+), n); + } else { + $crate::log::$level!("{}", format_args!($($arg)+)); + } + } + }}; +} + #[cfg(test)] mod tests { use super::*; @@ -83,7 +114,11 @@ mod tests { // The send side succeeding must not hand the recv side a fresh emit slot. assert_eq!(recv.due(), None); } - assert_eq!(send.due(), Some(1), "the other direction keeps its own slot"); + assert_eq!( + send.due(), + Some(1), + "the other direction keeps its own slot" + ); } #[test] diff --git a/src/webrtc.rs b/src/webrtc.rs index 9ecd98da0..f3c8cce76 100644 --- a/src/webrtc.rs +++ b/src/webrtc.rs @@ -461,9 +461,8 @@ impl WebRTCStream { // Only tear down on the terminal states so a short network blip (Wi-Fi roam, // sleep/wake, cell handover) does not permanently kill an established session. RTCPeerConnectionState::Failed | RTCPeerConnectionState::Closed => { - let _ = on_connection_notify.send(WebRTCConnectionState::Closed( - s.to_string(), - )); + let _ = + on_connection_notify.send(WebRTCConnectionState::Closed(s.to_string())); log::debug!("WebRTC session closing due to {}", s); let _ = stream_for_close2.lock().await.close().await; log::debug!("WebRTC session stream closed"); @@ -698,9 +697,7 @@ impl WebRTCStream { == RTCIceCandidateType::Relay ) }; - Some( - is_relay(&pair.local_candidate_id) || is_relay(&pair.remote_candidate_id), - ) + Some(is_relay(&pair.local_candidate_id) || is_relay(&pair.remote_candidate_id)) } #[inline] @@ -945,7 +942,9 @@ impl WebRTCStream { FRAG_END => None, FRAG_MORE if n > 1 => None, FRAG_MORE => Some("FRAG_MORE fragment carries no payload".to_owned()), - other => Some(format!("fragment header {other} is neither FRAG_END nor FRAG_MORE")), + other => Some(format!( + "fragment header {other} is neither FRAG_END nor FRAG_MORE" + )), }; if let Some(why) = bad { *acc = BytesMut::new(); @@ -1068,10 +1067,7 @@ mod tests { "turn:example.com:3478" ); assert_eq!(WebRTCStream::get_ice_servers().len(), 2); - config::Config::set_option( - "ice-servers".to_string(), - "".to_string(), - ); + config::Config::set_option("ice-servers".to_string(), "".to_string()); } #[test] @@ -1362,7 +1358,11 @@ IHR5cCBzcmZseCByYWRkciAwLjAuMC4wIHJwb3J0IDY0MDA4XHJcbmE9ZW5kLW9mLWNhbmRpZGF0ZXNc let big = vec![0xABu8; 200_000]; offerer.send_raw(big.clone()).await.unwrap(); let got = answerer.next().await.unwrap().unwrap(); - assert_eq!(got.len(), big.len(), "large message must survive fragmentation"); + assert_eq!( + got.len(), + big.len(), + "large message must survive fragmentation" + ); assert_eq!(&got[..], &big[..]); // Reverse direction. @@ -1407,7 +1407,9 @@ IHR5cCBzcmZseCByYWRkciAwLjAuMC4wIHJwb3J0IDY0MDA4XHJcbmE9ZW5kLW9mLWNhbmRpZGF0ZXNc lead.put_u8(FRAG_MORE); lead.put_slice(b"leading!"); dc.write(&lead.freeze()).await.unwrap(); - dc.write(&bytes::Bytes::copy_from_slice(frame)).await.unwrap(); + dc.write(&bytes::Bytes::copy_from_slice(frame)) + .await + .unwrap(); let err = answerer .next() @@ -1472,5 +1474,4 @@ IHR5cCBzcmZseCByYWRkciAwLjAuMC4wIHJwb3J0IDY0MDA4XHJcbmE9ZW5kLW9mLWNhbmRpZGF0ZXNc .await .expect("concurrent WebRTC sends did not complete in time"); } - }