From 12a0ec1888e4c423dbe890b65460a703afb91c47 Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Wed, 11 Jan 2023 14:32:20 +0100 Subject: [PATCH] tools: Add callback based filtering for logfile dump This patch introduces callback based filtering functionality for logfile dumps. Further, the `dump_logfile` function is split into a reusable part for dumps generated based on a filehandle. The state parameter can be used to keep the state for multiple consecutive function invocations. Signed-off-by: Christian Ebner --- src/PVE/Tools.pm | 59 +++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index cdbee6d..d933503 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -1265,29 +1265,25 @@ sub split_args { return $str ? [ Text::ParseWords::shellwords($str) ] : []; } -sub dump_logfile { - my ($filename, $start, $limit, $filter) = @_; - - my $lines = []; - my $count = 0; - - my $fh = IO::File->new($filename, "r"); - if (!$fh) { - $count++; - push @$lines, { n => $count, t => "unable to open file - $!"}; - return ($count, $lines); - } +sub dump_logfile_by_filehandle { + my ($fh, $filter, $state) = @_; - $start = $start // 0; - $limit = $limit // 50; + my $count = ($state->{count} //= 0); + my $lines = ($state->{lines} //= []); + my $start = ($state->{start} //= 0); + my $limit = ($state->{limit} //= 50); + my $final = ($state->{final} //= 1); + my $read_until_end = ($state->{read_until_end} //= $limit == 0); - my $read_until_end = $limit == 0; my $line; - if ($filter) { # duplicate code, so that we do not slow down normal path while (defined($line = <$fh>)) { - next if $line !~ m/$filter/; + if (ref($filter) eq 'CODE') { + next if !$filter->($line); + } else { + next if $line !~ m/$filter/; + } next if $count++ < $start; if (!$read_until_end) { next if $limit <= 0; @@ -1308,16 +1304,37 @@ sub dump_logfile { } } - close($fh); - # HACK: ExtJS store.guaranteeRange() does not like empty array # so we add a line - if (!$count) { + if (!$count && $final) { $count++; push @$lines, { n => $count, t => "no content"}; } - return ($count, $lines); + $state->{count} = $count; + $state->{limit} = $limit; +} + +sub dump_logfile { + my ($filename, $start, $limit, $filter) = @_; + + my $fh = IO::File->new($filename, "r"); + if (!$fh) { + return (1, { n => 1, t => "unable to open file - $!"}); + } + + my %state = ( + 'count' => 0, + 'lines' => [], + 'start' => $start, + 'limit' => $limit, + ); + + dump_logfile_by_filehandle($fh, $filter, \%state); + + close($fh); + + return ($state{'count'}, $state{'lines'}); } sub dump_journal { -- 2.39.2