#logging #log


Thread safe progress logging

2 unstable releases

0.3.0 Aug 8, 2022
0.2.0 Aug 5, 2022

#602 in Concurrency

Download history 28/week @ 2023-12-03 27/week @ 2023-12-10 8/week @ 2023-12-17 55/week @ 2023-12-31 74/week @ 2024-01-07 66/week @ 2024-01-14 104/week @ 2024-01-21 24/week @ 2024-02-11 63/week @ 2024-02-18 131/week @ 2024-02-25 37/week @ 2024-03-03 35/week @ 2024-03-10 44/week @ 2024-03-17

247 downloads per month
Used in 2 crates


345 lines

🦫 proglog

Build Status license Version info

Documentation Crates.io

This is a simple, thread-safe, count-based, progress logger.


proglog hooks into your existing log implementation (i.e. env_logger) and will output a log message every unit number of items it has seen. There are two primary methods, record() and record_with(...). record() simply increments the counter and will cause a log message to output when counter % unit == 0. record_with(Fn() -> impl Display) takes a function that outputs anything implementing display which will be appended to the log message.

How to use this

Add to your deps:

cargo add proglog


Please see the rayon example.

use proglog::ProgLogBuilder;

// Note a `log` backend needs to be globally initialized first

let logger = ProgLogBuilder::new().build();
for i in 0..10_000 {
    logger.record_with(|| format!("Logged item: {}", i));

// The logger will flush when it is dropped, writing a final progress message no mater the count.
// Alternatively you can call .flush() or .flush_with().

Things to know

If unit is too small, and your loop is too tight, this will output many log messages which will slow your program down in the same way any logging would slow a program down in a hot loop. If unit is sufficiently large, this should be safe to put in a hot loop as all it does increment update an atomic u64.

If your loop is tight, unit is small, and you are using rayon / updating from multiple threads your log messages may end up out of order. There is no guaranteed ordering of the submission of the log message to the logger. So thread A could hit the first unit break, thread B could hit the second point at the same time, but thread B gets to submit its log message first. Having sufficiently large unit will mitigate this, but you should not be depending on the log output order here. The tradeoff made is for speed of incrementing so this can be put in hot loops over guaranteed output ordering.



The pretty_counts features turns on the ability to format the numbers in the log messages. Set the ProgLogBuilder::count_formatter to one of the CountFormatterKinds and numbers will be formatted accordingly. i.e. 100000000 -> 100_000_000 with CountFormatterKind::Underscore.


cargo test

Direct Inspirations

  • The ProgressLogger found in fgpyo
  • The ProgressLogger in fgbio