Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Ubuntu 10.4 Server.

I have a dumb non-interactive legacy service which is running constantly on my server.

It is writing its log to a file with fixed name (/var/log/something.log).

It does not handle any signals to let go of the log file. I need to rotate that log file.

Is there a way to do this properly without changing the application and without losing any data in the log?

share|improve this question
add comment

4 Answers

up vote 5 down vote accepted

Ignacio's answer intrigued me so I did some research and came up with the Perl script below. If your service will write to a named pipe it should work and be usable with logrotate.

For it to work you need to make your logfile into a named pipe. Rename the existing file then

mkfifo /var/log/something.log

and to edit the 3 filenames to meet your requirements. Run your service then this daemon which should read the named pipe and write it to a new logfile.

If you rename /var/log/somethingrotateable.log then send a HUP to the daemon it will spawn itself and create a new somethingrotateable.log to write to. If using logrotate a postrotate script of kill -HUP 'cat /var/run/yourpidfile.pid'

#!/usr/bin/perl -w
use POSIX ();
use FindBin ();
use File::Basename ();
use File::Spec::Functions;
#
$|=1;
#
# Change the 3 filenames and paths below to meet your requirements.
#
my $FiFoFile = '/var/log/something.log';
my $LogFile = '/var/log/somethingrotateable.log';
my $PidFile = '/var/run/yourpidfile.pid';

# # make the daemon cross-platform, so exec always calls the script
# # itself with the right path, no matter how the script was invoked.
my $script = File::Basename::basename($0);
my $SELF = catfile $FindBin::Bin, $script;
#
# # POSIX unmasks the sigprocmask properly
my $sigset = POSIX::SigSet->new();
my $action = POSIX::SigAction->new('sigHUP_handler',$sigset,&POSIX::SA_NODEFER);
POSIX::sigaction(&POSIX::SIGHUP, $action);

sub sigHUP_handler {
#    print "Got SIGHUP";
    exec($SELF, @ARGV) or die "Couldn't restart: $!\n";
   }

#open the logfile to write to
open(LOGFILE, ">>$LogFile") or die "Can't open $LogFile";
open(PIDFILE, ">$PidFile") or die "Can't open PID File $PidFile";
print PIDFILE "$$\n";
close PIDFILE;
readLog();

sub readLog {
sysopen(FIFO, $FiFoFile,0)  or die "Can't open $FiFoFile";
while ( my $LogLine = <FIFO>) {
    print LOGFILE $LogLine;
   }
}
share|improve this answer
add comment

Log to a FIFO, then run a daemon that connects to the other side of the FIFO and has signal handlers that allow you to rotate the log.

share|improve this answer
add comment

You could try to let the application log to a named pipe and have some program (for example syslog-ng) that supports proper log rotation mechanisms read the log entries and log them to a file.

share|improve this answer
add comment

Send SIGSTOP to the process, copy the log to another name, truncate the log, send SIGCONT to the process, perhaps like this:

pkill -STOP legacyappname
cp /var/log/something.log /var/log/something.log.backup
cat /dev/null > /var/log/something.log
pkill -CONT legacyappname

You could also have logrotate do the magic for you with carefully crafted pre and post rotation scripts and the copytruncate option, like so:

/var/log/something {
    daily
    rotate 5
    copytruncate
    prerotate
        # This assumes you have a pid file, of course.
        # If you don't, this could instead be a pkill like above.
        kill -STOP `cat /var/run/legacyappname.pid`
    endscript
    postrotate
        kill -CONT `cat /var/run/legacyappname.pid`
    endscript
}
share|improve this answer
    
Interesting option, thanks. What will happen with socket connections to the app and from it during the stop? I'm worried about disconnects. –  Alexander Gladysh Oct 11 '10 at 19:02
    
Also, the app is being run under runit. What will its monitor do if the app process is stopped? –  Alexander Gladysh Oct 11 '10 at 19:03
    
The behavior of the connections would depend on the timeout they are set with and the time it takes to do the actual rotation. I wouldn't imagine that you'd run into any trouble there unless the logs are enormous. I don't have any experience with runit so I couldn't tell you how the monitor will react to stopping the process. –  mark Oct 12 '10 at 11:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.