Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^2: Timelocal out of range message

by itis.guptak (Initiate)
on Feb 03, 2014 at 07:36 UTC ( [id://1073144]=note: print w/replies, xml ) Need Help??


in reply to Re: Timelocal out of range message
in thread Timelocal out of range message

Thanks, Ken. Let me just explain what this script does. It pulls the systems message file from a list of hosts and put the content in a single file output on a central server from where it's run as cron job. I'm pasting a portion of code that's responsible for timelocal() execution in the script. The code I'm pasting contains three subroutines: addMessage(), processFile(), getLogsSCP(). getLogsSCP() will scp the files to central server. processFile() is called within getLogsSCP() and processFile() furthur calls addMessage(). Finally it's the addMessage() that invokes timelocal(). I've also pasted some variables used for computing the parameters passed to the timelocal function. This line of the code is generating the error.

my $logtime = timelocal(${sec}, ${min}, ${hour}, ${mday}, ${mon}, ${current_year} - ${new_yea +r});

Code

sub getLogsSCP { my @hosts = @_; dprint "Getting logs for the last ${cutoff} hours"; dprint " from " . @hosts . " hosts\n"; # Build command to list log files # Using find allows us to scan only files that are new enough my $ssh_command = "find"; $ssh_command .= " @messages_files"; $ssh_command .= " -mtime -" . (int(${cutoff} / 24) + 1); my $nHosts = 1; foreach (@hosts) { chomp; my $host = $_; $current_host = ${host}; $last{${host}} = ""; my $c = 0; while (<READER>) { chomp; my $file = $_; my $tmpfile = "/tmp/logmon.${host}.$hnow{year}$hnow{mon}$hnow{md +ay}.$ENV{LOGNAME}"; # Copy log file dprint localtime() . " Copying ${file} to ${tmpfile}\n"; my $scp = Net::SCP->new({"host" => ${host}}); $scp->get(${file}, ${tmpfile}); # Process log file my $size = (stat("${tmpfile}"))[7]; if (! defined(${size})) { dprint localtime() . " Failed to copy ${file} from ${host}\n"; addFakeMessage(${host}, "FAILED TO COPY ${file} FROM ${host}") +; $total_count++; next; } dprint localtime() . " Parsing ${tmpfile} (${size} bytes)\n"; open(FD, "${tmpfile}") or next; unlink "${tmpfile}"; $c += processFile(\*FD, ${tmpfile}, ${host}); close(FD); } push @emptyhosts, ${host} if ($c == 0); $total_count += $c; close(*READER); close(*WRITER); close(*ERR); } dprint "\n"; } # Process a log file (or stream) sub processFile() { my $FD = shift; # Caller must open and close file descrip +tor my $file = shift; my $host = shift; my $c = 0; my $line = 1; while (<FD>) { # Log file is too big if ($line++ > ${max_messages}) { dprint "\n" . localtime() . " Too many messages in ${file}"; addFakeMessage(${host}, "STOPPED PROCESSING ${file} AFTER ${max_ +messages} MESSAAGES (please rotate)"); $total_count++; last; } dprint "${line}..." if (($line % 10000) == 0); my $retval += addMessage($_); if (${retval} < 0) { $c = 0; } else { $c += ${retval}; } } dprint "\n" if (${line} > 10000); return ${c} ; } sub addMessage($) { my $msg = shift; chomp ${msg}; # Skip blank lines if (${msg} =~ /^$/) { $reason = "blank"; return 0; } # Parse message my ($month, $mday, $tm, $host, @message) = split(/ ?/, ${msg}); my ($hour, $min, $sec) = split(/:/, ${tm}) if (defined(${tm})); # Skip line if we don't know the hostname if (! defined(${host}) || ${host} eq "") { $reason = "hostname" ; re +turn 0; } # Skip lines that don't look like syslog messages unless (${tm} =~ /[0-2]\d:[0-5]\d/) { $reason = "tm = ${tm}"; return + 0; } # Skip lines that are too old my $mon = $month_to_mon{${month}}; my $logtime = timelocal(${sec}, ${min}, ${hour}, ${mday}, ${mon}, ${current_year} - ${new_yea +r}); <----------------- This line is producing the error. if ((${mon} == 0) && (${mday} == 1) && (${new_year} == 1)) { # Special case for Jan 1 (only!) $logtime = timelocal(${sec}, ${min}, ${hour}, ${mday}, ${mon}, ${current_year}); } $logtime -= ((int($offsets{${host}}) / 100) * 100) if (defined($offsets{${host}})); if (${logtime} < ${then}) { $reason = "too old"; return 0; } # Reset host if line is from the future; we may have messages from o +ne # year ago. Note that this may make the global counts wrong. if (${logtime} > (time + 3600)) { # Allow 1 hour slack time $last{${host}} = ""; $counts{${host}} = 0; delete($messages{${host}}); undef($times{${host}}{oldest}); undef($times{${host}}{newest}); $reason = "future"; return -1; } my %month_to_mon = # Convert month names to numbers (Jan +== 0) ( "Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3, "May" => 4, "Jun" => 5, "Jul" => 6, "Aug" => 7, "Sep" => 8, "Oct" => 9, "Nov" => 10, "Dec" => 11, "JAN" => 0, "FEB" => 1, "MAR" => 2, "APR" => 3, "MAY" => 4, "JUN" => 5, "JUL" => 6, "AUG" => 7, "SEP" => 8, "OCT" => 9, "NOV" => 10, "DEC" => 11); my @mon_to_month = # Convert month numbers to names (0 == + Jan) qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);

Replies are listed 'Best First'.
Re^3: Timelocal out of range message
by kcott (Archbishop) on Feb 04, 2014 at 04:19 UTC

    I wrote:

    "Please provide a short script that reproduces your problem. How to do this is explained in "How do I post a question effectively?"."

    Had you followed that link, you would have seen, in big, friendly letters, at the top of the screen:

    Paste actual code that reproduces the problem ...

    You haven't posted actual code. You haven't posted code that reproduces your problem.

    In addition, hundreds of lines of code is not a "short script": a dozen or so lines normally suffices for this sort of task. If you ever do need to post large tracts of code, data, etc., wrap it in <spoiler>...</spoiler> or <readmore>...</readmore> tags: see "Markup in the Monastery" and "Writeup Formatting Tips".

    What you have posted appears to have been copied from your browser. It looks like the code you posted a couple of hours before in this thread; it includes all the '+' signs at the beginning of lines (that indicate that a line wrapped) which are not part of the Perl code.

    If you can post a short script that shows Time::Local::timelocal() giving your "Timelocal out of range message", I'll be happy to look at it further.

    In writing a short script to reproduce your problem, you'll often gain insights into why your original code was having issues.

    Something else you can do is to add print statements to your original code to see what actual values are being passed to your functions. This can often point to where the problem lies.

    -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1073144]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2024-04-25 05:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found