3 # ----------------------------------------------------------------------
4 # Web interface for Mon.
5 # Arthur K. Chan <artchan@althem.com>
6 # Based on the Mon program by Jim Trocki <trockij@transmeta.com>.
7 # http://www.kernel.org/software/mon/
8 # ----------------------------------------------------------------------
10 # ----------------------------------------------------------------------
12 # Instructions ---------------------------------------------------------
14 # Install this cgi script to whereever your cgi-bin directory sits
15 # on your mon server. If you don't have a web server installed, try
16 # http://www.apache.org.
18 # Modify the "Configurable Parameters" section below to customize it
19 # to your site's settings. Send comment about this web interface to
20 # Art Chan at the address above.
22 # This script will require the CGI perl module. Available at any
23 # perl CPAN site. See http://www.perl.org for details.
26 # Configurable Parameters ----------------------------------------------
28 $organization = ""; # Organization name.
29 $monadmin = ""; # Your e-mail address.
30 $logo = ""; # Company or mon logo.
31 $reload="180"; # Seconds for page reload.
32 $monhost="monhost"; # Mon server hostname.
33 $BGCOLOR = "white"; # Background color
34 $BUTTONCOLOR = "tan"; # Button bar color
36 # You shouldn't need to change these.
37 $url = $ENV{SCRIPT_NAME}; # URL of this script.
39 # General Declarations -------------------------------------------------
41 use CGI; # Use the cgi module.
42 use Mon::Client; # mon client interface
44 %OPSTAT = %Mon::Client::OPSTAT;
46 $webpage = new CGI; # Declare instance of mod.
48 $time = time; # This will be used for
49 $localtime = localtime(time); # the time on the page.
52 # Reverse sort ---------------------------------------------------------
57 # Return untainted host or group name if safe, undef otherwise ---------
59 return $_[0] =~ /^([\w.\-_]+)$/ ? $1 : undef;
63 # Setup the html doc headers and such ----------------------------------
66 print $webpage->header;
67 print $webpage->start_html(-title=>"MON - $title",
69 print $webpage->h1("MON $title");
71 $webpage->print("\n<img src=\"$logo\"><br><br>\n");
74 print $webpage->h3("$organization");
79 @time = localtime($qtime);
80 my $ttime = sprintf ("%.2d:%.2d:%.2d", $time[2],$time[1],$time[0]);
81 print $webpage->center
82 ("\nThis information was presented at: $ttime. ");
86 # Print the button bar -------------------------------------------------
88 $button = "INPUT TYPE=\"submit\" NAME=\"command\"";
89 $webpage->print("\n\n<FORM METHOD=\"GET\">\n");
90 $webpage->print("<table bgcolor=$BUTTONCOLOR width=75% border=1 align=center>\n");
91 $webpage->print("<tr>\n");
92 $webpage->print("\t<td width=3 align=center>Show Operation Status</td>\n");
93 $webpage->print("\t<td width=3 align=center>Show Alert History</td>\n");
94 $webpage->print("\t<td width=3 align=center>Disable/Enable monitoring.</td>\n");
95 $webpage->print("\t<td width=3 align=center>List Disabled Hosts</td>\n");
96 $webpage->print("\t<td width=3 align=center>List PIDs for mon processes.</td>\n");
97 $webpage->print("\t<td width=3 align=center>Restart Mon</td>\n");
98 $webpage->print("</tr>\n");
99 $webpage->print("\t<tr><td width=3 align=center><$button VALUE=\"opstatus\"></td>\n");
100 $webpage->print("\t<td width=3 align=center><$button VALUE=\"alerthist\"></td>\n");
101 $webpage->print("\t<td width=3 align=center><$button VALUE=\"disable\"></td>\n");
102 $webpage->print("\t<td width=3 align=center><$button VALUE=\"disabled\"></td>\n");
103 $webpage->print("\t<td width=3 align=center><$button VALUE=\"pids\"></td>\n");
104 $webpage->print("\t<td width=3 align=center><$button VALUE=\"reset\"></td>\n");
105 $webpage->print("</tr></table>");
107 $webpage->print("</form>\n");
111 # query the server operational status ----------------------------------
114 print $webpage->center
115 ("This page will reload every $reload seconds.<br><br>\n");
116 $webpage->print("\n<META HTTP-EQUIV=\"Refresh\"");
117 $webpage->print("CONTENT=\"$reload\", URL=\"$url\">\n");
119 my $c = new Mon::Client (
125 if ($c->error ne "") {
126 # ignore the error for now :(
129 my %op = $c->list_opstatus();
131 if ($c->error ne "") {
132 # ignore the error for now :(
137 $webpage->print("<table align=center border=1 width=35%>");
139 ("<tr><td><font color=black>Service color legend:</font></td>\n");
140 $webpage->print("<td><font color=black>Unchecked</font></td>\n");
141 $webpage->print("<td><font color=green>Good</font></td>\n ");
142 $webpage->print("<td><font color=red>Error</font></td></tr>\n");
143 $webpage->print("</table>");
146 ("<table align=center width=80% border=1>\n");
148 ("<tr><th>Host Group</th><th>Service</th>\n");
150 ("<th>Last Checked</th><th>Est. Next Check</th></tr>\n");
152 foreach my $group (sort keys %op) {
153 foreach my $service (sort keys %{$op{$group}}) {
155 my $s = \%{$op{$group}->{$service}};
157 $webpage->print("<tr><td>\n");
159 ("<a href=\"$url?command=group&args=$group\">");
160 $webpage->print("$group</a></td>\n");
162 if ($s->{"opstatus"} == $OPSTAT{"untested"}) {
163 $webpage->print("<td><font color=black>\n");
164 $webpage->print("$service</font></td>");
166 } elsif ($s->{"opstatus"} == $OPSTAT{"fail"}) {
167 $webpage->print("<td><blink>");
169 ("<a href=\"$url?command=alert&args=$group,$service\">");
171 ("<font color=red>$service</font></a></blink></td>\n");
173 } elsif ($s->{"opstatus"} == $OPSTAT{"ok"}) {
174 $webpage->print("<td><font color=green>");
175 $webpage->print("$service</font></td>\n");
180 $txt = $_ if ($s->{"opstatus"} == $OPSTAT{$_});
182 $webpage->print("<td><font color=purple>");
183 $webpage->print("$service ($txt)</font></td>\n");
186 if ($s->{"opstatus"} == $OPSTAT{"untested"}) {
187 $webpage->print("<td>-</td>");
190 my @time = localtime ($s->{"last_check"});
192 sprintf ("<td>%.2d:%.2d:%.2d</td>\n", @time[2, 1, 0])
196 my @time = localtime ($qtime+$s->{"next"});
198 sprintf ("<td>%.2d:%.2d:%.2d</td>\n", @time[2, 1, 0])
200 $webpage->print("</tr>");
203 $webpage->print("</table>\n");
207 # Extract the list of hosts associated with the group ---------------
210 my $group = &validate_name ($args);
212 if (!defined $group) {
213 $webpage->print("Invalid host group\n");
216 my $c = new Mon::Client (
222 if ($c->error ne "") {
223 # ignore error for now
226 @hosts = $c->list_group ($group);
228 if ($c->error ne "") {
230 $webpage->print (<<"EOF"
232 Could not list groups: $e
241 $webpage->print("<table align=center width=50% border=1>");
242 $webpage->print("<th>Members of group \"<em>$group</em>\".</th>") ;
244 foreach my $host (sort @hosts) {
245 $webpage->print("<tr><td>$host</td></tr>") ;
247 $webpage->print("</table>");
252 # End the document -----------------------------------------------------
256 print $webpage->center("For questions about this server. Contact:");
257 print $webpage->center
258 ("<a href=\"mailto:$monadmin\">$monadmin</a><br>");
260 print $webpage->end_html;
264 # Get the params from the form -----------------------------------------
266 $command = $webpage->param('command');
267 $args = $webpage->param('args');
268 $enable_host = $webpage->param('enablehost');
269 $enable_group = $webpage->param('enablegroup');
270 $enable_service = $webpage->param('enableservice');
271 $enable_watch = $webpage->param('enablewatch');
273 $disable_host = $webpage->param('disablehost');
274 $disable_group = $webpage->param('disablegroup');
275 $disable_service = $webpage->param('disableservice');
276 $disable_watch = $webpage->param('disablewatch');
280 # What to do if the view alert details is depressed --------------------
284 my ($group, $service) = split (/\,/, $arg);
288 ("<h2>Failure detail for group <font color=red>$group</font> ");
290 ("and service <i>$service</i> test:</h2>");
292 my $c = new Mon::Client (
298 if ($c->error ne "") {
299 # ignore errors for now
302 my %op = $c->list_opstatus();
304 if ($c->error ne "") {
305 # ignore errors for now
310 foreach my $g (keys %op) {
311 next if ($g ne $group);
312 foreach my $s (keys %{$op{$g}}) {
313 next if ($s ne $service);
314 $webpage->print("$op{$g}->{$s}->{last_summary}\n");
322 # List alert history --------------------------------------------------
325 print $webpage->h2("Alert History:");
327 my $c = new Mon::Client (
333 if ($c->error ne "") {
337 my @l = $c->list_alerthist();
341 $webpage->print("<table border=1 width=80% align=center>\n");
343 $webpage->print("<tr><th>Group</th><th>Service</th>\n");
344 $webpage->print("<th>Type</th><th>Time</th><th>Alert</th>\n");
345 $webpage->print("<th>Args</th><th>Summary</th>\n");
346 $webpage->print("</tr>\n");
348 foreach my $line (reverse sort {$a->{"time"} <=> $b->{"time"}} (@l)) {
349 my $localtime = localtime ($line->{"time"});
351 $webpage->print("<tr><td><a href=\"$url?command=group&");
352 $webpage->print("args=$line->{group}\">$line->{group}</a></td>");
354 $webpage->print("<td>$line->{service}</td>\n");
355 $webpage->print("<td>$line->{type}</td>\n");
356 $webpage->print("<td>$localtime</td>\n");
358 $line->{"alert"} =~ s{^.*\/([^/]*)$}{$1};
360 $webpage->print("<td>$line->{alert}</td>\n");
363 if ($line->{"args"} !~ /^\s*$/) {
364 $args = $line->{"args"};
367 $webpage->print("<td>$args</td>\n");
368 $webpage->print("<td>$line->{summary}</td>");
370 $webpage->print("</tr>\n");
373 $webpage->print("</table>\n");
378 # Generic button function ---------------------------------------------
380 local ($title, $command) = @_;
383 print $webpage->h2("$title");
384 print "(command not implemented in this client)\n";
389 # Form to get item to disable -------------------------------------------
392 print $webpage->h2("$title");
394 $webpage->print ("(command not implemented in this client)\n");
400 my ($desc, $cmd, @arg);
402 $desc = "Attempting to disable a host";
403 $cmd = "disable host";
404 push @arg, $disable_host;
405 } elsif (($disable_group) && ($disable_service)) {
406 $desc = "Attempting to disable a service";
407 $cmd = "disable service";
408 push @arg, $disable_group, $disable_service;
409 } elsif ($disable_watch) {
410 $desc = "Disable a watch";
411 $cmd = "disable watch";
412 push @arg, $disable_watch;
413 } elsif ($enable_host) {
414 $desc = "Attempting to enable a host";
415 $cmd = "enable host";
416 push @arg, $enable_host;
417 } elsif (($enable_group) && ($enable_service)) {
418 $desc = "Attempting to enable a service";
419 $cmd = "enable service";
420 push @arg, $enable_group, $enable_service;
421 } elsif ($enable_watch) {
422 $desc = "Enable a watch";
423 $cmd = "enable watch";
424 push @arg, $enable_watch;
429 $_ = &validate_name($_);
430 $bad = 1 if !defined $_;
433 # Don't try to print out the invalid arg, it wouldn't be
435 print "Invalid argument for $cmd.\n";
438 print "$desc: @arg<br>\n";
442 open (MON, "$moncmd -s $monhost $cmd|");
451 print "<table width=100%>";
453 print $webpage->startform(GET);
454 print "Disable a host.<br>\n";
455 print $webpage->textfield('disablehost');
456 print " Hostname<br>";
457 print $webpage->submit(-name=>'command',-value=>'disable');
458 print $webpage->endform;
460 print $webpage->startform(GET);
461 print "Enable a host.<br>\n";
462 print $webpage->textfield('enablehost');
463 print " Hostname<br>";
464 print $webpage->submit(-name=>'command',-value=>'enable');
465 print $webpage->endform;
466 print "</td></table>";
469 print "<table width=100%>";
471 print $webpage->startform(GET);
472 print "Disable a service for a group.<br>\n";
473 print $webpage->textfield('disablegroup');
475 print $webpage->textfield('disableservice');
476 print " Service<br>";
477 print $webpage->submit(-name=>'command',-value=>'disable');
478 print $webpage->endform;
480 print $webpage->startform(GET);
481 print "Enable a service for a group.<br>\n";
482 print $webpage->textfield('enablegroup');
484 print $webpage->textfield('enableservice');
485 print " Service<br>";
486 print $webpage->submit(-name=>'command',-value=>'enable');
487 print $webpage->endform;
488 print "</td></table>";
491 print "<table width=100%>";
493 print $webpage->startform(GET);
494 print "Disable a watch.<br>\n";
495 print $webpage->textfield('disablewatch');
497 print $webpage->submit(-name=>'command',-value=>'disable');
498 print $webpage->endform;
500 print $webpage->startform(GET);
501 print "Enable a watch.<br>\n";
502 print $webpage->textfield('enablewatch');
504 print $webpage->submit(-name=>'command',-value=>'enable');
505 print $webpage->endform;
506 print "</td></table>";
512 # Main program ---------------------------------------------------------
514 &get_params; # Read the args.
516 if ($command =~ "group" ){ # Expand hostgroup.
517 &setup_page("Group Expansion");
520 elsif ($command =~ "alerthist"){ # Alert history button.
521 &setup_page("List the alert history");
524 elsif ($command =~ "alert"){ # View alert details.
525 &setup_page("Alert Details");
528 elsif ($command =~ "disabled"){ # Disabled hosts button.
529 &setup_page("List disabled hosts");
530 &button("Disabled hosts:","list disabled");
532 elsif ($command =~ "disable"){ # Disabled
533 &setup_page("Disable/Enable alert for host, group. or service");
536 elsif ($command =~ "enable"){ # Disabled
537 &setup_page("Disable/Enable alert for host, group. or service");
540 elsif ($command =~ "pids"){ # View pid button.
541 &setup_page("List pids of server, alerts and monitors.");
542 &button("List pids for all mon processes:", "list pids");
544 elsif ($command =~ "reset"){ # Reset mon button.
545 &setup_page("Restart Mon.");
546 &button("Attempting to reset mon...","reset");
548 # Button "opstatus" will fall through to else.
550 &setup_page("Operation Status");
557 # That's it! ----------------------------------------------------