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 <[email protected]> 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: [email protected]
> For additional commands, e-mail: [email protected]
> http://learn.perl.org/
>
>
>