| Crates.io | poll-tail |
| lib.rs | poll-tail |
| version | 0.1.2 |
| created_at | 2025-10-12 17:55:00.884711+00 |
| updated_at | 2025-10-25 18:07:26.568427+00 |
| description | A simple, polling-based file tailer that gracefully handles log rotation and timestamp parsing. |
| homepage | |
| repository | https://github.com/xangelix/poll-tail |
| max_upload_size | |
| id | 1879488 |
| size | 34,956 |
A simple, polling-based file tailer that gracefully handles log rotation.
poll-tail provides a FileListener that monitors a file for changes, similar to tail --follow. It's designed to be robust against file truncation, replacement, and deletion, which are common with log rotation mechanisms.
It operates on a synchronous, polling basis via the tick() method, making it extremely easy to integrate into any application loop without needing an async runtime or complex event-driven dependencies.
tick() periodically in your loop.Add the following to your Cargo.toml:
[dependencies]
poll-tail = "0.1.0" # use the latest version
Here's a basic example that follows a log file and prints new lines as they appear.
use std::{time::Duration, thread};
use poll_tail::{FileListener, Error};
fn main() -> Result<(), Error> {
let log_path = "/var/log/app.log";
// The builder will succeed even if the log file doesn't exist yet.
let mut listener = FileListener::builder(log_path)
.max_lines(1000) // Keep a rolling buffer of the last 1000 lines.
.initial_read_lines(50) // On first detection, read the last 50 lines.
.build()?;
println!("Watching for changes in {log_path}...");
loop {
// The core of the library: check the file for changes.
listener.tick()?;
// The lines() method gives you access to the internal buffer.
// You would typically process these lines (e.g., send them, display them)
// and then clear your own state.
for (timestamp, line) in listener.lines() {
// The default parser extracts RFC 3339 timestamps or uses the
// last known timestamp as a fallback.
println!("[{}] {}", timestamp.to_rfc3339(), line.trim_end());
}
// Poll every second.
thread::sleep(Duration::from_secs(1));
}
}
FileListener: The main struct that holds the file state and line buffer.FileListenerBuilder: A convenient builder for configuring the listener.tick(): The primary method you call to check for file updates.lines(): Returns a reference to the internal VecDeque of (DateTime<Utc>, String) tuples.Error: A thiserror-based enum for all possible failures.This project is licensed under the MIT license.