#!/usr/local/bin/perl
#
#pglog-rotator
#Copyright (c) Liberty RMS 2001-2003
#This file may be distributed under the same terms as PostgreSQL
#This file comes with NO WARRANTY WHATSOEVER
#
#

use IPC::Open3;
use IO::Handle;

$err_log_file='/path/to/logs/stderr_pg.log';
$out_log_file='/path/to/logs/stdout_pg.log';

#### log size in MBytes
$size_limit=1;

#### rotate nn files
$max_logs=7;

#### postgres cmd
# it is best if you set $PGDATA
# and use the $PATH to call just postmaster.
# That makes the output of 'ps -auxww' more valuable
$command = 'postmaster';


#######
sub HUP_SIGNAL {
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
	$gmtime = sprintf ("%.2d/%.2d/%.4d %.2d:%.2d:%.2d: ",  $mon+1, $mday, 1900+$year, $hour, $min, $sec);
        print "$gmtime: SIGHUP received. Ignored.\n";
}
$SIG{HUP} = \&HUP_SIGNAL;


open(LOG, ">>$err_log_file");
autoflush LOG 1;
open(OUT_LOG, ">>$out_log_file");
autoflush OUT_LOG 1;

$cnt = $max_logs;
$size_limit=$size_limit * 1024 * 1024;

### postgres 7.1.3 writes to stderr in any debug_level (0 to 16)
sub read_stderr
{
    while(<ERRFH>)
    {
	($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($err_log_file);
	if ( $size > $size_limit ) {
		close LOG;

		while ($cnt > 0) {
			$old_log=sprintf("%s.%s", $err_log_file, $cnt);
			$new_log=sprintf("%s.%s", $err_log_file, $cnt-1);
			rename $new_log, $old_log;
			$cnt--;
		}
		rename $err_log_file, $new_log;
		$cnt = $max_logs;
		open(LOG, ">>$err_log_file");
	}
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
	$gmtime = sprintf ("%.2d/%.2d/%.4d %.2d:%.2d:%.2d: ",  $mon+1, $mday, 1900+$year, $hour, $min, $sec);
	print LOG "$gmtime $_";
    }

}

### postgres 7.1.3 writes to stdout in debug_level 3 to 16
sub read_stdout
{
    while(<RDRFH>)
    {
	($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($out_log_file);
	if ( $size > $size_limit ) {
		close OUT_LOG;

		while ($cnt > 0) {
			$old_log=sprintf("%s.%s", $out_log_file, $cnt);
			$new_log=sprintf("%s.%s", $out_log_file, $cnt-1);
			rename $new_log, $old_log;
			$cnt--;
		}
		rename $out_log_file, $new_log;
		$cnt = $max_logs;
		open(OUT_LOG, ">>$out_log_file");
	}
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
	$gmtime = sprintf ("%.2d/%.2d/%.4d %.2d:%.2d:%.2d: ",  $mon+1, $mday, 1900+$year, $hour, $min, $sec);
	print OUT_LOG "$gmtime $_";
    }

}


$pid = open3(\*WTRFH, \*RDRFH, \*ERRFH, $command);

printf "postmaster [$pid] started: ";

print "$command\n";
print "STDERR log file: $err_log_file\n";
print "STDOUT log file: $out_log_file\n";
printf ("size limit: %.3f MBytes, ", $size_limit / 1024 / 1024); 
print "max logs: $max_logs\n";


# read stdout from postmaster
if (fork() == 0) {	## this is the child
	read_stdout();
	exit(0);
}

read_stderr();

printf "postmaster [$pid] killed.\n\n";

