32a33
> check_interval check_options check_period current_event_id current_notification_id current_problem_id last_event_id last_problem_id long_plugin_output notification_period retry_interval
37a39
> check_interval check_options check_period current_event_id current_notification_id current_problem_id last_event_id last_problem_id long_plugin_output notification_period retry_interval
42a45
> active_ondemand_host_check_stats active_ondemand_service_check_stats active_scheduled_host_check_stats active_scheduled_service_check_stats cached_host_check_stats cached_service_check_stats external_command_stats high_external_command_buffer_slots next_comment_id next_downtime_id next_event_id next_notification_id next_problem_id parallel_host_check_stats passive_host_check_stats passive_service_check_stats serial_host_check_stats total_external_command_buffer_slots used_external_command_buffer_slots
44c47,62
< Info => [qw( created version )]
---
> Contact => [qw(
> contact_name modified_attributes modified_host_attributes modified_service_attributes host_notification_period service_notification_period last_host_notification last_service_notification host_notifications_enabled service_notifications_enabled
> )],
> Servicecomment => [qw(
> host_name service_description entry_type comment_id source persistent entry_time expires expire_time author comment_data
> )],
> Hostcomment => [qw(
> host_name entry_type comment_id source persistent entry_time expires expire_time author comment_data
> )],
> Servicedowntime => [qw(
> host_name service_description downtime_id entry_time start_time end_time triggered_by fixed duration author comment
> )],
> Hostdowntime => [qw(
> host_name downtime_id entry_time start_time end_time triggered_by fixed duration author comment
> )],
> Info => [qw( created version )]
77c95,96
< pass in the Version => 2.0 parameter to new().
---
> pass in the Version => 2.0 parameter to new(). And similarly, pass in the
> Version => 3.0 parameter to new() for Nagios version 3.x logs.
93a113,118
> # for Nagios v3.0
> my $log = Nagios::StatusLog->new(
> Filename => "/var/opt/nagios/status.dat",
> Version => 3.0
> );
>
128,133c153,163
< LOGFILE => $logfile,
< VERSION => $version,
< INFO => {},
< PROGRAM => {},
< HOST => {},
< SERVICE => {}
---
> LOGFILE => $logfile,
> VERSION => $version,
> INFO => {},
> CONTACT => {},
> PROGRAM => {},
> HOST => {},
> HOSTCOMMENT => {},
> HOSTDOWNTIME => {},
> SERVICE => {},
> SERVICECOMMENT => {},
> SERVICEDOWNTIME => {}
149c179,181
< if ( $self->{VERSION} >= 2 ) {
---
> if ( $self->{VERSION} >= 3 ) {
> return $self->update_v3( @_ );
> } elsif ( $self->{VERSION} >= 2 && $self->{VERSION} < 3 ) {
302a335,425
> sub update_v3 ($) {
> my $self = shift;
>
> # be compatible with StatusLog which makes sure that references
> # held in client code remain valid during update (also prevents
> # some memory leaks)
> sub _copy3 {
> my( $from, $to ) = @_;
> foreach my $key ( keys %$from ) {
> $to->{$key} = $from->{$key};
> }
> }
>
> my %handlers = (
> hoststatus => sub {
> my $item = shift;
> my $host = $item->{host_name};
> if ( !exists $self->{HOST}{$host} ) {
> $self->{HOST}{$host} = {};
> }
> _copy3( $item, $self->{HOST}{$host} );
> },
> servicestatus => sub {
> my $item = shift;
> my $host = $item->{host_name};
> my $svc = $item->{service_description};
>
> if ( !exists $self->{SERVICE}{$host}{$svc} ) {
> $self->{SERVICE}{$host}{$svc} = {};
> }
> _copy3( $item, $self->{SERVICE}{$host}{$svc} );
> },
> info => sub {
> _copy3( shift, $self->{INFO} );
> },
> programstatus => sub {
> _copy3( shift, $self->{PROGRAM} );
> },
> contactstatus => sub {
> _copy3( shift, $self->{CONTACT} );
> },
> servicecomment => sub {
> _copy3( shift, $self->{SERVICECOMMENT} );
> },
> hostcomment => sub {
> _copy3( shift, $self->{HOSTCOMMENT} );
> },
> servicedowntime => sub {
> _copy3( shift, $self->{SERVICEDOWNTIME} );
> },
> hostdowntime => sub {
> _copy3( shift, $self->{HOSTDOWNTIME} );
> }
>
> );
>
> my $log_fh = gensym;
> open( $log_fh, "<$self->{LOGFILE}" )
> || croak "could not open file $self->{LOGFILE} for reading: $!";
>
> # change the first line of the RE to this:
> # (info|programstatus|hoststatus|servicestatus|contactstatus|servicecomment|hostcomment|servicedowntime|hostdowntime) \s* {(
> # to make it a bit more careful, but it has a measurable cost on runtime
> my $entry_re = qr/
> # capture the type into $1
> (\w+) \s*
> # capture all of the text between the brackets into $2
> {( .*? )}
> # match the last bracket only if followed by another definition
> (?=(?: \s* (?:info|programstatus|hoststatus|servicestatus|contacstatus|servicecomment|hostcomment|servicedowntime|hostdowntime) \s* { | \Z) )
> # capture remaining text (1-2 lines) into $3 for re-processing
> (.*)$
> /xs;
>
> my $entry = '';
> while ( my $line = <$log_fh> ) {
> next if ( $line =~ /^\s*#/ );
> $entry .= $line;
> if ( $entry =~ m/$entry_re/ ) {
> ( my $type, my $text, $entry ) = ( $1, $2, $3 );
> $text =~ s/[\r\n]+\s*/\n/g; # clean up whitespace and newlines
> my %item = map { split /\s*=\s*/, $_, 2 } split /\n/, $text;
> $handlers{$type}->( \%item );
> }
> }
>
> close( $log_fh );
>
> 1;
> }
>