rate-log 0.1.0

A Rust library for rate-limited logging that prevents spam by tracking message frequency and duration.
Documentation
  • Coverage
  • 100%
    7 out of 7 items documented6 out of 7 items with examples
  • Size
  • Source code size: 27.33 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.74 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 13s Average build duration of successful builds.
  • all releases: 12s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • ChenhuiZhang

Rate Log

Crates.io Documentation License

A Rust library for rate-limited logging that prevents spam by tracking message frequency and duration. This crate helps reduce log noise by detecting repeated messages and only outputting warnings when configurable limits are exceeded.

Inspired by the log_hz crate.

Features

  • Count-based rate limiting: Limit by number of repeated message occurrences
  • Duration-based rate limiting: Limit by accumulated time between repeated messages
  • Unified tracking: Always tracks both count and duration for comprehensive reporting
  • Smart duration formatting: Automatically formats durations in appropriate units (ms, s, m, h)
  • Message deduplication: Automatically resets counters when different messages are logged
  • Zero-cost abstractions: Minimal runtime overhead with compile-time optimizations
  • Test-friendly: Built-in output capture for unit testing

Quick Start

Add this to your Cargo.toml:

[dependencies]
rate-log = "0.1.0"

Basic Usage

use rate_log::{RateLog, Limit};
use std::time::Duration;

// Create a rate limiter that allows up to 5 repeated messages
let mut rate_log = RateLog::new(Limit::Rate(5));

// First occurrence of any message is always printed immediately
rate_log.log("This is a new message");  // Prints: "This is a new message"

// Log the same message multiple times - no output until limit exceeded
for i in 0..7 {
    rate_log.log("This is a new message");
}
// After 5 repetitions, it will output:
// "Message: \"This is a new message\" repeat for 5 times in the past 10ms"

// Different message gets printed immediately and resets counter
rate_log.log("Different message");  // Prints: "Different message"

Rate Limiting Types

Count-based Limiting (Limit::Rate)

Tracks the number of times the same message is logged consecutively:

use rate_log::{RateLog, Limit};

let mut logger = RateLog::new(Limit::Rate(3));

logger.log("Error occurred");     // 1st occurrence - printed immediately: "Error occurred"
logger.log("Error occurred");     // 2nd occurrence - counted silently
logger.log("Error occurred");     // 3rd occurrence - counted silently
logger.log("Error occurred");     // 4th occurrence - triggers warning:
                                  // "Message: \"Error occurred\" repeat for 3 times in the past 15ms"
logger.log("Different error");    // New message - printed immediately: "Different error"

Duration-based Limiting (Limit::Duration)

Accumulates the time elapsed between consecutive calls with the same message:

use rate_log::{RateLog, Limit};
use std::time::Duration;
use std::thread;

let mut logger = RateLog::new(Limit::Duration(Duration::from_secs(1)));

logger.log("Periodic event");      // 1st occurrence - printed immediately: "Periodic event"
thread::sleep(Duration::from_millis(300));
logger.log("Periodic event");      // 300ms accumulated - silent
thread::sleep(Duration::from_millis(800));
logger.log("Periodic event");      // 1100ms total - triggers warning:
                                   // "Message: \"Periodic event\" repeat for 2 times in the past 1s"

Use Cases

Error Logging

Prevent log spam from repeated error conditions:

use rate_log::{RateLog, Limit};

let mut error_logger = RateLog::new(Limit::Rate(10));

// This will only show the first occurrence and then a summary after 10 repetitions
for _ in 0..50 {
    error_logger.log("Database connection failed");
}

Performance Monitoring

Rate-limit performance warnings:

use rate_log::{RateLog, Limit};
use std::time::Duration;

let mut perf_logger = RateLog::new(Limit::Duration(Duration::from_secs(30)));

// Only warn about slow responses every 30 seconds of accumulated time
if response_time > threshold {
    perf_logger.log("Slow response detected");
}

Network Logging

Manage connection retry message frequency:

use rate_log::{RateLog, Limit};

let mut net_logger = RateLog::new(Limit::Rate(5));

// Limit connection retry spam
while !connected {
    net_logger.log("Retrying connection...");
    // attempt connection
}

Behavior

  • New message printing: Every new/different message is immediately printed to stdout
  • Unified tracking: Always tracks both message count and elapsed duration regardless of limit type
  • Silent repetitions: Repeated messages are counted silently until limit exceeded
  • Smart duration formatting: Automatically displays duration in appropriate units (ms, s, m, h) with whole numbers
  • Comprehensive warnings: Rate limit violations show both count and duration: "Message: "text" repeat for X times in the past Yms"
  • Counter reset: Switching to a different message resets all counters and prints the new message

API Documentation

RateLog::new(limit: Limit) -> Self

Creates a new rate limiter with the specified threshold.

RateLog::log(&mut self, msg: &str)

Logs a message with rate limiting applied. New messages are printed immediately, repeated messages are tracked until limits are exceeded.

Limit::Rate(u32)

Count-based rate limiting. Triggers when the same message exceeds the specified count.

Limit::Duration(Duration)

Duration-based rate limiting. Triggers when accumulated time between repeated messages exceeds the specified duration.

Testing

Run the test suite:

cargo test

Run with output to see the rate limiting in action:

cargo test -- --nocapture

Todo

  • Add configurable output formatting
  • Support for custom output writers (not just stdout)
  • Add reset methods for manual counter clearing
  • Benchmarks and performance optimization
  • no_std support for embedded environments
  • Integration with popular logging frameworks (log, tracing)
  • Configurable timestamp precision
  • Memory usage optimization for long-running applications
  • Async support for non-blocking rate limiting
  • Multi-threaded safety with Arc<Mutex<RateLog>>
  • Persistent rate limiting across application restarts
  • Rate limiting policies (exponential backoff, sliding window)
  • Metrics integration (Prometheus, StatsD)

Development

# Clone the repository
git clone https://github.com/your-username/rate-log.git
cd rate-log

# Run tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Check documentation
cargo doc --open

# Run clippy for linting
cargo clippy

# Format code
cargo fmt

License

This project is licensed under the MIT license (LICENSE or http://opensource.org/licenses/MIT).

Contribution

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to:

  • Update tests as appropriate
  • Follow the existing code style
  • Run cargo fmt and cargo clippy before submitting
  • Add documentation for new features