Crate dsi_progress_logger
source ·Expand description
A tunable progress logger to log progress information about long-running activities.
It is a port of the Java class it.unimi.dsi.util.ProgressLogger
from the DSI Utilities.
Logging is based on the standard log
crate at the info
level.
There is a ProgressLog
trait and a default implementation ProgressLogger
.
To log the progress of an activity, you call start
. Then, each time you want to mark progress,
you call update
, which increases the item counter, and will log progress information
if enough time has passed since the last log. The time check happens (in the case of ProgressLogger
)only on multiples of
LIGHT_UPDATE_MASK
+ 1 in the case of
light_update
,
which should be used when the activity has an extremely low cost that is comparable to that
of the time check (a call to Instant::now()
) itself.
A few setters can be called at any time to customize the logger (e.g., item_name
,
log_interval
, expected_updates
, etc.).
The setters take and return a mutable reference to the logger, so you must first assign
the logger to a variable, and then you can chain-call the setters on the variable in fluent style.
The disadvantage of this approach is that you must assign the logger to a variable, but the advantage
is that you can call any setter without having to reassign the variable holding the logger.
It is also possible to log used and free memory at each log interval by calling
display_memory
. Memory is read from system data by the sysinfo
crate, and
will be updated at each log interval (note that this will slightly slow down the logging process).
At any time, displaying the progress logger will give you time information up to the present.
However, since it is impossible to update the memory information from the Display::fmt
implementation,
you should call refresh
before displaying the logger
on your own.
When the activity is over, you call stop
, which fixes the final time, and
possibly display again the logger. done
will stop the logger, print Completed.
,
and display the final stats.
After you finished a run of the progress logger, can call start
again to measure another activity.
A typical call sequence to a progress logger is as follows:
use dsi_progress_logger::*;
stderrlog::new().init().unwrap();
let mut pl = ProgressLog::default();
pl.item_name("pumpkin");
pl.start("Smashing pumpkins...");
for _ in 0..100 {
// do something on each pumpkin
pl.update();
}
pl.done();
A progress logger can also be used as a handy timer:
use dsi_progress_logger::*;
stderrlog::new().init().unwrap();
let mut pl = ProgressLogger::default();
pl.item_name("pumpkin");
pl.start("Smashing pumpkins...");
for _ in 0..100 {
// do something on each pumpkin
}
pl.done_with_count(100);
This progress logger will display information about memory usage:
use dsi_progress_logger::*;
stderrlog::new().init().unwrap();
let mut pl = ProgressLogger::default();
pl.display_memory(true);
Optional logging
This crate supports optional logging by implementing ProgressLog
for Option<ProgressLog>
as a no-op.
As a result, you can pass to functions an argument pl
that is an impl ProgressLog
, with the following behavior:
- if you pass a
ProgressLogger
, the progress logger will be used, without any check; - if you pass
Option<ProgressLogger>::None
, no logging will be performed, and in fact the logging code should be entirely optimized away by the compiler; - if you pass an
Option::<ProgressLogger>
, logging will happen depending on the variant, and there will be a runtime check for each call topl
.
There is an info
method that can be used to log information to the logger
at the info
level.
The advantage of using info
is that the
logging will be optional depending on the type of the logger.
Structs
Traits
- Logging trait.