Parse-Syslog-Line

 view release on metacpan or  search on metacpan

lib/Parse/Syslog/Line.pm  view on Meta::CPAN

    }

    #
    # Host Information:
    if( $raw_string =~ s/^$RE{host}//o ) {
        my $hostStr = $1;
        my($ip) = ($hostStr =~ /($RE{IPv4})/o);
        if( defined $ip && length $ip ) {
            $msg{host_raw} = $hostStr;
            $msg{host} = $ip;
        }
        elsif( length $hostStr ) {
            my ($host,$domain) = split /\./, $hostStr, 2;
            $msg{host_raw} = $hostStr;
            $msg{host} = $host;
            $msg{domain} = $domain;
        }
    }
    # Check for relayed logs, grab the origin
    while( $raw_string =~ /^(?:\s*[0-9]+\s+)?$RE{date_iso8601}\s+$RE{host}/go ) {
        $msg{origin} = $2;
        $msg{origin_date} = $1;
        $raw_string = substr($raw_string,pos($raw_string));
    }

    # Find weird cisco dates
    if( $raw_string =~ s/^$RE{cisco_detection}//o ) {
        # Yes, Cisco adds a second timestamp to it's messages, because ...
        if( $raw_string =~ s/^$RE{date_long}//o ) {
            # Cisco encodes the status of NTP in the second datestamp, so let's pass it back
            if ( my $ntp = $1 ) {
                $msg{ntp} = $ntp eq '.' ? 'out of sync'
                          : $ntp eq '*' ? 'not configured'
                          : 'unknown';
            }
            else {
                $msg{ntp} = 'ok';
            }
        }
    }

    #
    # Parse the Program portion
    my $progsep = ':';
    if( $ExtractProgram ) {
        if( $raw_string =~ s/^$RE{program_raw}//o ) {
            $msg{program_raw} = $1;
            $progsep = $2 || '';
            my $progStr = join ' ', grep {!exists $INT_PRIORITY{$_}} split /\s+/, $msg{program_raw};
            if( $progStr =~ /^$RE{program_name}/o ) {
                $msg{program_name} = $1;
                my $remainder      = $2;
                if ( $remainder ) {
                    ($msg{program_pid}) = ($remainder =~ /$RE{program_pid}/o);
                    ($msg{program_sub}) = ($remainder =~ /$RE{program_sub}/o);
                    if( !$msg{program_sub}  ) {
                        ($msg{program_sub}) = ($remainder =~ /^(?:[\/\s])?([^\[(]+)/o);
                    }
                }
                if( $msg{program_name} !~ m{^/} && $msg{program_name} =~ tr{/}{} ) {
                    @msg{qw(program_name program_sub)} = split m{/}, $msg{program_name}, 2;
                }
            }
        }
        elsif( $raw_string =~ s/$RE{program_netapp}//o ) {
            # Check for a [host thing.subthing:level]: tag
            #          or [host:thing.subthing:level]: tag, Thanks NetApp.
            my $subStr = $1;
            $msg{program_raw} = qq{[$subStr]};
            my ($host,$program,$level) = split /[: ]+/, $subStr;
            $msg{program_name} = $program;
            if(!exists $msg{priority} && exists $LOG_PRIORITY{$level}) {
                $msg{priority} = $level;
                $msg{priority_int} = $LOG_PRIORITY{$level};
            }
            $raw_string =~ s/^[ :]+//;
        }
    }
    else {
        $raw_string =~ s/^\s+//;
    }

    # The left overs should be the message
    $msg{content} = $raw_string;
    chomp $msg{content};
    $msg{message} = defined $msg{program_raw} ? "$msg{program_raw}$progsep $msg{content}" : $msg{content};

    # Extract RFC Structured Data
    if( $RFC5424StructuredDataStrict ) {
        while ( $msg{content} =~ s/$RE{rfc_sdata_strict}//o ) {
            my $rfc_sdata = $1;
            my ($sdid,$sdata) = split /\s+/, $rfc_sdata, 2;
            foreach my $token ( $sdata =~ /($RE{sysword}=$RE{quotedstring})/og ) {
                my ($k,$v) = split /=/, $token, 2;
                next unless length $v;
                # Trim off the quotes
                $v = substr($v, 1, length($v) - 2);
                $msg{SDATA}{$sdid}{$k} = $v;
            }
        }
        $msg{content} =~ s/^\s+//;
    }
    elsif ( $RFC5424StructuredData ) {
        while ( $msg{content} =~ s/$RE{rfc_sdata_extract}//o ) {
            my $rfc_sdata = $1;
            my ($group) = $rfc_sdata =~ s/^([^\s=]+)\s// ? $1 : undef;
            foreach my $token ( $rfc_sdata =~ /($RE{sysword}=(?:$RE{quotedstring}|\S+))/og ) {
                my ($k,$v) = split /=/, $token, 2;
                next unless length $v;
                # Trim off the quotes
                $v =~ s/(?:^")|(?:"$)//g;
                if( $group ) {
                    $msg{SDATA}{$group}{$k} = $v;
                } else {
                    $msg{SDATA}{$k} = $v;
                }
            }
            # When we parse without ExtractProgram, shit gets weird.
            #   We need to restore the first space between the first semi-colon
            #   and the rest of the string
            $msg{content} =~ s/:\s*/: / if $msg{SDATA};



( run in 0.943 second using v1.01-cache-2.11-cpan-71847e10f99 )