mirror of
https://github.com/webmin/webmin.git
synced 2026-02-03 14:13:29 +00:00
Add support for additional units in systemd log viewer
This commit is contained in:
4
logviewer/config-debian-linux
Normal file
4
logviewer/config-debian-linux
Normal 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
|
||||
4
logviewer/config-redhat-linux
Normal file
4
logviewer/config-redhat-linux
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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'} ? "⇿ ".&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'} ? "⇝ ".&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);
|
||||
}
|
||||
|
||||
@@ -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' => "◦ ".
|
||||
&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' => "◦ ".
|
||||
&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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user