The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Perl Programming
|
Perl script log rotate with zip
Discuss Perl script log rotate with zip in the Perl Programming forum on Dev Shed. Perl script log rotate with zip Perl Programming forum discussing coding in Perl, utilizing Perl modules, and other Perl-related topics. Perl, the Practical Extraction and Reporting Language, is the choice for many for parsing textual information.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

September 28th, 2012, 01:50 PM
|
|
Registered User
|
|
Join Date: Sep 2012
Posts: 2
Time spent in forums: 31 m 27 sec
Reputation Power: 0
|
|
|
Perl script log rotate with zip
I have a perl script I inherited to rotate some logs, would like to add to the script to zip the log files as they rotate. Could anyone please help? Don't know alot about perl.
#!/usr/bin/perl -w
#
# This is a simple PERL program for opening a UDP ocket & listening for
# UDP logging datagrams.
#
# Each log message is in ASCII and is formatted as:
#
# <file>:<log test>
#
# A hash table (hashing filenames into file handles) is maintained to keep
# track of open files to which data is logged.
#
use Socket;
use POSIX;
# globals
%handles=();
$maxRotateBytes=20000;
$maxFiles=30;
sub check_rotate {
my $file = $_[0];
my $done=0;
my $filesz;
my $i;
my $j;
my $tmp;
if ($handles{$file}) {
$tmp = sysseek($handles{$file}, 0, SEEK_CUR);
$filesz = $tmp;
# print "$file: $filesz of $maxRotateBytes\n";
if ($filesz > $maxRotateBytes) {
# print "$file > $maxRotateBytes\n";
for ($i = 1; $i < $maxFiles && $done == 0; ) {
if (! -e "$file.$i") {
$done=1;
}
else {
$i++;
}
}
# print "largest suffix is $i\n";
if ($i == $maxFiles) {
# print "rmmax $file.$i\n";
unlink("$file.$i");
}
# blank out the hashmap entry; a new file will
# be opened when the next log message arrives
# print "close $file\n";
close($handles{$file});
undef $handles{$file};
# Now do the actual 'rotate'
for ($j = $i - 1; $j >= 0; $j--, $i--) {
if ($j == 0) {
# move filename to filename.1
# print "mv $file, $file.$i\n";
rename($file, "$file.$i");
}
else {
# move filename.i-1 to filename.i
# print "mv $file.$j, $file.$i\n";
rename("$file.$j", "$file.$i");
}
}
}
}
}
# parse command line options
use Getopt::Std;
my($opt_s, $opt_d, $opt_f, $opt_m);
$socknum=2500;
$logdir="/acmelogs";
$multi=1;
getopt('sdfm');
if ($opt_s) {
$socknum=$opt_s;
$multi=0;
}
if ($opt_d) {
$logdir = $opt_d;
printf("logdir=%s\n", $logdir);
}
if ($opt_f) {
$maxFiles = $opt_f;
printf("maxFiles=%s\n", $maxFiles);
}
if ($opt_m) {
$maxFiles = $opt_m;
printf("maxRotateBytes=%s\n", $maxRotateBytes);
}
# used to be $logdir[0] !- "."
if ((length($logdir) > 1) || ($logdir ne ".")) {
if (! -d $logdir) {
printf("Invalid target directory specified\n");
exit;
}
chdir($logdir) || die "Cannot change to $logdir";
}
printf("logger.pl: Listening on socket %d; Logging to '%s' multi=%s rotate=%d@%d\n", $socknum, $logdir, ($multi==1) ? "Y" : "N", $maxFiles,$maxRotateBytes);
$proto = getprotobyname('udp');
if (socket(LISTEN, PF_INET, SOCK_DGRAM, $proto)) {
setsockopt(LISTEN, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
bind(LISTEN, sockaddr_in($socknum, INADDR_ANY));
listen(LISTEN, SOMAXCONN);
}
else {
print STDERR "Failed to open listening socket : $!\n";
}
#
# need to keep a dynamically instantiated table of logfile names to
# file descriptors.
#
while (1) {
$from = recv(LISTEN, $rcvbuf, 1024, 0);
$fromip = inet_ntoa((unpack_sockaddr_in($from))[1]);
# $toip = inet_ntoa((unpack_sockaddr_in(getsockname(LISTEN)))[1]);
# get the target file
@fields=split(/:/, $rcvbuf);
$leaffile=$fields[0];
# handle multiple ip-based subdirectories per SD...
if ($multi != 0) {
$dir=$fromip;
if (! -d $dir) {
mkdir $dir,0777;
}
$file="$dir/$leaffile";
}
else {
$file=$leaffile;
}
# remove the file prefix from the buffer...
$outbuf=substr($rcvbuf, length($leaffile)+1);
# check to see if the file should be rotated...
check_rotate($file);
#
# Check to see if the extracted filename already exists in our
# table of open file decriptors.
#
if (! $handles{$file} ) {
if (open($handles{$file}, ">> $file")) {
if (! -e "$file.1") {
print "opened $file\n";
}
}
else {
print "Failed to open $file !!!\n";
}
}
# write to the file
syswrite($handles{$file}, "$outbuf\n");
# listen for more messages...
listen(LISTEN, SOMAXCONN);
}
|

September 28th, 2012, 02:04 PM
|
|
|
Please put your script inside the code tags so that its formatting (indentation) is retained which makes it easier for us to read and suggest where you need to adjust your code.
Also, please add the following 2 pragmas to your script and fix the issues that they point out. For the most part, that means that you'll need to declare your vars with the 'my' keyword.
Code:
use strict;
use warnings;
|

October 1st, 2012, 11:10 AM
|
|
Registered User
|
|
Join Date: Sep 2012
Posts: 2
Time spent in forums: 31 m 27 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by FishMonger Please put your script inside the code tags so that its formatting (indentation) is retained which makes it easier for us to read and suggest where you need to adjust your code.
Also, please add the following 2 pragmas to your script and fix the issues that they point out. For the most part, that means that you'll need to declare your vars with the 'my' keyword.
Code:
use strict;
use warnings;
|
Here it is with code tags.
Code:
#!/usr/bin/perl -w
#
# This is a simple PERL program for opening a UDP ocket & listening for
# UDP logging datagrams.
#
# Each log message is in ASCII and is formatted as:
#
# <file>:<log test>
#
# A hash table (hashing filenames into file handles) is maintained to keep
# track of open files to which data is logged.
#
use Socket;
use POSIX;
# globals
%handles=();
$maxRotateBytes=2000000000;
$maxFiles=30;
sub check_rotate {
my $file = $_[0];
my $done=0;
my $filesz;
my $i;
my $j;
my $tmp;
if ($handles{$file}) {
$tmp = sysseek($handles{$file}, 0, SEEK_CUR);
$filesz = $tmp;
# print "$file: $filesz of $maxRotateBytes\n";
if ($filesz > $maxRotateBytes) {
# print "$file > $maxRotateBytes\n";
for ($i = 1; $i < $maxFiles && $done == 0; ) {
if (! -e "$file.$i") {
$done=1;
}
else {
$i++;
}
}
# print "largest suffix is $i\n";
if ($i == $maxFiles) {
# print "rmmax $file.$i\n";
unlink("$file.$i");
}
# blank out the hashmap entry; a new file will
# be opened when the next log message arrives
# print "close $file\n";
close($handles{$file});
undef $handles{$file};
# Now do the actual 'rotate'
for ($j = $i - 1; $j >= 0; $j--, $i--) {
if ($j == 0) {
# move filename to filename.1
# print "mv $file, $file.$i\n";
rename($file, "$file.$i");
}
else {
# move filename.i-1 to filename.i
# print "mv $file.$j, $file.$i\n";
rename("$file.$j", "$file.$i");
}
}
}
}
}
# parse command line options
use Getopt::Std;
my($opt_s, $opt_d, $opt_f, $opt_m);
$socknum=2500;
$logdir="/acmelogs";
$multi=1;
getopt('sdfm');
if ($opt_s) {
$socknum=$opt_s;
$multi=0;
}
if ($opt_d) {
$logdir = $opt_d;
printf("logdir=%s\n", $logdir);
}
if ($opt_f) {
$maxFiles = $opt_f;
printf("maxFiles=%s\n", $maxFiles);
}
if ($opt_m) {
$maxFiles = $opt_m;
printf("maxRotateBytes=%s\n", $maxRotateBytes);
}
# used to be $logdir[0] !- "."
if ((length($logdir) > 1) || ($logdir ne ".")) {
if (! -d $logdir) {
printf("Invalid target directory specified\n");
exit;
}
chdir($logdir) || die "Cannot change to $logdir";
}
printf("logger.pl: Listening on socket %d; Logging to '%s' multi=%s rotate=%d@%d\n", $socknum, $logdir, ($multi==1) ? "Y" : "N", $maxFiles,$maxRotateBytes);
$proto = getprotobyname('udp');
if (socket(LISTEN, PF_INET, SOCK_DGRAM, $proto)) {
setsockopt(LISTEN, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
bind(LISTEN, sockaddr_in($socknum, INADDR_ANY));
listen(LISTEN, SOMAXCONN);
}
else {
print STDERR "Failed to open listening socket : $!\n";
}
#
# need to keep a dynamically instantiated table of logfile names to
# file descriptors.
#
while (1) {
$from = recv(LISTEN, $rcvbuf, 1024, 0);
$fromip = inet_ntoa((unpack_sockaddr_in($from))[1]);
# $toip = inet_ntoa((unpack_sockaddr_in(getsockname(LISTEN)))[1]);
# get the target file
@fields=split(/:/, $rcvbuf);
$leaffile=$fields[0];
# handle multiple ip-based subdirectories per SD...
if ($multi != 0) {
$dir=$fromip;
if (! -d $dir) {
mkdir $dir,0777;
}
$file="$dir/$leaffile";
}
else {
$file=$leaffile;
}
# remove the file prefix from the buffer...
$outbuf=substr($rcvbuf, length($leaffile)+1);
# check to see if the file should be rotated...
check_rotate($file);
#
# Check to see if the extracted filename already exists in our
# table of open file decriptors.
#
if (! $handles{$file} ) {
if (open($handles{$file}, ">> $file")) {
if (! -e "$file.1") {
print "opened $file\n";
}
}
else {
print "Failed to open $file !!!\n";
}
}
# write to the file
syswrite($handles{$file}, "$outbuf\n");
# listen for more messages...
listen(LISTEN, SOMAXCONN);
}
|

October 4th, 2012, 08:24 AM
|
|
|
|
Sorry for not responding earlier. I've been tied up with family matters and work so I haven't been able to spend as much time in the perl forums as I normally do.
I see that you've also posted this question on perlguru and Laurent_R is trying to help you. Rather than duplicating effort on multiple forums, I'll post my comments in the perlguru thread instead of here.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|