Hey Brandon

Here is a solution to this problem. It is purposely really long. It takes
the simplest most understandable solution.

If you have questions about it let me know.


#!/usr/local/bin/perl

# always a good idea, forces scope to if/for/foreach/while blocks
use strict;

# open the file, into a file handle called $RR - die with sad face if unable
# to open file
open my $RR, '<', 'nagios.dat' || die 'unable to open nagios.dat :(';

# we need to know if were inside a 'hoststatus' block or not
# this variable keeps track of that
my $we_are_inside_hoststatus_block = 0;

# the logic is to set  $we_are_inside_hoststatus_block to 1 ( true )
# when we see the hoststatus block begins and then set it to 0 ( false )
# when the block is done

# once were inside a hoststatus block were going to save the actual hostname
# in this variable
my $current_block_hostname;

# read file line by line
while (<$RR>) {

        # each line coming into this block of code is automatically
        # called $_ by perl, were going to rename it to $line
        # to make the example clearer
        my $line = $_;

        # each line thats coming in has a \n ( carriage return - new line)
        # at the end - we dont need that. chomp() removes it
        chomp $line;

        # theres two possible scenarios
        # 1 . were outside a hoststatus block
        # 2 . were inside  a hoststatus block

        if ($we_are_inside_hoststatus_block) {

                # theres two possible scenarios inside of here
                # 1 . we already know the hostname of this hoststatus block
                # 2 . we do not

                if ($current_block_hostname) {

                        # case 1

                        # were inside a hoststatus block
                        # and we know what host_name it is for
                        # all we need is the current_state

                        # read the big comment in the else{}
                        # block below to know what this is doing
                        # \d+ means one or more numbers
                        next unless $line =~ /\s+current_state=(\d+)/;

                        my $current_state = $1;

                        # we have everything we need
                        # host_name and current_state and were in a
                        # host status block - all we need to do is
                        # print this information to the screen
                        print "$current_block_hostname:$current_state\n";

                        # since were finished with this hoststatus
                        # block we can reset our
$we_are_inside_hoststatus_block
                        # and $current_block_hostname variables
                        # so the script starts looking for a new
                        # hoststatus block to process

                        $we_are_inside_hoststatus_block = undef;
                        $current_block_hostname         = undef;
                        next;

                }
                else {

                        # case 2

                        # were inside a hostsatus block but we still
                        # dont know what hostname its for
                        #
                        # we dont care about any line unless
                        # it matches the regular expression :
                        # one or more spaces
                        # 'host_name='
                        # \S+ means : something thats not whitespace
                        # the parentheses mean we want to capture
                        # the value between them
                        # perl will automatically call the first
                        # captured value $1, the second one $2
                        # so on and so forth
                        next unless $line =~ /\s+host_name=(\S+)/;

                        # cool we have the hostname of this hoststatus
                        # block
                        $current_block_hostname = $1;

                        # go to the next line of the file
                        next;

                }

        }
        else {

                # we are not inside a hoststatus block
                # in this case we dont care about any of these lines
                # unless its a line that STARTS a hoststatus block

                # does the line match the regular expression that
                # informs us we are starting a hoststatus block ?
                # ^ means beginning of line
                # \s+ means one or more spaces
                # so were looking for a line that begins with
                # 'hoststatus' has one or more spaces and then has a '{'
                if ( $line =~ /^hoststatus\s+{/ ) {

                        # were inside a new hoststatus block
                        $we_are_inside_hoststatus_block = 1;

                }

        }

}

close $RR;


==========

Peace it in, peace it out & peace it inside out.

- Jose from Mexico.



On Tue, Jan 31, 2012 at 4:43 PM, Brandon Phelps <bphe...@gls.com> wrote:

> Hello all,
>
> I am attempting to parse a Nagios status.dat file and am curious about
> what the most efficient way to do this would be.  I'm sure I could come up
> with something but it would be very convoluted and I'm sure there is a
> better way.  Below is a sample of the file.  The sections I am interested
> in are the "hoststatus" sections.  Any other section I want to simply
> ignore.  Within the hoststatus sections are a few lines I am looking for:
>  host_name=<whatever> and current_state=<whatever>, I'd simply like to
> perform a task based on these "whatever"'s.  For example, output lines such
> as:
>
> some_host:1
> another_host:0
>
> Where some_host and another_host are host_name's from the file, and 1 and
> 0 are current_state's for the corresponding host.
>
> Any pointers or examples would be appreciated!
>
> Here is a sample of the file:
>
> info {
>        created=1328049467
>        version=3.2.3
>        last_update_check=1328014790
>        update_available=1
>        last_version=3.2.3
>        new_version=3.3.1
>        }
>
> programstatus {
>        modified_host_attributes=0
>        modified_service_attributes=0
>        nagios_pid=1370
>        daemon_mode=1
>        (lots of stuff)
>        }
>
> hoststatus {
>        host_name=some_host
>        modified_attributes=0
>        check_command=check-host-alive
>        check_period=
>        notification_period=24x7
>        check_interval=5.000000
>        retry_interval=1.000000
>        event_handler=
>        has_been_checked=1
>        should_be_scheduled=1
>        check_execution_time=0.012
>        check_latency=0.246
>        check_type=0
>        current_state=1
>        last_hard_state=0
>        last_event_id=0
>        current_event_id=0
>        current_problem_id=0
>        last_problem_id=0
>        plugin_output=OK - 10.1.1.1.1: rta 1.822ms, lost 0%
>        long_plugin_output=
>        performance_data=rta=1.822ms;**3000.000;5000.000;0; pl=0%;80;100;;
> rtmax=1.822ms;;;; rtmin=1.822ms;;;;
>        last_check=1328049317
>        next_check=1328049627
>        check_options=0
>        current_attempt=1
>        max_attempts=10
>        state_type=1
>        last_state_change=1328047050
>        last_hard_state_change=**1328047050
>        last_time_up=1328049327
>        last_time_down=0
>        last_time_unreachable=0
>        last_notification=0
>        next_notification=0
>        no_more_notifications=0
>        current_notification_number=0
>        current_notification_id=0
>        notifications_enabled=1
>        problem_has_been_acknowledged=**0
>        acknowledgement_type=0
>        active_checks_enabled=1
>        passive_checks_enabled=1
>        event_handler_enabled=1
>        flap_detection_enabled=1
>        failure_prediction_enabled=1
>        process_performance_data=1
>        obsess_over_host=1
>        last_update=1328049467
>        is_flapping=0
>        percent_state_change=0.00
>        scheduled_downtime_depth=0
>        }
>
> hoststatus {
>        host_name=another_host
>        modified_attributes=0
>        check_command=check-host-alive
>        check_period=
>        notification_period=24x7
>        check_interval=5.000000
>        retry_interval=1.000000
>        event_handler=
>        has_been_checked=1
>        should_be_scheduled=1
>        check_execution_time=10.011
>        check_latency=0.268
>        check_type=0
>        current_state=0
>        last_hard_state=0
>        last_event_id=7
>        current_event_id=8
>        current_problem_id=3
>        last_problem_id=1
>        plugin_output=CRITICAL - 10.1.1.2: rta nan, lost 100%
>        long_plugin_output=
>        performance_data=rta=0.000ms;**3000.000;5000.000;0;
> pl=100%;80;100;; rtmax=0.000ms;;;; rtmin=0.000ms;;;;
>        last_check=1328049417
>        next_check=1328049497
>        check_options=0
>        current_attempt=3
>        max_attempts=10
>        state_type=0
>        last_state_change=1328049437
>        last_hard_state_change=**1328049057
>        last_time_up=1328049057
>        last_time_down=1328049437
>        last_time_unreachable=0
>        last_notification=0
>        next_notification=0
>        no_more_notifications=0
>        current_notification_number=0
>        current_notification_id=0
>        notifications_enabled=1
>        problem_has_been_acknowledged=**0
>        acknowledgement_type=0
>        active_checks_enabled=1
>        passive_checks_enabled=1
>        event_handler_enabled=1
>        flap_detection_enabled=1
>        failure_prediction_enabled=1
>        process_performance_data=1
>        obsess_over_host=1
>        last_update=1328049467
>        is_flapping=0
>        percent_state_change=17.30
>        scheduled_downtime_depth=0
>        }
>
> servicestatus {
>        host_name=some_host
>        service_description=PING
>        modified_attributes=0
>        check_command=check_ping!7000.**0,40%!9000.0,70%
>        check_period=24x7
>        notification_period=24x7
>        check_interval=5.000000
>        (lots more stuff...)
>        }
> (file has lots more, but excluded here for brevity)
>
> Thanks,
> Brandon
>
> --
> To unsubscribe, e-mail: beginners-unsubscr...@perl.org
> For additional commands, e-mail: beginners-h...@perl.org
> http://learn.perl.org/
>
>
>

Reply via email to