#!/usr/bin/perl
use strict;BEGIN {
# execute get_alarm on SIG{ALRM}...
$SIG{ALRM} = \&get_alarm;
# trigger alarm...
alarm(60);
}
# load package for command line arguments (GetOptions)...
use Getopt::Long;
# load package for file handling (dirname)...
use File::Basename;
# define variables...
use vars qw( $opt_V $opt_p $opt_s $opt_t $opt_h $file );
# define command line arguments...
Getopt::Long::Configure('bundling');
GetOptions
( "V" => \$opt_V, "version" => \$opt_V,
"p=s" => \$opt_p, "period=s" => \$opt_p,
"t=i" => \$opt_t, "tzone=i" => \$opt_t,
"s=s" => \$opt_s, "symlink=s" => \$opt_s,
"h" => \$opt_h, "help" => \$opt_h );
# default time shift is 0 if opt_t is not defined...
$opt_t=0 if ( !$opt_t );
# ****************************************************************
# check cammandline arguments...
# display help or usage...
if ( $opt_h ) {
print "<STDIN> | cronolog --symlink|-s /path/to/symlink [ --tzone|-t <time shift> --period|";
print "-p 1day --help|-h --version|-V ] /path/to/logfile-\%Y-\%m-\%d.log\n\n";
print "\t--symlink|-s /path/to/symlink (requiered)\n";
print "\t--tzone|-t int (-12..+12) (default 0)\n";
print "\t--period|-p rotation period (not in use, we rotate at 00:00)\n";
print "\t--help|-h display this screen\n";
print "\t--version|-V display version\n\n";
exit 0;
}
# print out a cronolog version...
if ( $opt_V ) {
print "cronolog version 1.7.0\n";
exit 0;
}
# error message if no logifle defined...
if ( !$ARGV[-1] ) {
print "cronolog: No logfile defined.\n";
exit 1;
}
# define error message if logfile directory is not writable...
if ( ! -w dirname( $ARGV[-1] ) ) {
print "cronolog: Can't create logfile -".$ARGV[-1]."- becouse the directory is not writable.\n";
exit 1;
}
# error message if no symlink defined...
if ( !$opt_s ) {
print "cronolog: No symlink defined.\n";
exit 1;
}
# define error message if symlink directory is not writable...
if ( ! -w dirname( $opt_s ) ) {
print "cronolog: Can't create symlink -".$opt_s."- becouse the directory is not writable.\n";
exit 1;
}
# ****************************************************************
# program action...
# loop STDIN...
while (<STDIN>) {
# get current filename from template...
$file=get_filename($ARGV[-1]);
# flush buffer...
$|=1;
# write data from STDIN...
open (DAT, ">>$file") or die( "Can't open -".$file."-: ".$! );
print DAT $_;
close(DAT);
}
# ****************************************************************
# return logfile name from logfile template...
sub get_filename {
my $filename=shift;
# get date as array reference( YYYY, MM, DD, HH, MM, SS )...
my $ref_date = date( $opt_t );
# replace spaceholder ( %Y, %m, %d, %H, %M, %S => strftime )...
$filename =~ s!\%Y!$ref_date->[0]!g;
$filename =~ s!\%m!$ref_date->[1]!g;
$filename =~ s!\%d!$ref_date->[2]!g;
$filename =~ s!\%H!$ref_date->[3]!g;
$filename =~ s!\%M!$ref_date->[4]!g;
$filename =~ s!\%S!$ref_date->[5]!g;
return $filename;
}
# ****************************************************************
# function on signal handler...
sub get_alarm {
my $symlink=$opt_s;
# get target file of the symlink...
my $target = readlink( $symlink );
# create new file if not exists...
if ( ! -f $file ) {
open (DAT, ">$file") or die( "Can't open -".$file."-: ".$! );
close(DAT);
}
# remove symlink if target file and current logfile not equal...
if ( $target ne $file ) {
# remove symlink only if exists...
unlink( "$symlink" ) or die( "Can't remove symlink: ".$! ) if ( -l $symlink );
}
# create symlink to current logfile if no symlink exists...
symlink( "$file", "$symlink" ) or die( "Can't create symlink: ".$! ) if ( ! -l $symlink );
# trigger new alarm...
alarm(60);
}
# ****************************************************************
# return date as array ( %Y, %m, %d, %H, %M, %S => strftime )...
sub date {
my $tzone=shift;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time+($tzone*3600));
$year = 1900+$year;
$mon = $mon+1;
$sec = sprintf( "%02d", $sec );
$min = sprintf( "%02d", $min );
$hour = sprintf( "%02d", $hour );
$mon = sprintf( "%02d", $mon );
$mday = sprintf( "%02d", $mday );
my @date=( $year, $mon, $mday, $hour, $min, $sec );
return \@date;
}
# ****************************************************************
# end of this script...