I'm trying to write a small process that keeps scanning a log path.
All the rotated files are ".csv", while the current one which is still being written has ".csv.cur" as its extension.
The process should keep looking in "almost" real time for ".csv.cur" files and perform operations on their content.
To make it short, it should work like a "tail -f | replace something".
So this is the main code:
for (;;) {
opendir(my $cdrs, $path) || die $!;
my @current = grep { /^$host.+\.cur$/ && -f "$path/$_" } readdir($cdrs);
closedir($cdrs);
if (! $current[0]) {
&debug(DEBUG_MODE, "[PARENT] No CURRENT file found in: $path/. Retrying in $current_lookup_retry second(s)...\n");
sleep $current_lookup_retry;
next;
}
if ((! $last_file) || ($last_file ne $current[0])) {
$last_file = $current[0];
my $c_pid = &spawn_guardian("$path/$current[0]");
&debug(DEBUG_MODE, "[PARENT] Guardian spawned (Child PID $c_pid)\n");
&debug(DEBUG_MODE, "[PARENT] CURRENT set to: $current[0]\n");
}
select(undef, undef, undef, $ms);
}
And the sub spawn_guardian:
sub spawn_guardian() {
$SIG{CHLD} = "IGNORE"; # prevent defunct processes
my $child_pid = fork();
if (!defined $child_pid) {
die "[CHILD] Cannot fork: $!";
} elsif ($child_pid == 0) {
# no need to verify if the parent dies
&debug(DEBUG_MODE, "[CHILD][$$] Spawning guardian for $_[0]...\n");
my $file = File::Tail->new(name => $_[0],
#name_changes => \&lcount($line_count),
interval => 1,
maxinterval => 5,
adjustafter => 1,
#errmode => 'die',
resetafter => 15,
debug => DEBUG_MODE);
while (defined(my $line = $file->read)) {
if ($line) { # Try to evaluate the content of $line
print "[CHILD][$$] $line";
} else { # Try to gracefully exit from this Child process
&grace($$, $_[0]);
}
}
&debug(DEBUG_MODE, "[CHILD][$$] Exiting guardian for $_[0]...\n"); # this should never be executed anyway
exit 0; # same as previous line
}
return $child_pid; # return PID to Parent process
}
This is the output I get from this code:
[DEBUG][PARENT] No CURRENT file found in: /root/OLOShaper/. Retrying in 2 second(s)...
[DEBUG][PARENT] No CURRENT file found in: /root/OLOShaper/. Retrying in 2 second(s)...
[DEBUG][CHILD][8346] Spawning guardian for /root/OLOShaper/mcitti21-KCZsOUrfmlFNRDXk.csv.cur...
[DEBUG][PARENT] Guardian spawned (Child PID 8346)
[DEBUG][PARENT] CURRENT set to: mcitti21-KCZsOUrfmlFNRDXk.csv.cur
[CHILD][8346] <omitted content of the .csv.cur>
[CHILD][8346] <omitted content of the .csv.cur>
[CHILD][8346] <omitted content of the .csv.cur>
[DEBUG][PARENT] No CURRENT file found in: /root/OLOShaper/. Retrying in 2 second(s)...
Error opening /root/OLOShaper/mcitti21-KCZsOUrfmlFNRDXk.csv.cur: No such file or directory at ./OLOShaper line 91
[DEBUG][PARENT] No CURRENT file found in: /root/OLOShaper/. Retrying in 2 second(s)...
[DEBUG]Ctrl-C detected!
Graceful shutdown in progress for PID 8344...
[DEBUG]Resetting PID file...
[DEBUG]Removing PID file...
Service ./OLOShaper has been halted.
So as you can see I get this error:
Error opening /root/OLOShaper/mcitti21-KCZsOUrfmlFNRDXk.csv.cur: No such file or directory at ./OLOShaper line 91
What I do in oder to generate it, it's to delete the .csv.cur file while the process is scanning it.
Of course, I'm doing such idiotic thing in order to test the code, but I really can't come up with a solution to handle this error.
Let me know if you need more information.