From: Christian Ebner <c.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH common 1/1] tools: Add callback based filtering for firewall logfiles
Date: Mon, 9 Jan 2023 16:07:06 +0100 [thread overview]
Message-ID: <20230109150706.446377-3-c.ebner@proxmox.com> (raw)
In-Reply-To: <20230109150706.446377-1-c.ebner@proxmox.com>
This patch introduces callback based filtering functionality for firewall logs.
In addition, the contents of rotated logfiles are included by setting the
`include_rotated_logs` flag.
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
src/PVE/Tools.pm | 108 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 91 insertions(+), 17 deletions(-)
diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm
index cdbee6d..cafc2f7 100644
--- a/src/PVE/Tools.pm
+++ b/src/PVE/Tools.pm
@@ -17,6 +17,7 @@ use IO::Handle;
use IO::Pipe;
use IO::Select;
use IO::Socket::IP;
+use IO::Zlib;
use IPC::Open3;
use JSON;
use POSIX qw(EINTR EEXIST EOPNOTSUPP);
@@ -1265,29 +1266,19 @@ 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, $start, $limit, $filter, $count, $lines, $read_until_end) = @_;
- $start = $start // 0;
- $limit = $limit // 50;
-
- 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,6 +1299,29 @@ sub dump_logfile {
}
}
+ return ($count, $lines, $limit);
+}
+
+sub dump_logfile {
+ my ($filename, $start, $limit, $filter) = @_;
+
+ $start = $start // 0;
+ $limit = $limit // 50;
+
+ my $read_until_end = $limit == 0;
+ 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);
+ }
+
+ ($count, $lines, $limit) = dump_logfile_by_filehandle(
+ $fh, $start, $limit, $filter, $count, $lines, $read_until_end);
+
close($fh);
# HACK: ExtJS store.guaranteeRange() does not like empty array
@@ -1320,6 +1334,66 @@ sub dump_logfile {
return ($count, $lines);
}
+sub dump_fw_logfile {
+ my ($filename, $start, $limit, $filter, $include_rotated_logs) = @_;
+
+ if (!$include_rotated_logs) {
+ return dump_logfile($filename, $start, $limit, $filter);
+ }
+
+ $start = $start // 0;
+ $limit = $limit // 50;
+
+ # Take into consideration also rotated logs
+ my ($basename, $logdir, $type) = fileparse($filename);
+ my @files = ();
+
+ opendir(LOGDIR, $logdir) || die "Cannot open $logdir";
+ my $entry;
+ while ($entry = readdir(LOGDIR)) {
+ my $namefilter = $basename."*";
+ next if $entry !~ m/$namefilter/;
+ push @files, $entry;
+ }
+ closedir(LOGDIR);
+ @files = reverse sort @files;
+
+ my $read_until_end = $limit == 0;
+ my $lines = [];
+ my $count = 0;
+
+ foreach (@files) {
+ my ($base, $path, $type) = fileparse($_, ".gz");
+
+ my $fh;
+ if ($type eq '.gz') {
+ $fh = IO::Zlib->new($logdir.$_, "r");
+ } else {
+ $fh = IO::File->new($logdir.$_, "r");
+ }
+
+ if (!$fh) {
+ $count++;
+ push @$lines, { n => $count, t => "unable to open file - $!"};
+ return ($count, $lines);
+ }
+
+ ($count, $lines, $limit) = dump_logfile_by_filehandle(
+ $fh, $start, $limit, $filter, $count, $lines, $read_until_end);
+
+ close($fh);
+ }
+
+ # HACK: ExtJS store.guaranteeRange() does not like empty array
+ # so we add a line
+ if (!$count) {
+ $count++;
+ push @$lines, { n => $count, t => "no content"};
+ }
+
+ return ($count, $lines);
+}
+
sub dump_journal {
my ($start, $limit, $since, $until, $service) = @_;
--
2.30.2
next prev parent reply other threads:[~2023-01-09 15:08 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-09 15:07 [pve-devel] [PATCH common firewall] Optonal `since` and `until` firewall log filtering Christian Ebner
2023-01-09 15:07 ` [pve-devel] [PATCH firewall 1/1] api: Add optional parameters `since` and `until` for timestamp filter Christian Ebner
2023-01-09 15:07 ` Christian Ebner [this message]
2023-01-10 12:36 ` [pve-devel] [PATCH common 1/1] tools: Add callback based filtering for firewall logfiles Wolfgang Bumiller
2023-01-11 8:36 ` Christian Ebner
2023-01-11 8:42 ` Wolfgang Bumiller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230109150706.446377-3-c.ebner@proxmox.com \
--to=c.ebner@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.