#!/usr/bin/perl # NPDaemon_admin - Performance data daemon admin client for Nagios # # Copyright (C) 2007 Mark Steele http://www.control-alt-del.org/code # # Ideas, debugging, documentation by Thomas Guyot-Sionnest # # 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 2 # 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # use IO::Socket::INET; use strict; use Storable qw(thaw); use Curses::UI; use Data::Dumper; ## Grab all the data stored in the server my $DataCache = cmd_DUMP(); # Create the root object and main window. my $cui = new Curses::UI ( -clear_on_exit => 1, -debug => 0, -mouse_support => 1, -color_support => 1 ); $cui->set_binding( sub { exit(0); } , "\cQ"); my $main = $cui->add( undef, 'Window', -title => 'Main Window', ); $main->add( undef, 'Label', -y => $main->height - 1, -width => $main->width, -text => ' / cycles through pages; -Q exits', -textalignment => 'middle', -bold => 1, ); # Create notebook and a couple of pages. my $notebook = $main->add( undef, 'Notebook', -height => $main->height - 1, ); my $nb_commands = $notebook->add_page("Command"); $nb_commands->add( undef, 'Label', -text => 'Please select a command to execute'); $nb_commands->add('cmdlabel','Label',-text=>'Command',-y=>5); $nb_commands->add('serverlabel','Label',-text=>'Server',-y=>5,-x=>25); $nb_commands->add('servicelabel','Label',-text=>'Service',-y=>5,-x=>50); $nb_commands->add('counterlabel','Label',-text=>'Counter',-y=>5,-x=>75); my @Commands = qw(INDEX DUMP QUERY GET HELP CLEAR); my (@services, @servers, @counters); $nb_commands->add( 'cmdlistpopup', 'Popupmenu', -y => 7, -values => \@Commands, -width => 20, ); $nb_commands->add( 'serverlistpopup', 'Popupmenu', -y => 7, -x => 25, -width => 20, -values => \@servers ); $nb_commands->add( 'servicelistpopup', 'Popupmenu', -y => 7, -x => 50, -width => 20, -values => \@services ); $nb_commands->add( 'counterlistpopup', 'Popupmenu', -y => 7, -x => 75, -width => 20, -values => \@counters ); $nb_commands->add( undef, 'Buttonbox', -y => 9, -buttons => [ { -label => "[Execute]", -onpress => \&button_callback, }, { -label => "[Refresh Cache]", -onpress => \&refresh_cache, }, { -label => "[Clear output]", -onpress => sub { my $this = shift; my $cmd_out = $this->parent->getobj('cmd_output'); $cmd_out->text(''); }, }, ], ); refresh_cache(); $nb_commands->add( 'cmd_output','TextViewer', -y => 15, -x => 3, -height => 30, -vscrollbar => 1, ); my $nb_about = $notebook->add_page("About"); $nb_about->add('about_txtvwr','TextViewer',-text=><<'EOF',-vscrollbar=>1); This is the administrative client for PerfDaemon, the perl FIFO/Socket daemon which can be used to feed Cacti the performance data collected by Nagios. Send any questions/comments to mark@zango.com EOF $notebook->focus; # Let user play. $cui->mainloop; sub cmd_DUMP { my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 1111,Proto => 'tcp',Blocking => 1) || die "couldn't connect: $!"; print $sock "DUMP\n"; my $Data; while(<$sock>) { $Data .= $_; } $Data = ${thaw($Data)}; return $Data; } sub cmd_INDEX { my $srv = shift; my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 1111,Proto => 'tcp',Blocking => 1) || die "couldn't connect: $!"; print $sock "INDEX <$srv>\n"; return <$sock>; } sub cmd_CLEAR { my $srv = shift; my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 1111,Proto => 'tcp',Blocking => 1) || die "couldn't connect: $!"; print $sock "CLEAR\n"; return <$sock>; } sub cmd_HELP { my $srv = shift; my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 1111,Proto => 'tcp',Blocking => 1) || die "couldn't connect: $!"; print $sock "HELP\n"; my $buf; while (<$sock>) { $buf .= $_; } return $buf; } sub cmd_QUERY { my ($srv,$svc) = @_; my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 1111,Proto => 'tcp',Blocking => 1) || die "couldn't connect: $!"; print $sock "QUERY <$srv> <$svc>\n"; return <$sock>; } sub cmd_GET { my ($srv,$svc,$cnt) = @_; my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 1111,Proto => 'tcp',Blocking => 1) || die "couldn't connect: $!"; print $sock "GET <$srv> <$svc> <$cnt>\n"; return <$sock>; } sub refresh_cache { my $this = shift; $DataCache = cmd_DUMP(); my %services; my %counters; for (keys %{$DataCache}) { foreach my $svc (keys %{$DataCache->{$_}}) { $services{$svc} = 1; foreach my $cnt (keys %{$DataCache->{$_}->{$svc}->{Data}}) { $counters{$cnt} = 1; } } } @services = keys %services; @counters = keys %counters; @servers = keys %{$DataCache}; $nb_commands->delete('serverlistpopup'); $nb_commands->delete('counterlistpopup'); $nb_commands->delete('servicelistpopup'); $nb_commands->draw(); $nb_commands->add( 'serverlistpopup', 'Popupmenu', -y => 7, -x => 25, -width => 20, -values => \@servers ); $nb_commands->add( 'servicelistpopup', 'Popupmenu', -y => 7, -x => 50, -width => 20, -values => \@services ); $nb_commands->add( 'counterlistpopup', 'Popupmenu', -y => 7, -x => 75, -width => 20, -values => \@counters ); $nb_commands->draw(); } sub button_callback { my $this = shift; my $cmd_p = $this->parent->getobj('cmdlistpopup'); my $srv_p = $this->parent->getobj('serverlistpopup'); my $svc_p = $this->parent->getobj('servicelistpopup'); my $cnt_p = $this->parent->getobj('counterlistpopup'); my $cmd_out = $this->parent->getobj('cmd_output'); if (!$cmd_p->get) { $cui->dialog("ERROR: You must specifiy a command to run"); return; } if ($cmd_p->get eq 'INDEX') { if (!$srv_p->get) { $cui->dialog("Missing server for INDEX command"); return; } $cmd_out->text(''); $cmd_out->text(cmd_INDEX($srv_p->get)); } elsif ($cmd_p->get eq 'QUERY') { if (!$srv_p->get || !$svc_p->get) { $cui->dialog("Missing server or service for QUERY command"); return; } $cmd_out->text(''); $cmd_out->text(cmd_QUERY($srv_p->get,$svc_p->get)); } elsif ($cmd_p->get eq 'GET') { if (!$srv_p->get || !$svc_p->get || !$cnt_p->get) { $cui->dialog("Missing server, service or counter for GET command"); return; } $cmd_out->text(''); $cmd_out->text(cmd_GET($srv_p->get,$svc_p->get,$cnt_p->get)); } elsif ($cmd_p->get eq 'DUMP') { my $d = cmd_DUMP(); $cmd_out->text(Dumper($d)); } elsif ($cmd_p->get eq 'CLEAR') { $cmd_out->text(cmd_CLEAR); } elsif ($cmd_p->get eq 'HELP') { $cmd_out->text(cmd_HELP); } }