Skip to content

Instantly share code, notes, and snippets.

@nemunaire
Last active August 22, 2019 08:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nemunaire/9669659 to your computer and use it in GitHub Desktop.
Save nemunaire/9669659 to your computer and use it in GitHub Desktop.
View in terminal hosts and services states of your domain. This is done by reading a nagios status file.
#!/usr/bin/env perl
#=============================================================================
#
# FILE: status.pl
#
# USAGE: ./status.pl [options]
#
# DESCRIPTION: Give Nagios status about hosts and services
#
# REQUIREMENTS: Perl 5.10.1; Term::ANSIColor
# BUGS: none known
# AUTHOR: nemunaire <nemunaire@nemunai.re>
# CREATED: 03/18/2014 15:55:00
#=============================================================================
use v5.10.1;
use strict;
use warnings;
use utf8;
use open IO => ':utf8';
use open ':std';
use Getopt::Long;
use Pod::Usage;
use Term::ANSIColor;
### COMMAND-LINE #############################################################
our $STATUS_FILE = "/var/nagios/status.dat";
our $ALL_HOSTS = 0;
our $REVERSE_STATE = 0;
our @HOSTS;
our @SERVICES;
our @STATES;
my $help = 0;
GetOptions(
'all-hosts' => \$ALL_HOSTS,
'reverse-state' => \$REVERSE_STATE,
'file=s' => \$STATUS_FILE,
'host|H=s' => \@HOSTS,
'service|S=s' => \@SERVICES,
'state=s' => \@STATES,
'help' => \$help,
) or pod2usage(2);
pod2usage( -exitval => 0, -verbose => 2 ) if $help;
$ALL_HOSTS = 1 if !@HOSTS;
push @SERVICES, ".*" if !@SERVICES;
@STATES = ( "ok", "warning", "critical", "unknown" ) if !@STATES;
### FUNCTIONS ################################################################
sub parseNagiosStatus {
my $statusFile = shift // "/var/nagios/status.dat";
my %data;
open my $sng, "<", $statusFile;
$sng->binmode(":encoding(iso-8859-1)");
while (<$sng>)
{
if (/\s*(\w+)\s*{/) {
my $categ = $1;
my %row;
while (<$sng>) {
if (/}/) {
last;
}
elsif (/^\s*([^= \t]+)\s*=\s*(.*)\s*$/) {
$row{$1} = $2;
}
}
if (exists $data{$categ}) {
push @{ $data{$categ} }, \%row ;
} else {
$data{$categ} = [ \%row ];
}
}
}
close $sng;
return \%data;
}
sub getHoststatus {
my $hostname = shift;
my $data = shift;
for my $host (@{ $data->{hoststatus} }) {
return $host if exists $host->{host_name} and $host->{host_name} eq $hostname;
}
return undef;
}
sub getServicestatus {
my $hostname = shift;
my $data = shift;
my @status;
for my $service (@{ $data->{servicestatus} }) {
push @status, $service if exists $service->{host_name} and $service->{host_name} eq $hostname;
}
return @status;
}
sub displayHost($) {
my $host = shift;
my $state_str = colored("@ UNREACHABLE", "magenta");
$state_str = colored("↑ UP", "green") if ($host->{last_hard_state} == 0);
$state_str = colored("↓ DOWN", "red", "bold") if ($host->{last_hard_state} == 1);
say colored($host->{host_name} . ":", "bold"), " $state_str, ", $host->{plugin_output};
}
sub displayService($) {
my $service = shift;
my $state_str = colored(" ? UNKNOWN", "magenta");
$state_str = colored(" ✓ OK", "green") if ($service->{last_hard_state} == 0);
$state_str = colored(" ! WARNING", "yellow") if ($service->{last_hard_state} == 1);
$state_str = colored("✘ CRITICAL", "red", "bold") if ($service->{last_hard_state} == 2);
say $state_str, " ", colored($service->{service_description} . ": ", "bold"), $service->{plugin_output};
}
### MAIN ################################################################
my $data = parseNagiosStatus($STATUS_FILE);
if ($ALL_HOSTS) {
@HOSTS = ();
for my $host (@{ $data->{hoststatus} }) {
push @HOSTS, $host->{host_name};
}
}
for my $i (0..$#STATES) {
$STATES[$i] = 0 if lc($STATES[$i]) eq "ok";
$STATES[$i] = 1 if lc($STATES[$i]) eq "warning";
$STATES[$i] = 2 if lc($STATES[$i]) eq "critical";
$STATES[$i] = 3 if lc($STATES[$i]) eq "unknown";
}
for my $host (@HOSTS) {
chomp $host;
my $hs = getHoststatus($host, $data);
if ($hs) {
displayHost($hs);
next if ($hs->{last_hard_state} != 0);
for my $service (getServicestatus($host, $data)) {
my $tmp = scalar(grep { $service->{last_hard_state} == int($_) } @STATES) && scalar(grep { $service->{service_description} =~ /$_/i } @SERVICES);
displayService($service) if ($REVERSE_STATE ^ $tmp);
}
print "\n";
}
else {
say "Unknown host '$host'";
}
}
__END__
=head1 NAME
Nagios status CLI - Display hosts and services status through terminal
=head1 SYNOPSIS
./status.pl [OPTIONS]
=head1 OPTIONS
=over
=item B<--all-hosts>
Display all hosts (erase all other --host seen).
=item B<--file=path>
Use the given nagios status file instead of C</var/nagios/status.dat>.
=item B<--help>
Displays the help.
=item B<--host=hostname> B<-H=hostname>
Filter displayed results by hosts. Can be passed many times.
=item B<--reverse-state>
When giving some --service, expect that non-matching services are display instead of matching one.
=item B<--service=regexp> B<-S=regexp>
Filter displayed results by matching services. Can be passed many times.
=item B<--state=[ok|warning|critical|unknown]>
Filter displayed results by service state. Can be passed many times.
=back
=head1 EXIT STATUS
This script always returns 0.
=head1 DEPENDENCIES
=over
=item
perl >= 5.10.1
=item
Term::ANSIColor v5.001+
=back
=head1 AUTHOR
nemunaire <nemunaire@nemunai.re>
=head1 VERSION
This is B<status.pl> version 1.0.
=head1 LICENSE AND COPYRIGHT
B<The GNU GPLv3 License>
Copyright (C) 2014 nemunaire
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
@shqnayaz
Copy link

Would have been more good, If an option to pick hostnames from a file to run a check had been made.
something like ./nagios-status.pl -F=/tmp/hostsfile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment