Add support for additional units in systemd log viewer

This commit is contained in:
Ilia Ross
2024-05-26 01:12:39 +03:00
parent f9198b0fbd
commit cc2502737f
5 changed files with 143 additions and 27 deletions

View File

@@ -0,0 +1,4 @@
lines=100
others=1
reverse=1
extras_units=apache2.service apparmor.service apport.service clamav-daemon.service clamav-freshclam.service console-setup.service cron.service dbus.service dovecot.service fail2ban.service fcgiwrap-*.service firewalld.service lm-sensors.service lookup-domain.service mariadb.service milter-greylist.service mysql.service named.service nginx.service opendkim.service php*-fpm.service polkit.service postfix.service postgrey.service proftpd.service quotaon.service saslauthd.service spamd.service ssh.service sshd.service unattended-upgrades.service usermin.service webmin.service

View File

@@ -0,0 +1,4 @@
lines=100
others=1
reverse=1
extras_units=auditd.service chronyd.service crond.service dovecot.service dracut-shutdown.service fcgiwrap-*.service firewalld.service httpd.service kdump.service lm_sensors.service mariadb.service mysql.service named.service NetworkManager.service nginx.service php-fcgi-*.service php-fpm.service php*-php-fpm.service polkit.service postfix.service proftpd.service saslauthd.service sshd.service usermin.service webmin.service

View File

@@ -1,5 +1,6 @@
lines=Default number of lines to display,0,6
refresh=Seconds between log view refreshes,3,Never
others=Show logs from other modules?,1,1-Yes,0-No
extras_units=Extra units to show separate logs for,9,50,8,\t
extras=Extra log files to show,9,50,4,\t
reverse=Log display order,1,1-Newest lines at top,0-Newest lines at bottom

View File

@@ -13,6 +13,7 @@ if (!&has_command('journalctl')) {
}
# Display syslog rules
my @col0;
my @col1;
my @col2;
my @col3;
@@ -20,10 +21,12 @@ if ($access{'syslog'}) {
my @systemctl_cmds = &get_systemctl_cmds();
foreach $o (@systemctl_cmds) {
local @cols;
push(@cols, &text('index_cmd', "<tt>".$o->{'cmd'}."</tt>"));
push(@cols, $o->{'desc'});
push(@cols, &ui_link("view_log.cgi?idx=$o->{'id'}&view=1", $text{'index_view'}) );
push(@col1, \@cols);
push(@cols, &text('index_cmd', "<tt>".
&cleanup_destination($o->{'cmd'})."</tt>"));
push(@cols, &cleanup_description($o->{'desc'}));
push(@cols, &ui_link("view_log.cgi?idx=$o->{'id'}&view=1",
$text{'index_view'}) );
push(@col0, \@cols);
}
# System logs from other modules
@@ -73,6 +76,7 @@ if ($access{'syslog'}) {
"view_log.cgi?idx=syslog-ng-".
$dest->{'index'}."&"."view=1",
$text{'index_view'}) );
@cols = sort { $a->[2] cmp $b->[2] } @cols;
push(@col1, \@cols);
}
}
@@ -95,9 +99,10 @@ if ($config{'others'} && $access{'others'}) {
push(@cols, &text('index_cmd',
"<tt>".&html_escape($o->{'cmd'})."</tt>"));
}
push(@cols, &html_escape($o->{'desc'}));
push(@cols, $o->{'desc'} ? "&#x21FF;&nbsp; ".&html_escape($o->{'desc'}) : "");
push(@cols, &ui_link("view_log.cgi?oidx=$o->{'mindex'}".
"&omod=$o->{'mod'}&view=1", $text{'index_view'}) );
@cols = sort { $a->[2] cmp $b->[2] } @cols;
push(@col2, \@cols);
}
}
@@ -114,18 +119,18 @@ foreach $e (&extra_log_files()) {
push(@cols, &text('index_cmd',
"<tt>".&html_escape($e->{'cmd'})."</tt>"));
}
push(@cols, &html_escape($e->{'desc'}));
push(@cols, $e->{'desc'} ? "&#x21DD;&nbsp; ".&html_escape($e->{'desc'}) : "");
push(@cols, &ui_link("view_log.cgi?extra=".&urlize($e->{'file'} || $e->{'cmd'})."&view=1", $text{'index_view'}) );
@cols = sort { $a->[2] cmp $b->[2] } @cols;
push(@col3, \@cols);
}
# Print sorted table with logs files and commands
my @acols = (@col1, @col2, @col3);
my @acols = (@col0, @col1, @col2, @col3);
print &ui_columns_start( @acols ? [
$text{'index_to'},
$text{'index_rule'}, "" ] : [ ], 100);
if (@acols) {
@acols = sort { $a->[2] cmp $b->[2] } @acols;
foreach my $col (@acols) {
print &ui_columns_row($col);
}

View File

@@ -32,28 +32,123 @@ return 0;
sub get_systemctl_cmds
{
my $lines = $config{'lines'} || 1000;
return !&has_command('journalctl') ? () : (
{ 'cmd' => "journalctl --lines $lines -p alert..emerg",
'desc' => $text{'journal_journalctl_alert_emerg'},
'id' => "journal-1", },
{ 'cmd' => "journalctl --lines $lines -p err..crit",
'desc' => $text{'journal_journalctl_err_crit'},
'id' => "journal-2", },
{ 'cmd' => "journalctl --lines $lines -p notice..warning",
'desc' => $text{'journal_journalctl_notice_warning'},
'id' => "journal-3", },
{ 'cmd' => "journalctl --lines $lines -p debug..info",
'desc' => $text{'journal_journalctl_debug_info'},
'id' => "journal-4", },
{ 'cmd' => "journalctl --lines $lines -k ",
'desc' => $text{'journal_journalctl_dmesg'},
'id' => "journal-5", },
{ 'cmd' => "journalctl --lines $lines -x ",
'desc' => $text{'journal_expla_journalctl'},
'id' => "journal-6", },
my $journalctl_cmd = &has_command('journalctl');
return () if (!$journalctl_cmd);
my @rs = (
{ 'cmd' => "journalctl --lines $lines",
'desc' => $text{'journal_journalctl'},
'id' => "journal-1", },
{ 'cmd' => "journalctl --lines $lines -x ",
'desc' => $text{'journal_expla_journalctl'},
'id' => "journal-2", },
{ 'cmd' => "journalctl --lines $lines -p alert..emerg",
'desc' => $text{'journal_journalctl_alert_emerg'},
'id' => "journal-3", },
{ 'cmd' => "journalctl --lines $lines -p err..crit",
'desc' => $text{'journal_journalctl_err_crit'},
'id' => "journal-4", },
{ 'cmd' => "journalctl --lines $lines -p notice..warning",
'desc' => $text{'journal_journalctl_notice_warning'},
'id' => "journal-5", },
{ 'cmd' => "journalctl --lines $lines -p debug..info",
'desc' => $text{'journal_journalctl_debug_info'},
'id' => "journal-6", },
{ 'cmd' => "journalctl --lines $lines -k ",
'desc' => $text{'journal_journalctl_dmesg'},
'id' => "journal-7", } );
return @rs if (!$config{'extras_units'});
# Add more units from config if exists on the system
my (%ucache, %uread);
my $units_cache = "$module_config_directory/units.cache";
&read_file($units_cache, \%ucache);
if (!%ucache) {
my $out = &backquote_command(
"systemctl list-units --full --all ".
"-t service --no-legend");
foreach my $line (split(/\r?\n/, $out)) {
$line =~ s/^[^a-z0-9\-\_\.]+//i;
my ($unit, $desc) = (split(/\s+/, $line, 5))[0, 4];
$uread{$unit} = $desc;
}
}
# Add extra units
foreach my $unit (split(/\t+/, $config{'extras_units'})) {
my %units = %uread ? %uread : %ucache;
my ($eunit) = grep { $_ eq $unit } keys %units;
next if (!$eunit && $unit !~ /\*/);
# Units by wildcard
if ($unit =~ /\*/) {
my $unit_re = $unit;
$unit_re =~ s/\*/.*/g;
foreach my $u (keys %units) {
if ($u =~ /^$unit_re$/) {
push(@rs, { 'cmd' => "journalctl --lines ".
"$lines -u $u",
'desc' => "&#x25E6;&nbsp; ".
&fix_clashing_description(
$units{$u}, $u),
'id' => "journal-$u", });
$ucache{$u} = $units{$u};
}
}
next;
}
# Unit by name
my $desc = $units{$eunit} || $unit;
$desc =~ s/\.$//;
push(@rs, { 'cmd' => "journalctl --lines $lines -u $unit",
'desc' => "&#x25E6;&nbsp; ".
&fix_clashing_description($desc),
'id' => "journal-$unit", });
$ucache{$eunit} = $desc;
}
# Save cache
if (%uread) {
&lock_file($units_cache);
&write_file($units_cache, \%ucache);
&unlock_file($units_cache);
}
return @rs;
}
# clear_systemctl_cache()
# Clear the cache of systemctl units
sub clear_systemctl_cache
{
unlink("$module_config_directory/units.cache");
}
# cleanup_destination(cmd)
# Returns a destination of some command cleaned up for display
sub cleanup_destination
{
my $cmd = shift;
$cmd =~ s/--lines\s+\d+\s*//;
$cmd =~ s/\.service$//;
return $cmd;
}
# cleanup_description(desc)
# Returns a description cleaned up for display
sub cleanup_description
{
my $desc = shift;
$desc =~ s/\s+\(Virtualmin\)//;
return $desc;
}
# fix_clashing_description(description, service)
# Returns known clashing descriptions fixed
sub fix_clashing_description
{
my ($desc, $serv) = @_;
# EL systems name for PHP FastCGI Process Manager is repeated
if ($serv =~ /php(\d+)-php-fpm/) {
my $php_version = $1;
$php_version = join(".", split(//, $php_version));
$desc =~ s/PHP/PHP $php_version/;
}
return $desc;
}
# all_log_files(file)
@@ -138,5 +233,12 @@ foreach my $f (@rv) {
return @rv;
}
# config_post_save
# Called after the module's configuration has been saved
sub config_post_save
{
&clear_systemctl_cache();
}
1;