Search code examples
perlparsingsyslog

Parsing a syslog entry


This is what an entry looks like:

Jan 26 20:53:31 hostname logger: System rebooted for hard disk upgrade

I'm writing a small application to parse entries like this and email a nicely formatted message to the admin. I'm writing in Perl and found the split() function which is exactly what I'm looking for:

my @tmp = split(/ /, $string, 4);
@tmp = {$date, $hostname, $facility, $message)

That's what I'm hoping to get. Split() can handle the spaces in the $message part because I limit the amount of "words" to split off. However, the spaces in the $date part throw it off. Is there a clean way I can get these variables to represent what they're supposed to?

I know I could use substr() to grab the first 15 characters (the date), then use split() and limit it to 3 words instead of 4, then grab all my strings from there. But is there a more elegant way to do this?


Solution

  • If one-lined-ness is important to elegance, split on spaces that are not followed by a digit:

    my ( $time, $hostname, $facility, $message ) = split /\s+(?=\D)/, $string, 4;
    

    But it makes more sense to use a combination of split and unpack to address the need:

    my ( $timeStamp, $log ) = unpack 'A15 A*', $string;
    
    my ( $host, $facility, $msg ) = split /\s+/, $log;