G'day ovedpo15,
Three reasons why I wouldn't recommend this approach:
-
You are effectively deleting information from a log.
Except for appending information to a log,
I would consider it to be very bad practice to modify a log's contents in any other manner.
-
Your progress is based on the number of paths processed.
Information about how long each took to process (i.e. from the timestamps) is lost.
-
You will run into all sorts of problems if you try to `tail -f logfile` when its contents are in flux.
Having said that, if you want to proceed with this
— perhaps you just want snapshots of the log instead of continual progress updates —
you could use the core module Tie::File.
Here's an example (with show_log_to_date() simulating snapshots):
#!/usr/bin/env perl
use strict;
use warnings;
use Tie::File;
my $DEBUG_FILE = 'pm_11134904_log_progress.log';
tie my(@DEBUG_RECORDS), 'Tie::File', $DEBUG_FILE
or die "Can't tie $DEBUG_FILE: $!";
debug("$0 started.");
for my $step ('A' .. 'C') {
debug("Start step $step");
if ($step eq 'B') {
my @paths = 1 .. 5;
my $overwrite_last = 0;
for my $path (@paths) {
sleep 1;
my $progress = 100 * $path / @paths;
my $msg = "Processing step $step Progress: $progress%";
debug($msg, $overwrite_last++);
show_log_to_date();
}
}
else {
debug("Processing step $step ...");
}
debug("End step $step");
}
debug("$0 completed.");
untie @DEBUG_RECORDS;
show_log_to_date();
sub debug {
my ($msg, $overwrite_last) = @_;
my $log_entry = join ' ', "".localtime, $msg;
pop @DEBUG_RECORDS if $overwrite_last;
push @DEBUG_RECORDS, $log_entry;
return;
}
sub show_log_to_date {
print '-' x 40, "\n";
system cat => $DEBUG_FILE;
}
Output from a sample run:
$ ./pm_11134904_log_progress.pl
----------------------------------------
Sun Jul 11 10:20:39 2021 ./pm_11134904_log_progress.pl started.
Sun Jul 11 10:20:39 2021 Start step A
Sun Jul 11 10:20:39 2021 Processing step A ...
Sun Jul 11 10:20:39 2021 End step A
Sun Jul 11 10:20:39 2021 Start step B
Sun Jul 11 10:20:40 2021 Processing step B Progress: 20%
----------------------------------------
Sun Jul 11 10:20:39 2021 ./pm_11134904_log_progress.pl started.
Sun Jul 11 10:20:39 2021 Start step A
Sun Jul 11 10:20:39 2021 Processing step A ...
Sun Jul 11 10:20:39 2021 End step A
Sun Jul 11 10:20:39 2021 Start step B
Sun Jul 11 10:20:41 2021 Processing step B Progress: 40%
----------------------------------------
Sun Jul 11 10:20:39 2021 ./pm_11134904_log_progress.pl started.
Sun Jul 11 10:20:39 2021 Start step A
Sun Jul 11 10:20:39 2021 Processing step A ...
Sun Jul 11 10:20:39 2021 End step A
Sun Jul 11 10:20:39 2021 Start step B
Sun Jul 11 10:20:42 2021 Processing step B Progress: 60%
----------------------------------------
Sun Jul 11 10:20:39 2021 ./pm_11134904_log_progress.pl started.
Sun Jul 11 10:20:39 2021 Start step A
Sun Jul 11 10:20:39 2021 Processing step A ...
Sun Jul 11 10:20:39 2021 End step A
Sun Jul 11 10:20:39 2021 Start step B
Sun Jul 11 10:20:43 2021 Processing step B Progress: 80%
----------------------------------------
Sun Jul 11 10:20:39 2021 ./pm_11134904_log_progress.pl started.
Sun Jul 11 10:20:39 2021 Start step A
Sun Jul 11 10:20:39 2021 Processing step A ...
Sun Jul 11 10:20:39 2021 End step A
Sun Jul 11 10:20:39 2021 Start step B
Sun Jul 11 10:20:44 2021 Processing step B Progress: 100%
----------------------------------------
Sun Jul 11 10:20:39 2021 ./pm_11134904_log_progress.pl started.
Sun Jul 11 10:20:39 2021 Start step A
Sun Jul 11 10:20:39 2021 Processing step A ...
Sun Jul 11 10:20:39 2021 End step A
Sun Jul 11 10:20:39 2021 Start step B
Sun Jul 11 10:20:44 2021 Processing step B Progress: 100%
Sun Jul 11 10:20:44 2021 End step B
Sun Jul 11 10:20:44 2021 Start step C
Sun Jul 11 10:20:44 2021 Processing step C ...
Sun Jul 11 10:20:44 2021 End step C
Sun Jul 11 10:20:44 2021 ./pm_11134904_log_progress.pl completed.
Some other points regarding the specific code you posted:
-
You are opening and closing the logfile every time you call debug().
Unless you have a very good reason for doing otherwise,
open once near the start of the program, pass a filehandle to debug(),
close once near the end of the program.
-
The 'open ... or return 0;' made me cringe: that's no way to handle I/O problems.
See open for many examples of how to do this;
my code above has an example;
also autodie is often a good alternative method (I use this a lot).
-
Use of a lexical filehandle and the 3-argument form of open is very good;
it's just the error handling that has a problem.
-
I see 'return 0' used twice in debug(); however, although not shown,
I would expect debug() is called in void context,
i.e. debug(...) not my $debug_return_value = debug(...).
Just use return; in any subroutine that's called in void context.