[#171] Log files now rotate at 10MB up to seven times

This commit is contained in:
Oliver Gorwits
2015-01-24 18:59:08 +00:00
parent 2d48243326
commit 8305f9bf0b
3 changed files with 108 additions and 14 deletions

View File

@@ -1,3 +1,9 @@
2.030001 - 2015-01-08
[NEW FEATURES]
* [#171] Log files now rotate at 10MB up to seven times
2.030000 - 2015-01-08 2.030000 - 2015-01-08
[NEW FEATURES] [NEW FEATURES]

View File

@@ -41,6 +41,7 @@ BEGIN {
use Daemon::Control; use Daemon::Control;
use Filesys::Notify::Simple; use Filesys::Notify::Simple;
use File::Copy;
use App::Netdisco::Environment; use App::Netdisco::Environment;
my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml'; my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml';
@@ -50,6 +51,7 @@ my @args = (scalar @ARGV > 1 ? @ARGV[1 .. $#ARGV] : ());
my $log_dir = dir($home, 'logs'); my $log_dir = dir($home, 'logs');
mkdir $log_dir if ! -d $log_dir; mkdir $log_dir if ! -d $log_dir;
my $log_file = file($log_dir, 'netdisco-daemon.log');
my $uid = (stat($netdisco->stringify))[4] || 0; my $uid = (stat($netdisco->stringify))[4] || 0;
my $gid = (stat($netdisco->stringify))[5] || 0; my $gid = (stat($netdisco->stringify))[5] || 0;
@@ -59,25 +61,26 @@ Daemon::Control->new({
program => \&restarter, program => \&restarter,
program_args => [@args], program_args => [@args],
pid_file => file($home, 'netdisco-daemon.pid'), pid_file => file($home, 'netdisco-daemon.pid'),
stderr_file => file($log_dir, 'netdisco-daemon.log'), stderr_file => $log_file,
stdout_file => file($log_dir, 'netdisco-daemon.log'), stdout_file => $log_file,
redirect_before_fork => 0, redirect_before_fork => 0,
uid => $uid, gid => $gid, uid => $uid, gid => $gid,
})->run; })->run;
# the guts of this are borrowed from Plack::Loader::Restarter - many thanks!! # the guts of this are borrowed from Plack::Loader::Restarter - many thanks!!
my $child = 0;
sub restarter { sub restarter {
my ($daemon, @program_args) = @_; my ($daemon, @program_args) = @_;
$0 = 'netdisco-daemon'; $0 = 'netdisco-daemon';
my $child = fork_and_start($daemon, @program_args); $child = fork_and_start($daemon, @program_args);
exit(1) unless $child; exit(1) unless $child;
my $watcher = Filesys::Notify::Simple->new([$ENV{DANCER_ENVDIR}]); my $watcher = Filesys::Notify::Simple->new([$ENV{DANCER_ENVDIR}, $log_dir]);
warn "config watcher: watching $ENV{DANCER_ENVDIR} for updates.\n"; warn "config watcher: watching $ENV{DANCER_ENVDIR} for updates.\n";
local $SIG{TERM} = sub { signal_child('TERM', $child); exit(0); }; local $SIG{TERM} = sub { $child = signal_child('TERM', $child); exit(0); };
while (1) { while (1) {
my @restart; my @restart;
@@ -85,19 +88,33 @@ sub restarter {
# this is blocking # this is blocking
$watcher->wait(sub { $watcher->wait(sub {
my @events = @_; my @events = @_;
@events = grep {file($_->{path})->basename eq $config} @events; @events = grep {$_->{path} eq $log_file or
file($_->{path})->basename eq $config} @events;
return unless @events; return unless @events;
@restart = @events; @restart = @events;
}); });
my ($hupit, $rotate) = (0, 0);
next unless @restart; next unless @restart;
warn "-- $_->{path} updated.\n" for @restart;
foreach my $f (@restart) {
if ($f->{path} eq $log_file) {
++$rotate;
}
else {
warn "-- $f->{path} updated.\n";
++$hupit;
}
}
rotate_logs($child, $daemon, @program_args) if $rotate;
if ($hupit) {
signal_child('TERM', $child); signal_child('TERM', $child);
$child = fork_and_start($daemon, @program_args); $child = fork_and_start($daemon, @program_args);
exit(1) unless $child; exit(1) unless $child;
} }
} }
}
sub fork_and_start { sub fork_and_start {
my ($daemon, @daemon_args) = @_; my ($daemon, @daemon_args) = @_;
@@ -121,6 +138,36 @@ sub signal_child {
waitpid($pid, 0); waitpid($pid, 0);
} }
sub rotate_logs {
my $child = shift;
return unless (-f $log_file) and
((-s $log_file) > (10 * 1024768));
my @files = glob file($log_dir, '*');
foreach my $f (reverse sort @files) {
next unless $f =~ m/$log_file\.(\d)$/;
my $pos = $1;
unlink $f if $pos == 7;
my $next = $pos + 1;
(my $newf = $f) =~ s/\.$pos$/.$next/;
rename $f, $newf;
}
# if the log file's about 10M then the race condition in copy/truncate
# has a low probability. if the file's larger, then we rename and kill
if ((-s $log_file) > (11 * 1024768)) {
rename $log_file, $log_file .'.1';
signal_child('TERM', $child);
$child = fork_and_start(@_);
exit(1) unless $child;
}
else {
copy $log_file, $log_file .'.1';
truncate $log_file, 0;
}
}
=head1 NAME =head1 NAME
netdisco-daemon - Job Control Daemon for Netdisco netdisco-daemon - Job Control Daemon for Netdisco

View File

@@ -42,6 +42,7 @@ BEGIN {
use Daemon::Control; use Daemon::Control;
use Filesys::Notify::Simple; use Filesys::Notify::Simple;
use IO::File; use IO::File;
use File::Copy;
use App::Netdisco::Environment; use App::Netdisco::Environment;
my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml'; my $config = ($ENV{PLACK_ENV} || $ENV{DANCER_ENVIRONMENT}) .'.yml';
@@ -92,7 +93,7 @@ sub restarter {
my $child = fork_and_start($daemon, @program_args); my $child = fork_and_start($daemon, @program_args);
exit(1) unless $child; exit(1) unless $child;
my $watcher = Filesys::Notify::Simple->new([$ENV{DANCER_ENVDIR}]); my $watcher = Filesys::Notify::Simple->new([$ENV{DANCER_ENVDIR}, $log_dir]);
warn "config watcher: watching $ENV{DANCER_ENVDIR} for updates.\n"; warn "config watcher: watching $ENV{DANCER_ENVDIR} for updates.\n";
# TODO: starman also supports TTIN,TTOU,INT,QUIT # TODO: starman also supports TTIN,TTOU,INT,QUIT
@@ -105,15 +106,27 @@ sub restarter {
# this is blocking # this is blocking
$watcher->wait(sub { $watcher->wait(sub {
my @events = @_; my @events = @_;
@events = grep {file($_->{path})->basename eq $config} @events; @events = grep {$_->{path} eq $log_file or
file($_->{path})->basename eq $config} @events;
return unless @events; return unless @events;
@restart = @events; @restart = @events;
}); });
my ($hupit, $rotate) = (0, 0);
next unless @restart; next unless @restart;
warn "-- $_->{path} updated.\n" for @restart;
signal_child('HUP', $child); foreach my $f (@restart) {
if ($f->{path} eq $log_file) {
++$rotate;
}
else {
warn "-- $f->{path} updated.\n";
++$hupit;
}
}
rotate_logs($child) if $rotate;
signal_child('HUP', $child) if $hupit;
} }
} }
@@ -139,6 +152,34 @@ sub signal_child {
waitpid($pid, 0); waitpid($pid, 0);
} }
sub rotate_logs {
my $child = shift;
return unless (-f $log_file) and
((-s $log_file) > (10 * 1024768));
my @files = glob file($log_dir, '*');
foreach my $f (reverse sort @files) {
next unless $f =~ m/$log_file\.(\d)$/;
my $pos = $1;
unlink $f if $pos == 7;
my $next = $pos + 1;
(my $newf = $f) =~ s/\.$pos$/.$next/;
rename $f, $newf;
}
# if the log file's about 10M then the race condition in copy/truncate
# has a low probability. if the file's larger, then we rename and kill
if ((-s $log_file) > (15 * 1024768)) {
rename $log_file, $log_file .'.1';
signal_child('HUP', $child);
}
else {
copy $log_file, $log_file .'.1';
truncate $log_file, 0;
}
}
=head1 NAME =head1 NAME
netdisco-web - Web Application Server for Netdisco netdisco-web - Web Application Server for Netdisco