Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

grabbing time from a syslog logfile

by mysfitt (Initiate)
on Sep 12, 2005 at 19:57 UTC ( [id://491354]=perlquestion: print w/replies, xml ) Need Help??

mysfitt has asked for the wisdom of the Perl Monks concerning the following question:

Perl gurus, take pity on this newb. I have been writing a script that's purpose is to compare two timestamps and figure out the time delta between them. The difficulty that I am having is with the code to extract the hour from the syslog string. The UNIX command that I would use would be tail -n1 <file> | cut -c8-9. Is there a way to do this with perl? Here is the code that I've come up with so far:
open(MSG_FILE, "$syslog_dir/$_/messages"); @msg_content = <MSG_FILE>; close MSG_FILE; # Read time of last entry in a file [think tail -n1] # and compare to current $msg_content[-1] =~ /((\d{1,2})\:(\d{2})\:(\d{2})){1}/ +; @timestamp = split(/:/, $1);
Please let me know where I have gone awry. alas the output has been inconsistent.

Replies are listed 'Best First'.
Re: grabbing time from a syslog logfile
by socketdave (Curate) on Sep 12, 2005 at 20:18 UTC
    I would craft a regex that properly gathers the entire date from the beginning of your log entry, then use something like str2time from Date::Parse to get a unix timestamp. They're much easier to do math on, and this can take care of all sorts of gotchas for you, perhaps something similar to this, depending on your log format:

    #!/usr/bin/perl use warnings; use strict; use Date::Parse; my $line = 'Sep 12 15:07:48 2005 -0500 hostname rest of log entry goes + here'; ( my $date ) = ( $line =~ /^(\w\w\w \d\d \d\d:\d\d:\d\d \d\d\d\d [-|\+ +]\d\d\d\d)/ ); print str2time( $date )."\n";


    As for grabbing the last x number of lines from a file, you could open a pipe to a tail:

    open (PIPE, "/path/to/tail -n 10 /path/to/logfile |");
    Update: Better yet, try File::Tail.

Re: grabbing time from a syslog logfile
by philcrow (Priest) on Sep 12, 2005 at 20:10 UTC
    If you like cut at the command line, try substr in Perl:
    my $hour = substr $msg_content[-1], 8, 2;
    This says to store 2 characters beginning at position 8 of the last line in the file into the new variable $hour. There are many other ways to accomplish this.

    How to read the last line in the file is more interesting. Above, it looks like you are willing to read the whole file into memory. That's good enough, if your syslog doesn't grow too large.

    Phil

Re: grabbing time from a syslog logfile
by Hue-Bond (Priest) on Sep 12, 2005 at 22:03 UTC
    open(MSG_FILE, "$syslog_dir/$_/messages");

    Better use lexical filehandles and always check the return status of system calls:

    my $infile = "$syslog_dir/$_/messages"; open my $msg_file, '<', $infile or die "couldn't open $infile: $!";
    @msg_content = <MSG_FILE>;

    Since you're going to work with the file line by line, you should not slurp it into memory as that could fill it up and bring the system down to its knees. Better use something like:

    while (<$msg_file>) { do_things; }

    And close afterwards (although this is not applicable to this very problem).

    With regard to your actual question, I'd follow socketdave's advice and use File::Tail. As for the regex, given that syslog format is a well established one (at least, I'm not aware of any way to customize or localize it), I'd stick some magic values in it:

    /^.{7}([\S]{8})/;

    --
    David Serrano

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2024-04-18 07:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found