CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: General Discussions: General Questions:
Adding zip of file to log ratation script

 



DBCooper
New User

Oct 2, 2012, 9:14 AM

Post #1 of 7 (20883 views)
Adding zip of file to log ratation script Can't Post

I am new to Perl, not a programmer. I inherited a script that works well but runs me out of space. Would like to add zipping of the files as the script rotates the logs. Any help pointing me in the right direction would be appreciated. Scipt is below in code tags I think?

I receive the following errors when I run with use strict and warnings. Have tried but canít seem to fix them.



Global symbol "%handles" requires explicit package name at ./logger-with-rotate.pl line 20.
Global symbol "%handles" requires explicit package name at ./logger-with-rotate.pl line 32.
Global symbol "%handles" requires explicit package name at ./logger-with-rotate.pl line 33.
Global symbol "%handles" requires explicit package name at ./logger-with-rotate.pl line 55.
Global symbol "%handles" requires explicit package name at ./logger-with-rotate.pl line 56.
BEGIN not safe after errors--compilation aborted at ./logger-with-rotate.pl line 75.




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;
#use strict;
#use warnings;
#use diagnostics;

# globals
%handles=();
my $maxRotateBytes=2000000000;
my $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);
}



Laurent_R
Veteran / Moderator

Oct 2, 2012, 10:15 AM

Post #2 of 7 (20880 views)
Re: [DBCooper] Adding zip of file to log ratation script [In reply to] Can't Post

Hi, there may be other things, but start to change:


Code
%handles=();


to:


Code
my %handles=();



DBCooper
New User

Oct 2, 2012, 12:26 PM

Post #3 of 7 (20873 views)
Re: [Laurent_R] Adding zip of file to log ratation script [In reply to] Can't Post

I did that and now these are the errors I get. Thanks for your reply!

Global symbol "$socknum" requires explicit package name at ./logger-with-rotate.pl line 78.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 79.
Global symbol "$multi" requires explicit package name at ./logger-with-rotate.pl line 80.
Global symbol "$socknum" requires explicit package name at ./logger-with-rotate.pl line 84.
Global symbol "$multi" requires explicit package name at ./logger-with-rotate.pl line 85.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 88.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 89.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 101.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 101.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 102.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 106.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 106.
Global symbol "$socknum" requires explicit package name at ./logger-with-rotate.pl line 109.
Global symbol "$logdir" requires explicit package name at ./logger-with-rotate.pl line 109.
Global symbol "$multi" requires explicit package name at ./logger-with-rotate.pl line 109.
Global symbol "$proto" requires explicit package name at ./logger-with-rotate.pl line 111.
Global symbol "$proto" requires explicit package name at ./logger-with-rotate.pl line 112.
Global symbol "$socknum" requires explicit package name at ./logger-with-rotate.pl line 114.
Global symbol "$from" requires explicit package name at ./logger-with-rotate.pl line 127.
Global symbol "$rcvbuf" requires explicit package name at ./logger-with-rotate.pl line 127.
Global symbol "$fromip" requires explicit package name at ./logger-with-rotate.pl line 128.
Global symbol "$from" requires explicit package name at ./logger-with-rotate.pl line 128.
Global symbol "@fields" requires explicit package name at ./logger-with-rotate.pl line 131.
Global symbol "$rcvbuf" requires explicit package name at ./logger-with-rotate.pl line 131.
Global symbol "$leaffile" requires explicit package name at ./logger-with-rotate.pl line 132.
Global symbol "@fields" requires explicit package name at ./logger-with-rotate.pl line 132.
Global symbol "$multi" requires explicit package name at ./logger-with-rotate.pl line 134.
Global symbol "$dir" requires explicit package name at ./logger-with-rotate.pl line 135.
Global symbol "$fromip" requires explicit package name at ./logger-with-rotate.pl line 135.
Global symbol "$dir" requires explicit package name at ./logger-with-rotate.pl line 136.
Global symbol "$dir" requires explicit package name at ./logger-with-rotate.pl line 137.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 139.
Global symbol "$dir" requires explicit package name at ./logger-with-rotate.pl line 139.
Global symbol "$leaffile" requires explicit package name at ./logger-with-rotate.pl line 139.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 142.
Global symbol "$leaffile" requires explicit package name at ./logger-with-rotate.pl line 142.
Global symbol "$outbuf" requires explicit package name at ./logger-with-rotate.pl line 145.
Global symbol "$rcvbuf" requires explicit package name at ./logger-with-rotate.pl line 145.
Global symbol "$leaffile" requires explicit package name at ./logger-with-rotate.pl line 145.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 148.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 154.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 155.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 155.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 156.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 157.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 161.
Global symbol "$file" requires explicit package name at ./logger-with-rotate.pl line 166.
Global symbol "$outbuf" requires explicit package name at ./logger-with-rotate.pl line 166.
Execution of ./logger-with-rotate.pl aborted due to compilation errors.


Laurent_R
Veteran / Moderator

Oct 2, 2012, 2:00 PM

Post #4 of 7 (20871 views)
Re: [DBCooper] Adding zip of file to log ratation script [In reply to] Can't Post

Same thing, you need to declare your variables before you use them.

So you need something like this:


Code
my $socknum; 
my $logdir;
my $multi;
#etc, once per variable


This may look painful, but it actually helps you avoiding more difficult to detect mistakes, like typos in the name of variables.

Having said that, there is more to it than simply pre-declaring your lexical variables. The place where you do this declaration is also important. Often, Perl beginners declare all their variables at the beginning (at the very top of the program, as is often done in other languages). This is better than not declaring them, but this is often not optimal at all; usually, variables should be declared in the smallest scope possible. But it is a bit complicated to explain these things in details here in a forum.


DBCooper
New User

Oct 3, 2012, 11:56 AM

Post #5 of 7 (20855 views)
Re: [Laurent_R] Adding zip of file to log ratation script [In reply to] Can't Post

Ok, I have it to a point that I cant fix. I am getting this error.

Use of uninitialized value $file in hash element at ./logger-with-rotate.pl line 32.
Use of uninitialized value $file in hash element at ./logger-with-rotate.pl line 33.
sysseek() on closed filehandle $handles{...} at ./logger-with-rotate.pl line 33.
Use of uninitialized value $filesz in numeric gt (>) at ./logger-with-rotate.pl line 36.
Use of uninitialized value $file in hash element at ./logger-with-rotate.pl line 154.
Use of uninitialized value $file in hash element at ./logger-with-rotate.pl line 166.
syswrite() on closed filehandle $handles{...} at ./logger-with-rotate.pl line 166.


Laurent_R
Veteran / Moderator

Oct 3, 2012, 2:43 PM

Post #6 of 7 (20851 views)
Re: [DBCooper] Adding zip of file to log ratation script [In reply to] Can't Post

Hm, you should probably post your new code, removing out commented out code and giving the errors obtained after having removed commented out code. This will make it easier to find where the remaining errors are.

I haven't taken the time to examine you full code (I wait for a cleanout version), but my guess (without having tried to understand everything that you are doing at this point) is that you should probably change:


Code
if ($handles{$file}) { # ...


to something like:


Code
if (defined $handles{$file}) { # ...


The other "unitialized value" errors are probably similar.

The second point (again I haven't checked, I would prefer to look at cleaned code) is that you were probably not aware to open the file whose filehandle is $handle.


FishMonger
Veteran / Moderator

Oct 4, 2012, 6:43 AM

Post #7 of 7 (20820 views)
Re: [DBCooper] Adding zip of file to log ratation script [In reply to] Can't Post

I agree with Laurent_R about needing to see your updated code so we can better help you.

The code you've posted so far has a number of problems and until we resolve those issues, I hesitate to make suggestions on the adding of the zip file code. Doing so at this point, IMO, would only serve to make the code more difficult to deal with.

One point I will make now is to somewhat disagree with Laurent_R's last suggestion on the conditional used to check $handles{$file}. Checking if it's defined in not sufficient. It could be defined, but still not be a filehandle that can be read from or written to.

You could use the ref() function to check/verify that it's a type GLOB (i.e. the function returns 'GLOB'). But that still doesn't tell you if it's an open filehandle. To test for that condition, you use the fileno() function.

Here's a short test script that demonstrates what I'm talking about.

Code
#!/usr/bin/perl 

use 5.10.0;
use strict;
use warnings;
use Data::Dumper;

my (%handles, $type, $fd);

open $handles{$0}, '<', $0 or die $!;

$type = ref $handles{$0};
$fd = fileno $handles{$0};
say Dumper($type, $fd);

close $handles{$0};

$type = ref $handles{$0};
$fd = fileno $handles{$0};

say Dumper($type, $fd);

if ( defined $handles{$0} ) {
say "The filehandle is defined, but is it open?";

unless (fileno $handles{$0}) {
say "No, it's not open";
}
}


Outputs:

Quote
$VAR1 = 'GLOB';
$VAR2 = 3;

$VAR1 = 'GLOB';
$VAR2 = undef;

The filehandle is defined, but is it open?
No, it's not open


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives