summaryrefslogtreecommitdiff
path: root/scripts/system/vyatta_update_syslog.pl
diff options
context:
space:
mode:
authorJames Davidson <james.davidson@vyatta.com>2012-04-05 17:52:08 -0700
committerJames Davidson <james.davidson@vyatta.com>2012-04-18 11:04:44 -0700
commit2415dea5aa5ecc1542b3da7795c0b7c49b98f259 (patch)
tree75c34b1c20ebbcf0dec9689bbb702f116363cc26 /scripts/system/vyatta_update_syslog.pl
parentf329c52b1d835aee551e2002e25937ed9447eb7d (diff)
downloadvyatta-cfg-system-2415dea5aa5ecc1542b3da7795c0b7c49b98f259.tar.gz
vyatta-cfg-system-2415dea5aa5ecc1542b3da7795c0b7c49b98f259.zip
Use rsyslog to trigger log rotation
The previous implementation of log rotation used an hourly cron job to check log file size and possibly perform a rotation. If the logging rate is high, this interval may allow for root file system space exhustion. Utilizing rsyslog's outchannel mechanism enables log rotation to be initiated as soon as the log file becomes larger than its configured size. Fixes Bug 7807.
Diffstat (limited to 'scripts/system/vyatta_update_syslog.pl')
-rwxr-xr-xscripts/system/vyatta_update_syslog.pl86
1 files changed, 69 insertions, 17 deletions
diff --git a/scripts/system/vyatta_update_syslog.pl b/scripts/system/vyatta_update_syslog.pl
index 1c4c6d46..3421d61a 100755
--- a/scripts/system/vyatta_update_syslog.pl
+++ b/scripts/system/vyatta_update_syslog.pl
@@ -23,22 +23,42 @@
use strict;
use lib "/opt/vyatta/share/perl5";
use Vyatta::Config;
+use File::Basename;
use File::Compare;
+use File::Temp qw/ tempfile /;
my $SYSLOG_CONF = '/etc/rsyslog.d/vyatta-log.conf';
-my $SYSLOG_TMP = "/tmp/rsyslog.conf.$$";
-my $MESSAGES = '-/var/log/messages';
+my $SYSLOG_TMPL = "/tmp/rsyslog.conf.XXXXXX";
+my $MESSAGES = '/var/log/messages';
my $CONSOLE = '/dev/console';
+my $LOGROTATE_CFG_DIR = '/opt/vyatta/etc/logrotate';
my %entries = ();
die "$0 expects no arguments\n" if (@ARGV);
-sub add_entry {
+sub add_target_selector {
my ( $selector, $target ) = @_;
- $entries{$target} = [] unless $entries{$target};
- push @{ $entries{$target} }, $selector;
+ $entries{$target}{selector} = [] unless $entries{$target}{selector};
+ push @{ $entries{$target}{selector} }, $selector;
+}
+
+sub set_target_param {
+ my ( $config, $level, $target, $param ) = @_;
+ my $path = "$level archive $param";
+
+ if (! $config->exists($path)) {
+ my @tmpl = $config->parseTmpl($path);
+ $entries{$target}{$param} = $tmpl[2];
+ } else {
+ $entries{$target}{$param} = $config->returnValue($path);
+ }
+}
+
+sub get_target_param {
+ my ( $target, $param ) = @_;
+ return $entries{$target}{$param};
}
# This allows overloading local values in CLI
@@ -57,10 +77,25 @@ sub read_config {
$facility = $facmap{$facility} if ( $facmap{$facility} );
$loglevel = '*' if ( $loglevel eq 'all' );
- add_entry( $facility . '.' . $loglevel, $target );
+ $entries{$target} = {} unless $entries{$target};
+ add_target_selector( $facility . '.' . $loglevel, $target );
+ }
+
+ # This is a file target so we set size and files
+ if ($target =~ m:^/var/log/:) {
+ set_target_param($config, $level, $target, 'size');
+ set_target_param($config, $level, $target, 'files');
}
}
+sub print_outchannel {
+ my ( $fh, $channel, $target, $size ) = @_;
+ # Force outchannel size to be 1k more than logrotate config to guarantee rotation
+ $size = ($size + 5) * 1024;
+ print $fh "\$outchannel $channel,$target,$size,/usr/sbin/logrotate ${LOGROTATE_CFG_DIR}/$channel\n";
+ print $fh join( ';', @{ $entries{$target}{selector} } ), " \$$channel\n";
+}
+
my $config = new Vyatta::Config;
$config->setLevel("system syslog");
@@ -68,8 +103,8 @@ read_config( $config, 'global', $MESSAGES );
# Default syslog.conf if no global entry
unless (%entries) {
- add_entry( '*.notice', $MESSAGES );
- add_entry( 'local7.*', $MESSAGES );
+ add_target_selector( '*.notice', $MESSAGES );
+ add_target_selector( 'local7.*', $MESSAGES );
}
read_config( $config, 'console', $CONSOLE );
@@ -86,23 +121,40 @@ foreach my $user ( $config->listNodes('user') ) {
read_config( $config, 'user $user', $user );
}
-open my $out, '>', $SYSLOG_TMP
- or die "Can't open $SYSLOG_TMP: $!";
+my ($out, $tempname) = tempfile($SYSLOG_TMPL, UNLINK => 1)
+ or die "Can't create temp file: $!";
+my $files;
+my $size;
foreach my $target ( keys %entries ) {
- print $out join( ';', @{ $entries{$target} } ), "\t$target\n";
+ if ($target eq $MESSAGES) {
+ $size = get_target_param($target, 'size');
+ $files = get_target_param($target, 'files');
+ print_outchannel($out, 'global', $target, $size);
+ system("sudo /opt/vyatta/sbin/vyatta_update_logrotate.pl $files $size 1") == 0
+ or die "Can't genrate global log rotation config: $!";
+ } elsif ($target =~ m:^/var/log/user/:) {
+ my $file = basename($target);
+ $size = get_target_param($target, 'size');
+ $files = get_target_param($target, 'files');
+ print_outchannel($out, 'file_' . $file, $target, $size);
+ system("sudo /opt/vyatta/sbin/vyatta_update_logrotate.pl $file $files $size 1") == 0
+ or die "Can't genrate global log rotation config: $!";
+ } else {
+ print $out join( ';', @{ $entries{$target}{selector} } ), "\t$target\n";
+ }
}
close $out
- or die "Can't output $SYSLOG_TMP: $!";
+ or die "Can't output $tempname: $!";
# Don't need to do anything, save time on boot
-if ( -e $SYSLOG_CONF && compare( $SYSLOG_CONF, $SYSLOG_TMP ) == 0 ) {
- unlink($SYSLOG_TMP);
+if ( -e $SYSLOG_CONF && compare( $SYSLOG_CONF, $tempname ) == 0 ) {
+ unlink($tempname);
exit 1;
}
-system("sudo cp $SYSLOG_TMP $SYSLOG_CONF") == 0
- or die "Can't copy $SYSLOG_TMP to $SYSLOG_CONF";
+system("sudo cp $tempname $SYSLOG_CONF") == 0
+ or die "Can't copy $tempname to $SYSLOG_CONF: $!";
-unlink($SYSLOG_TMP);
+unlink($tempname);
exit 0;