@@ -295,3 +295,156 @@ macro_rules! info_ratelimited {
295295 }
296296 } ;
297297}
298+
299+ /// As [`tracing::event!`], but rate limited.
300+ ///
301+ /// Can be called with optional parameters to customize rate limiting:
302+ /// - `period: <ms>` - rate limiting period in milliseconds
303+ /// - `limit: <count>` - maximum events per period
304+ ///
305+ /// `level` is required and must be a compile-time literal identifier (ERROR, WARN, INFO, DEBUG, TRACE).
306+ #[ macro_export]
307+ macro_rules! event_ratelimited_static {
308+ // With both period and limit and level
309+ ( level: $level: ident, period: $period: expr, limit: $limit: expr, $( $rest: tt) * ) => { {
310+ static RATE_LIMITER : $crate:: RateLimiter = $crate:: RateLimiter :: new_default( ) ;
311+ if let Ok ( missed_events) = RATE_LIMITER . event_with_config( Some ( $period) , Some ( $limit) ) {
312+ $crate:: tracing:: event!(
313+ $crate:: tracing:: Level :: $level,
314+ dropped_ratelimited = missed_events,
315+ $( $rest) *
316+ ) ;
317+ }
318+ } } ;
319+ // With only period and level
320+ ( level: $level: ident, period: $period: expr, $( $rest: tt) * ) => { {
321+ static RATE_LIMITER : $crate:: RateLimiter = $crate:: RateLimiter :: new_default( ) ;
322+ if let Ok ( missed_events) = RATE_LIMITER . event_with_config( Some ( $period) , None ) {
323+ $crate:: tracing:: event!(
324+ $crate:: tracing:: Level :: $level,
325+ dropped_ratelimited = missed_events,
326+ $( $rest) *
327+ ) ;
328+ }
329+ } } ;
330+ // With only limit and level
331+ ( level: $level: ident, limit: $limit: expr, $( $rest: tt) * ) => { {
332+ static RATE_LIMITER : $crate:: RateLimiter = $crate:: RateLimiter :: new_default( ) ;
333+ if let Ok ( missed_events) = RATE_LIMITER . event_with_config( None , Some ( $limit) ) {
334+ $crate:: tracing:: event!(
335+ $crate:: tracing:: Level :: $level,
336+ dropped_ratelimited = missed_events,
337+ $( $rest) *
338+ ) ;
339+ }
340+ } } ;
341+ // Default case (only level provided)
342+ ( level: $level: ident, $( $rest: tt) * ) => { {
343+ static RATE_LIMITER : $crate:: RateLimiter = $crate:: RateLimiter :: new_default( ) ;
344+ if let Ok ( missed_events) = RATE_LIMITER . event( ) {
345+ $crate:: tracing:: event!(
346+ $crate:: tracing:: Level :: $level,
347+ dropped_ratelimited = missed_events,
348+ $( $rest) *
349+ ) ;
350+ }
351+ } } ;
352+ }
353+
354+ /// Helper macro for dynamically dispatching to [`event_ratelimited_static!`] based on a runtime level.
355+ ///
356+ /// This macro accepts a runtime `tracing::Level` expression and dispatches to the appropriate
357+ /// compile-time level identifier. Allows the log level to be determined at runtime.
358+ ///
359+ /// Examples:
360+ /// ```
361+ /// use tracing::Level;
362+ /// use tracelimit::event_ratelimited;
363+ /// event_ratelimited!(Level::ERROR, period: 1000, limit: 5, "custome period and limit");
364+ /// event_ratelimited!(Level::WARN, period: 10000, "custom period only");
365+ /// event_ratelimited!(Level::INFO, limit: 50, "custom limit only");
366+ /// event_ratelimited!(Level::TRACE, "simple message");
367+ /// ```
368+ #[ macro_export]
369+ macro_rules! event_ratelimited {
370+ // With period and limit and level
371+ ( $level: expr, period: $period: expr, limit: $limit: expr, $( $rest: tt) * ) => {
372+ match $level {
373+ $crate:: tracing:: Level :: ERROR => {
374+ $crate:: event_ratelimited_static!( level: ERROR , period: $period, limit: $limit, $( $rest) * ) ;
375+ }
376+ $crate:: tracing:: Level :: WARN => {
377+ $crate:: event_ratelimited_static!( level: WARN , period: $period, limit: $limit, $( $rest) * ) ;
378+ }
379+ $crate:: tracing:: Level :: INFO => {
380+ $crate:: event_ratelimited_static!( level: INFO , period: $period, limit: $limit, $( $rest) * ) ;
381+ }
382+ $crate:: tracing:: Level :: DEBUG => {
383+ $crate:: event_ratelimited_static!( level: DEBUG , period: $period, limit: $limit, $( $rest) * ) ;
384+ }
385+ $crate:: tracing:: Level :: TRACE => {
386+ $crate:: event_ratelimited_static!( level: TRACE , period: $period, limit: $limit, $( $rest) * ) ;
387+ }
388+ }
389+ } ;
390+ // With period and level
391+ ( $level: expr, period: $period: expr, $( $rest: tt) * ) => {
392+ match $level {
393+ $crate:: tracing:: Level :: ERROR => {
394+ $crate:: event_ratelimited_static!( level: ERROR , period: $period, $( $rest) * ) ;
395+ }
396+ $crate:: tracing:: Level :: WARN => {
397+ $crate:: event_ratelimited_static!( level: WARN , period: $period, $( $rest) * ) ;
398+ }
399+ $crate:: tracing:: Level :: INFO => {
400+ $crate:: event_ratelimited_static!( level: INFO , period: $period, $( $rest) * ) ;
401+ }
402+ $crate:: tracing:: Level :: DEBUG => {
403+ $crate:: event_ratelimited_static!( level: DEBUG , period: $period, $( $rest) * ) ;
404+ }
405+ $crate:: tracing:: Level :: TRACE => {
406+ $crate:: event_ratelimited_static!( level: TRACE , period: $period, $( $rest) * ) ;
407+ }
408+ }
409+ } ;
410+ // With limit and level
411+ ( $level: expr, limit: $limit: expr, $( $rest: tt) * ) => {
412+ match $level {
413+ $crate:: tracing:: Level :: ERROR => {
414+ $crate:: event_ratelimited_static!( level: ERROR , limit: $limit, $( $rest) * ) ;
415+ }
416+ $crate:: tracing:: Level :: WARN => {
417+ $crate:: event_ratelimited_static!( level: WARN , limit: $limit, $( $rest) * ) ;
418+ }
419+ $crate:: tracing:: Level :: INFO => {
420+ $crate:: event_ratelimited_static!( level: INFO , limit: $limit, $( $rest) * ) ;
421+ }
422+ $crate:: tracing:: Level :: DEBUG => {
423+ $crate:: event_ratelimited_static!( level: DEBUG , limit: $limit, $( $rest) * ) ;
424+ }
425+ $crate:: tracing:: Level :: TRACE => {
426+ $crate:: event_ratelimited_static!( level: TRACE , limit: $limit, $( $rest) * ) ;
427+ }
428+ }
429+ } ;
430+ // Default case (only level provided)
431+ ( $level: expr, $( $rest: tt) * ) => {
432+ match $level {
433+ $crate:: tracing:: Level :: ERROR => {
434+ $crate:: event_ratelimited_static!( level: ERROR , $( $rest) * ) ;
435+ }
436+ $crate:: tracing:: Level :: WARN => {
437+ $crate:: event_ratelimited_static!( level: WARN , $( $rest) * ) ;
438+ }
439+ $crate:: tracing:: Level :: INFO => {
440+ $crate:: event_ratelimited_static!( level: INFO , $( $rest) * ) ;
441+ }
442+ $crate:: tracing:: Level :: DEBUG => {
443+ $crate:: event_ratelimited_static!( level: DEBUG , $( $rest) * ) ;
444+ }
445+ $crate:: tracing:: Level :: TRACE => {
446+ $crate:: event_ratelimited_static!( level: TRACE , $( $rest) * ) ;
447+ }
448+ }
449+ } ;
450+ }
0 commit comments