diff options
author | James Davidson <james.davidson@vyatta.com> | 2012-04-05 17:52:08 -0700 |
---|---|---|
committer | James Davidson <james.davidson@vyatta.com> | 2012-04-18 11:04:44 -0700 |
commit | 2415dea5aa5ecc1542b3da7795c0b7c49b98f259 (patch) | |
tree | 75c34b1c20ebbcf0dec9689bbb702f116363cc26 | |
parent | f329c52b1d835aee551e2002e25937ed9447eb7d (diff) | |
download | vyatta-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.
-rw-r--r-- | Makefile.am | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | debian/vyatta-cfg-system.postinst.in | 1 | ||||
-rwxr-xr-x | scripts/system/vyatta_update_logrotate.pl | 20 | ||||
-rwxr-xr-x | scripts/system/vyatta_update_syslog.pl | 86 | ||||
-rw-r--r-- | sysconf/logrotate_messages | 9 | ||||
-rw-r--r-- | templates/system/syslog/file/node.tag/archive/files/node.def | 4 | ||||
-rw-r--r-- | templates/system/syslog/file/node.tag/archive/node.def | 3 | ||||
-rw-r--r-- | templates/system/syslog/file/node.tag/archive/size/node.def | 4 | ||||
-rw-r--r-- | templates/system/syslog/global/archive/files/node.def | 4 | ||||
-rw-r--r-- | templates/system/syslog/global/archive/node.def | 4 | ||||
-rw-r--r-- | templates/system/syslog/global/archive/size/node.def | 4 | ||||
-rw-r--r-- | templates/system/syslog/node.def | 2 |
12 files changed, 84 insertions, 58 deletions
diff --git a/Makefile.am b/Makefile.am index 7a7559f7..3998a990 100644 --- a/Makefile.am +++ b/Makefile.am @@ -91,7 +91,6 @@ bin_sudo_users_SCRIPTS = scripts/keepalived/vyatta-clear-vrrp.pl bin_sudo_users_SCRIPTS += scripts/keepalived/vyatta-show-vrrp.pl sysconf_DATA += sysconf/LICENSE -sysconf_DATA += sysconf/logrotate_messages sysconf_DATA += sysconf/issue sysconf_DATA += sysconf/issue.net sysconf_DATA += sysconf/motd.tail diff --git a/debian/vyatta-cfg-system.postinst.in b/debian/vyatta-cfg-system.postinst.in index 36644e7a..3f75d6d7 100644..100755 --- a/debian/vyatta-cfg-system.postinst.in +++ b/debian/vyatta-cfg-system.postinst.in @@ -129,6 +129,7 @@ mkdir -p /opt/vyatta/etc/config/user-data mkdir -p /opt/vyatta/etc/config/support chown -R root:vyattacfg /opt/vyatta/etc/config chmod -R 775 /opt/vyatta/etc/config +mkdir -p /opt/vyatta/etc/logrotate # create /opt/vyatta/etc/config/scripts/vyatta-postconfig-bootup.script # this should be after 'mkdir -p /opt/vyatta/etc/config/scripts' above diff --git a/scripts/system/vyatta_update_logrotate.pl b/scripts/system/vyatta_update_logrotate.pl index a3a879ba..05867658 100755 --- a/scripts/system/vyatta_update_logrotate.pl +++ b/scripts/system/vyatta_update_logrotate.pl @@ -1,17 +1,25 @@ #!/usr/bin/perl +# Exit code: +# 0 - success +# 1 - missing parameter +# 2 - invalid files or size parameters +# 3 - unable to write logrotate config + use strict; -my $file = "messages"; +my $cfg_dir = "/opt/vyatta/etc/logrotate"; +my $file = "global"; my $log_file = "/var/log/messages"; +my $log_conf = "${cfg_dir}/$file"; if ($#ARGV == 3) { $file = shift; $log_file = "/var/log/user/$file"; + $log_conf = "${cfg_dir}/file_$file"; } my $files = shift; my $size = shift; my $set = shift; -my $log_conf = "/etc/logrotate.d/$file"; if (!defined($files) || !defined($size) || !defined($set)) { exit 1; @@ -25,7 +33,7 @@ if (!($files =~ m/^\d+$/) || !($size =~ m/^\d+$/)) { # (the detection mechanism in XORP doesn't work anyway) unlink $log_conf; -open my $out, '>>', $log_conf +open my $out, '>', $log_conf or exit 3; if ($set == 1) { print $out <<EOF; @@ -34,13 +42,9 @@ $log_file { notifempty rotate $files size=${size}k - postrotate - invoke-rc.d rsyslog reload >/dev/null - endscript } EOF } close $out; -exec '/usr/sbin/invoke-rc.d', 'rsyslog', 'restart'; -exit 4; +exit 0; 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; diff --git a/sysconf/logrotate_messages b/sysconf/logrotate_messages deleted file mode 100644 index 7ffa559b..00000000 --- a/sysconf/logrotate_messages +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/messages { - missingok - notifempty - rotate 10 - size=1000k - postrotate - invoke-rc.d rsyslog reload >/dev/null - endscript -} diff --git a/templates/system/syslog/file/node.tag/archive/files/node.def b/templates/system/syslog/file/node.tag/archive/files/node.def index 09eea916..bb60506c 100644 --- a/templates/system/syslog/file/node.tag/archive/files/node.def +++ b/templates/system/syslog/file/node.tag/archive/files/node.def @@ -3,7 +3,3 @@ type: u32 help: Number of saved files default: 5 - -update: - sudo sh -c "/opt/vyatta/sbin/vyatta_update_logrotate.pl \ - '$VAR(../../@)' '$VAR(@)' '$VAR(../size/@)' 1" diff --git a/templates/system/syslog/file/node.tag/archive/node.def b/templates/system/syslog/file/node.tag/archive/node.def index 873cd0a6..0e7f6b3e 100644 --- a/templates/system/syslog/file/node.tag/archive/node.def +++ b/templates/system/syslog/file/node.tag/archive/node.def @@ -1,5 +1,4 @@ help: Log file size and rotation characteristics delete: - sudo sh -c "/opt/vyatta/sbin/vyatta_update_logrotate.pl \ - '$VAR(../@)' '$VAR(files/@)' '$VAR(size/@)' 0" + sudo rm -f "/opt/vyatta/etc/logrotate/file_$VAR(../@)" diff --git a/templates/system/syslog/file/node.tag/archive/size/node.def b/templates/system/syslog/file/node.tag/archive/size/node.def index f3e7e52f..0c9a1f7e 100644 --- a/templates/system/syslog/file/node.tag/archive/size/node.def +++ b/templates/system/syslog/file/node.tag/archive/size/node.def @@ -3,7 +3,3 @@ type: u32 help: Size of log files (kbytes) default: 0 - -update: - sudo sh -c "/opt/vyatta/sbin/vyatta_update_logrotate.pl \ - '$VAR(../../@)' '$VAR(../files/@)' '$VAR(@)' 1" diff --git a/templates/system/syslog/global/archive/files/node.def b/templates/system/syslog/global/archive/files/node.def index d4e8af82..bb60506c 100644 --- a/templates/system/syslog/global/archive/files/node.def +++ b/templates/system/syslog/global/archive/files/node.def @@ -3,7 +3,3 @@ type: u32 help: Number of saved files default: 5 - -update: - sudo sh -c "/opt/vyatta/sbin/vyatta_update_logrotate.pl \ - '$VAR(@)' '$VAR(../size/@)' 1" diff --git a/templates/system/syslog/global/archive/node.def b/templates/system/syslog/global/archive/node.def index 82bc9e86..2ec10727 100644 --- a/templates/system/syslog/global/archive/node.def +++ b/templates/system/syslog/global/archive/node.def @@ -1,5 +1 @@ help: Log file size and rotation characteristics - -delete: - sudo sh -c "/opt/vyatta/sbin/vyatta_update_logrotate.pl \ - '$VAR(files/@)' '$VAR(size/@)' 0" diff --git a/templates/system/syslog/global/archive/size/node.def b/templates/system/syslog/global/archive/size/node.def index 341f4a5b..4d360a44 100644 --- a/templates/system/syslog/global/archive/size/node.def +++ b/templates/system/syslog/global/archive/size/node.def @@ -3,7 +3,3 @@ type: u32 help: Size of log files (kbytes) default: 250 - -update: - sudo sh -c "/opt/vyatta/sbin/vyatta_update_logrotate.pl \ - '$VAR(../files/@)' '$VAR(@)' 1" diff --git a/templates/system/syslog/node.def b/templates/system/syslog/node.def index 81fb3f6c..ebe02232 100644 --- a/templates/system/syslog/node.def +++ b/templates/system/syslog/node.def @@ -1,5 +1,5 @@ priority: 400 help: System logging daemon end: if /opt/vyatta/sbin/vyatta_update_syslog.pl; then - sudo /usr/sbin/invoke-rc.d rsyslog restart + sudo /usr/sbin/invoke-rc.d rsyslog reload || sudo /usr/sbin/invoke-rc.d rsyslog restart fi |