NAME
Log::Any::Progress - log incremental progress using Log::Any
VERSION
Version 1.00
SYNOPSIS
use Log::Any::Progress;
use Log::Any::Adapter 'Stderr';
my $progress = Log::Any::Progress->new(
count => $num_things_to_do,
prefix => 'Processing widgets',
);
foreach my $thing_to_do (@things_to_do) {
do_the_thing($thing_to_do);
$progress->update;
}
DESCRIPTION
This module makes it easy to use Log::Any to log incremental progress, similar in concept to Term::ProgressBar. It can be useful for monitoring the progress of a long-running process and to get an idea of how long that process might take to finish.
It is generally applied to a processing loop. In the typical case where the expected number of iterations is known in advance, it produces output containing the iteration count, percent completion, elapsed time, average time per iteration, and estimated time remaining. For example:
Progress: Iteration:0/5 0% STARTING
Progress: Iteration:1/5 20% Elapsed:2.000s Avg:2.000s Remaining:8.001s
Progress: Iteration:2/5 40% Elapsed:4.001s Avg:2.000s Remaining:6.001s
Progress: Iteration:3/5 60% Elapsed:6.001s Avg:2.000s Remaining:4.001s
Progress: Iteration:4/5 80% Elapsed:8.001s Avg:2.000s Remaining:2.000s
Progress: Iteration:5/5 100% FINISHED Elapsed:10.002s Avg:2.000s
The remaining time estimate as of any particular iteration is a simple linear calculation based on the average time per iteration up to that point, and the number of remaining iterations.
If the expected number of iterations is not known in advance, it still reports on incremental progress, but cannot compute either percent completion or estimated remaining time. For example:
Progress: Iteration:0 STARTING
Progress: Iteration:1 Elapsed:2.000s Avg:2.000s
Progress: Iteration:2 Elapsed:4.001s Avg:2.000s
Progress: Iteration:3 Elapsed:6.001s Avg:2.000s
Progress: Iteration:4 Elapsed:8.001s Avg:2.000s
Progress: Iteration:5 Elapsed:10.001s Avg:2.000s
METHODS
new
my $progress = Log::Any::Progress->new(
count => $num_things_to_do, # mandatory
delayed_start => 1,
logger => $logger,
log_level => 'info',
log_level_start_finish => 'notice',
min_sec_between_messages => 10,
prefix => 'Processing widgets',
);
Create a new object for logging incremental progress. Options include:
- count
-
A mandatory non-zero count of the expected number of iterations for progress tracking.
Specifying
-1
indicates that the expected number of iterations is unknown, in which case abbreviated statistics will be logged for each iteration (percent completion and estimated finish time cannot be computed without knowing the expected number of iterations in advance). - delayed_start
-
An optional boolean value controlling whether or not "start" should be automatically called at time of object construction. It defaults to false, in which case "start" is automatically called, assuming that progress tracking will commence immediately after.
Specifying a true value for
delayed_start
will prevent "start" from being automatically called, in which case it should be explicitly called just before progress iteration begins. - logger
-
An optional Log::Any logger object to use for logging.
If not specified, a logger object will be obtained via
Log::Any->get_logger()
, which will in turn use whatever Log::Any::Adapter might be configured.If not specifying a logger object, you will want to make sure that some adapter other than the default Log::Any::Adapter::Null adapter is configured (for example, Log::Any::Adapter::Stderr), otherwise no log messages will be emitted.
- log_level
-
An optional Log::Any log level for the incremental progress lines. It defaults to
info
.Valid log levels include:
trace debug info (inform) notice warning (warn) error (err) critical (crit, fatal) alert emergency
- log_level_start_finish
-
An optional Log::Any log level for the start and finish progress lines. It defaults to
notice
.Valid log levels include:
trace debug info (inform) notice warning (warn) error (err) critical (crit, fatal) alert emergency
- min_sec_between_messages
-
An optional value for the minimum number of seconds to wait before emitting the next incremental progress log message (as a result of calling "update"). Values specifying fractional seconds are allowed (e.g.
0.5
). It defaults to10
seconds.Setting
min_sec_between_messages
appropriately can be used to control log verbosity in cases where many hundreds or thousands of iterations are being processed and it's not necessary to report after each iteration. Setting it to0
will result in every incremental progress message will be emitted. - prefix
-
An optional string which will be used to prefix each logged message. It defaults to
Progress
.
start
my $progress = Log::Any::Progress->new(
count => $num_things_to_do,
delayed_start => 1, # don't start the timer yet
);
# Do some other work here that might take some time...
$progress->start;
foreach my $thing_to_do (@things_to_do) {
do_the_thing($thing_to_do);
$progress->update;
}
Initialize (or reinitialize) the progress object by resetting the start time, elapsed time, etc.
This is normally called automatically at object construction time unless "delayed_start" is specified, in which case it should be called explicitly at the appropriate time.
Initializing the progress object (whether done automatically or manually) causes the first log message to be emitted.
update
my $progress = Log::Any::Progress->new(
count => $num_things_to_do,
);
foreach my $thing_to_do (@things_to_do) {
do_the_thing($thing_to_do);
$progress->update;
}
Update the iteration count within the progress object and maybe emit a corresponding log message showing the current progress statistics (depending on timing and the value of "min_sec_between_messages").
Calling update
with no arguments increments the internal iteration count by one. A positive interger may be passed as an argument to explicitly update the iteration count to a particular value.
Once the iteration count reaches the specified "count" value, the progress is considered to be complete and a final log message is emitted with summary statistics, and subsequent calls to update
will have no effect.
format_seconds
my $string = $progress->format_seconds($elapsed_seconds);
This methods formats the elapsed time, average time, and remaining time values from seconds into something more easily readable. For example, 10000
seconds is formatted as 2h46m40.000s
.
It can be overridden in a subclass if desired.
AUTHOR
Larry Leszczynski, <larryl at cpan.org>
BUGS
Please report any bugs or feature requests through the web interface at https://github.com/larryl/Log-Any-Progress.
I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Log::Any::Progress
You can also look for information at:
GitHub (report bugs or suggest features here)
CPAN Ratings
Search CPAN
LICENSE AND COPYRIGHT
This software is Copyright (c) 2023 by Larry Leszczynski.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)