source: trunk/nagios-velvice/velvice.cgi @ 433

Last change on this file since 433 was 433, checked in by g7moreau, 4 years ago
  • Show Unknow to add button force
  • Property svn:keywords set to Id
File size: 23.9 KB
Line 
1#!/usr/bin/env perl
2#
3# 2014/05/15 Gabriel Moreau <Gabriel.Moreau@univ-grenoble-alpes.fr>
4# 2017/06/22 Gabriel Moreau - big update
5# 2018/06/25 Gabriel Moreau - make velvice generic
6# 2018/11/03 Gabriel Moreau - ajax
7#
8# velvice.cgi
9# Copyright (C) 2014-2019, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France
10#
11# Need NagiosStatus http://exchange.nagios.org/directory/Addons/APIs/Perl/NagiosStatus-2Epm/details
12# Possible command http://old.nagios.org/developerinfo/externalcommands/commandlist.php
13#
14# apt-get install perl-modules libnagios-object-perl libhtml-parser-perl liburi-encode-perl libcolor-calc-perl libyaml-syck-perl
15# apt-get install libdatetime-event-recurrence-perl libdatetime-set-perl
16
17use strict;
18use warnings;
19use version; our $VERSION = version->declare('0.11.2');
20
21use CGI;
22use HTML::Entities ();
23use Nagios::StatusLog;
24use URI::Encode qw(uri_encode uri_decode);
25use Color::Calc ();
26use YAML::Syck;
27
28my $query           = CGI->new();
29my $cgi_check       = uri_decode($query->param('check')) || '';
30my $cgi_script_name = $query->script_name();
31my $cgi_path        = $cgi_script_name =~ s{/[^/]+\.cgi$}{}r;
32my $param_only      = uri_decode($query->param('only')) || '';
33my $cgi_only;
34$cgi_only++ if $param_only eq 'body';
35undef $query;
36undef $param_only;
37
38my %STATUS_DB = (
39   CRITICAL => {id => 5, color => '#F88888'},
40   UNKNOWN  => {id => 4, color => '#FFBB55'},  # #4488FF
41   WARNING  => {id => 3, color => '#FFFF00'},
42   PENDING  => {id => 2, color => '#E0E0E0'},
43   OK       => {id => 1, color => '#88D066'},
44   );
45
46my $config = {};
47$config = YAML::Syck::LoadFile('/etc/nagios3/velvice.yml') if -e '/etc/nagios3/velvice.yml';
48$config->{'nagios-server'}                ||= {};
49$config->{'nagios-server'}{'status-file'} ||= '/var/cache/nagios3/status.dat';
50$config->{'nagios-server'}{'nagios-cmd'}  ||= '/var/lib/nagios3/rw/nagios.cmd';
51$config->{'nagios-server'}{'portal-url'}  ||= $cgi_path =~ s{/cgi-bin/}{/}r . '/';
52$config->{'nagios-server'}{'status-cgi'}  ||= "$cgi_path/status.cgi";
53$config->{'nagios-server'}{'stylesheets'} ||= $config->{'nagios-server'}{'portal-url'} =~ s{/?$}{/stylesheets}r;
54$config->{'nagios-server'}{'image'}       ||= $config->{'nagios-server'}{'portal-url'} =~ s{/?$}{/images}r;
55$config->{'host-mapping'}                 ||= {};
56$config->{'color-downtime'}               ||= {};
57$config->{'color-downtime'}{'day-min'}    ||=  3;
58$config->{'color-downtime'}{'day-max'}    ||= 50;
59$config->{'color-downtime'}{'factor'}     ||=  0.7;
60$config->{'remote-action'}                ||= {};
61$config->{'refresh'}                      ||=  0;
62
63sub hostmapping {
64   my $host = shift;
65
66   return exists $config->{'host-mapping'}{$host} ? $config->{'host-mapping'}{$host} : $host;
67   }
68
69sub downtime {
70   my ($time_change) = @_;
71
72   my $now = time;
73   return sprintf '%.1f', ($now - $time_change) / (60 * 3600);
74   }
75
76sub alertcolor {
77   my ($status, $downtime) = @_;
78
79   my $color = '#0000FF';
80   $color = $STATUS_DB{$status}->{'color'} if exists $STATUS_DB{$status};
81
82   $downtime = $downtime - $config->{'color-downtime'}{'day-min'}; # same color first days
83   $downtime = $config->{'color-downtime'}{'day-max'} if $downtime > $config->{'color-downtime'}{'day-max'}; # max 50 days for color
84   $downtime =  0 if $downtime <  0;
85
86   my $factor = ($downtime * $config->{'color-downtime'}{'factor'}) / $config->{'color-downtime'}{'day-max'};
87   return Color::Calc::color_light_html($color, $factor);
88   }
89
90sub nosbreak {
91   my ($str) = @_;
92   
93   return $str =~ s/\s/\&nbsp;/gr;
94   }
95
96my $log = Nagios::StatusLog->new(
97   Filename => $config->{'nagios-server'}{'status-file'},
98   Version  => 3.0
99   );
100
101# refresh configuration
102if (exists $config->{'refreshments'}) {
103   require DateTime::Event::Recurrence;
104   require DateTime::SpanSet;
105
106   my @refreshments;
107   SET:
108   for my $set (@{$config->{'refreshments'}}) {
109      my $start   = DateTime::Event::Recurrence->weekly(days => $set->{'days'}, hours => $set->{'start'});
110      my $end     = DateTime::Event::Recurrence->weekly(days => $set->{'days'}, hours => $set->{'end'});
111      my $spanset = DateTime::SpanSet->from_sets(start_set => $start, end_set => $end);
112      push @refreshments, {refresh => $set->{'refresh'}, spanset => $spanset};
113      }
114
115   my $now = DateTime->now(time_zone => 'local');
116   SET:
117   for my $set (@refreshments) {
118      next SET if not $set->{'spanset'}->contains($now);
119 
120      $config->{'refresh'} = $set->{'refresh'};
121      last SET;
122      }
123   }
124
125my %hostdown;
126my @serviceproblems;
127my %hostcount;
128my @futurecheck;
129HOST:
130for my $host (sort $log->list_hosts()) {
131   my $host_stat = $log->host($host);
132
133   if ($host_stat->status eq 'DOWN') {TESTIF:{
134      for my $srv ($log->list_services_on_host($host)) {
135         last TESTIF if $log->service($host, $srv)->status eq 'OK' or $log->service($host, $srv)->status eq 'PENDING';
136         }
137
138      $hostdown{$host} = $host_stat;
139      next HOST;
140      }}
141
142   SRV:
143   for my $srv ($log->list_services_on_host($host)) {
144      my $status = $log->service($host, $srv)->status;
145
146      next SRV if $status eq 'OK';
147
148      push @serviceproblems, $log->service($host, $srv);
149   
150      my $downtime = downtime($log->service($host, $srv)->last_state_change);
151      my $color    = alertcolor($status, $downtime);
152
153      my $status_id = 0;
154      $status_id = $STATUS_DB{$status}->{'id'} if exists $STATUS_DB{$status};
155
156      #$hostcount{$host}++;
157      $hostcount{$host} ||= {count => 0, color => $color, status_id => $status_id, downtime => $downtime};
158      $hostcount{$host}->{'count'}++;
159      if (($status_id > $hostcount{$host}->{'status_id'})
160            or (($status_id == $hostcount{$host}->{'status_id'}) and ($downtime < $hostcount{$host}->{'downtime'}))) {
161         $hostcount{$host}->{'downtime'}  = $downtime;
162         $hostcount{$host}->{'status_id'} = $status_id;
163         $hostcount{$host}->{'color'}     = $color;
164         }
165      }
166   }
167
168my $now = time;
169my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $now;
170$year += 1900;
171$mon++;
172# my $date_sec = sprintf '%04i-%02i-%02i %02i:%02i:%02i', $year, $mon, $mday, $hour, $min, $sec;
173my $date_min = nosbreak(sprintf '%04i-%02i-%02i %02i:%02i', $year, $mon, $mday, $hour, $min);
174
175my $htmlpage;
176
177$htmlpage .= <<"ENDH" if not $cgi_only;
178Content-Type: text/html
179
180<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
181<html lang="en">
182<head>
183 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
184ENDH
185
186$htmlpage .= <<"ENDH" if $cgi_only;
187Content-Type: text/xml
188
189<?xml version="1.0" encoding="utf-8"?>
190<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
191ENDH
192
193#$htmlpage .= " <meta http-equiv=\"Refresh\" content=\"$config->{'refresh'}\">" if $config->{'refresh'} > 59; # minimum 1 min
194$htmlpage .= <<"ENDH" if not $cgi_only;
195 <title>Nagios  Velvice</title>
196 <link rel="stylesheet"    type="text/css"  href="$config->{'nagios-server'}{'stylesheets'}/velvice.css">
197 <link rel="shortcut icon" type="image/ico" href="$config->{'nagios-server'}{'image'}/favicon.ico">
198 <script type="text/javascript">
199   var refresh_sec = 900; // 15 min = 900 s
200   var refresh_interval;
201   function refresh() {
202      var req = new XMLHttpRequest();
203      var datenow = new Date();
204      console.log("Grabbing Value");
205      req.open("GET", '$cgi_script_name?only=body', true); // Grabs whatever you've written in this file
206      req.onload = function () {
207         if (req.status == 200) {
208            document.getElementById('master-body').innerHTML = req.responseXML.getElementById('master-body').innerHTML;
209            console.log("Update Page at", datenow.toLocaleTimeString());
210
211            refresh_next = req.responseXML.getElementById('master-body').getAttribute("refresh");
212            if (refresh_next < 60 && refresh_next != 0) {
213               refresh_next = 60;
214               }
215            if (refresh_next != refresh_sec) {
216               refresh_sec = refresh_next;
217               clearInterval(refresh_interval);
218               refresh_interval = setInterval(refresh, refresh_sec * 1000);
219               console.log("Update at", datenow.toLocaleTimeString(), "Refresh Interval:", refresh_sec);
220               document.getElementById('master-body').setAttribute("refresh", refresh_sec);
221               }
222            }
223         }
224      req.send(null);
225      }
226
227   function init() { // This is the function the browser first runs when it's loaded.
228      refresh_sec = document.getElementById('master-body').getAttribute("refresh");
229      if (refresh_sec < 60 && refresh_sec != 0) {
230         refresh_sec = 60;
231         }
232      // Set the refresh() function to run every 900 seconds. 1 second would be 1000
233      refresh_interval = setInterval(refresh, refresh_sec * 1000);
234      console.log("Start Refresh Interval:", refresh_sec);
235      }
236</script>
237</head>
238ENDH
239
240$htmlpage .= <<"ENDH";
241<body id="master-body" onload="init()" refresh="$config->{'refresh'}">
242<div class="header">
243 <h1>
244  <ul>
245    <li>Nagios Velvice Alert Panel : <a href="$config->{'nagios-server'}{'portal-url'}" target="_blank">Core Server</a></li>
246    <li><small><a id="refresh" href="$cgi_script_name">$date_min</a></small></li>
247  </ul>
248 </h1>
249</div>
250ENDH
251
252my %service_name   = ();
253my %service_status = ();
254for my $srv (@serviceproblems) {
255   $service_name{$srv->service_description}++;
256   $service_status{$srv->status}++;
257   }
258
259if (scalar @serviceproblems == 0) {
260   $htmlpage .= "<p>No alert to recheck.</p>\n";
261   }
262else {
263
264   $htmlpage .= "<p>Alert to recheck - Level:\n";
265   $htmlpage .= join ",\n",
266      " <span class='button'><a href='$cgi_script_name?check=all'>ALL</a><small>" . scalar(@serviceproblems) . '</small></span>',
267      map(" <span class='button'><a href='$cgi_script_name?check=" . lc(uri_encode($_)) . "'>$_</a><small>$service_status{$_}</small></span>",
268         sort keys %service_status);
269   $htmlpage .= ".\n";
270   $htmlpage .= " <br />\n";
271   $htmlpage .= " Service:\n";
272   $htmlpage .= join ",\n",
273      map(" <span class='button'><a href='$cgi_script_name?check=" . lc(uri_encode($_)) . "'>" . nosbreak($_) . "</a><small>$service_name{$_}</small></span>",
274         sort keys %service_name);
275   $htmlpage .= ".\n";
276   $htmlpage .= "</p>\n";
277
278   my $nagios_cmd;
279   open $nagios_cmd, '>>', $config->{'nagios-server'}{'nagios-cmd'} or die "Can't open file filename: $!";
280
281   my %remote_sshdown = ();
282   my %remote_db      = ();
283   my $remote_flag;
284
285   my $current_host  = '';
286   $htmlpage .= "<table border=\"1\">\n";
287   SERVICE_PROBLEMS:
288   for my $srv (@serviceproblems) {
289      my $hostname = $srv->host_name;
290      my $service  = $srv->service_description;
291      my $status   = $srv->status;
292      my $downtime = downtime($srv->last_state_change);
293      my $output   = HTML::Entities::encode($srv->plugin_output) =~ s/^[A-Z_\s]+?[:-]//r;
294
295      my $color = alertcolor($status, $downtime);
296      my $stylecolor = "style='background:$color;'";
297      $htmlpage .= " <tr>\n";
298      if ($hostname ne $current_host) {
299         $current_host  = $hostname;
300         my $rowspan    = $hostcount{$hostname}->{'count'};
301         my $rowcolor   = "style='background:" . $hostcount{$hostname}->{'color'} . ";'";
302         $htmlpage .= "  <td $rowcolor rowspan='$rowspan'>"
303            . "<a href=\"$cgi_script_name?check=" . uri_encode($hostname) . '">&#8623;</a></td>' . "\n";
304         $htmlpage .= "  <td $rowcolor class='hoop' rowspan='$rowspan'>"
305            . "<a href=\"$config->{'nagios-server'}{'status-cgi'}?host=" . uri_encode($hostname) . "\" target=\"_blank\">$hostname</a></td>\n";
306         }
307
308      my $bold;
309      ACTION_STYLE:
310      for my $act_name (keys %{$config->{'remote-action'}}) {
311         my $act_regex = $config->{'remote-action'}{$act_name}{'regex'};
312         my $act_style = $config->{'remote-action'}{$act_name}{'style'} || '';
313         $bold++ if $service =~ m/$act_regex/ and $act_style eq 'bold';
314         }
315      $htmlpage .= $bold ? "  <td $stylecolor class='hoop bold'>" : "  <td $stylecolor class='hoop'>";
316      $htmlpage .= "$service</td>\n";
317
318      $htmlpage .= "  <td $stylecolor class='hoop'>$status</td>\n";
319      $htmlpage .= "  <td $stylecolor class='comment'>$output</td>\n";
320      $htmlpage .= "  <td $stylecolor class='days'>$downtime days</td>\n";
321
322      if (($cgi_check =~ m/all/i)
323            or ($cgi_check =~ m/^$service$/i)
324            or ($cgi_check =~ m/critical/i and $status eq 'CRITICAL')
325            or ($cgi_check =~ m/unknown/i  and $status eq 'UNKNOWN')
326            or ($cgi_check =~ m/warning/i  and $status eq 'WARNING')
327            or ($cgi_check =~ m/pending/i  and $status eq 'PENDING')
328            or ($cgi_check eq $hostname    and $status =~ m/^(CRITICAL|UNKNOWN|WARNING|PENDING)$/)
329            ) {
330         $now++;
331         my $interval = $srv->next_check() - $srv->last_check() || 300; # 5 * 60 = 300
332         $interval =  240 if $interval <  240;
333         $interval = 3000 if $interval > 3000;
334         my $future = $now + 20 + int(rand($interval - 20));
335
336         $htmlpage .= "  <td class='checking'>" . ($future - $now) . "</td>\n";
337         #$htmlpage .= " -- <b>CHECK</b> [$now/" . ($future - $now) . "]";
338         printf $nagios_cmd "[%lu] SCHEDULE_FORCED_SVC_CHECK;%s;%s;%lu\n", $now, $hostname, $service, $now;
339         # delay future command
340         push @futurecheck, sprintf "[%lu] SCHEDULE_FORCED_SVC_CHECK;%s;%s;%lu", $future, $hostname, $service, $future;
341         }
342
343      ACTION_PUSH_AND_DEPEND:
344      for my $act_name (keys %{$config->{'remote-action'}}) {
345         my $act_regex  = $config->{'remote-action'}{$act_name}{'regex'};
346         my $act_status = $config->{'remote-action'}{$act_name}{'status'} || 'ALL';
347         my $act_depend = $config->{'remote-action'}{$act_name}{'depend'} || 'SSH';
348
349         if ($service =~ m/$act_regex/ and ($act_status eq 'ALL' or $status =~ m/$act_status/)) {
350            $remote_db{$act_name} ||= [];
351            push @{$remote_db{$act_name}}, $hostname;
352            $remote_flag++;
353            }
354
355         # check depend service otherwise
356         $remote_sshdown{$act_depend} ||= {};
357         $remote_sshdown{$act_depend}->{$hostname}++ if $service =~ m/$act_depend/;
358         }
359
360      $htmlpage .= " </tr>\n";
361      }
362
363   $htmlpage .= "</table>\n";
364   close $nagios_cmd;
365
366   # host down
367   if (%hostdown) {
368      $htmlpage .= "<br />\n";
369      $htmlpage .= "<table border='1'>\n";
370      HOST_DOWN:
371      for my $host (sort keys %hostdown) {
372         my $host_stat = $hostdown{$host};
373         my $hostname = $host_stat->host_name;
374         my $downtime = downtime($host_stat->last_state_change);
375         my $color = alertcolor('CRITICAL', $downtime);
376         my $stylecolor = "style='background:$color;'";
377         $htmlpage .= " <tr>\n";
378         $htmlpage .= "  <td $stylecolor>" . "<a href=\"$cgi_script_name?check=" . uri_encode($hostname) . '">&#8623;</a></td>' . "\n";
379         $htmlpage .= "  <td $stylecolor class='hoop'><a href=\"$config->{'nagios-server'}{'status-cgi'}?host=" . uri_encode($hostname) . "\" target=\"_blank\">$hostname</a></td>\n";
380         my @host_service;
381         for my $srv ($log->list_services_on_host($host)) {
382            my $service = $log->service($host, $srv)->service_description;
383            push @host_service, $service;
384            if ($cgi_check eq $hostname) {
385               $now++;
386               printf $nagios_cmd "[%lu] SCHEDULE_FORCED_SVC_CHECK;%s;%s;%lu\n", $now, $hostname, $service, $now;
387               }
388            }
389         $htmlpage .= "  <td $stylecolor><small>" . join(', ', @host_service) . "</small></td>\n";
390         $htmlpage .= "  <td style='background:$color; text-align:right;'>$downtime days</td>\n";
391         $htmlpage .= "  <td class='checking'></td>\n" if $cgi_check eq $hostname;
392         $htmlpage .= " </tr>\n";
393         }
394      $htmlpage .= "</table>\n";
395      }
396
397   # remote action
398   if ($remote_flag) {
399      require Nagios::Object::Config;
400      my $parser = Nagios::Object::Config->new();
401      $parser->parse("/var/cache/nagios3/objects.cache");
402
403      $htmlpage .= "<div class='action'>\n";
404      REMOTE_ACTION:
405      for my $act_name (keys %remote_db) {
406         my $act_depend = $config->{'remote-action'}{$act_name}{'depend'} || 'SSH';
407
408         my @action = grep !exists $remote_sshdown{$act_depend}->{$_}, @{$remote_db{$act_name}};
409         if (@action) {
410            my $srv_title = $config->{'remote-action'}{$act_name}{'title'} || "Action: $act_name";
411            $htmlpage .= "<h2>$srv_title</h2>\n";
412            $htmlpage .= "<pre>\n";
413            my $remote_action = $config->{'remote-action'}{$act_name}{'command'};
414            $remote_action = $config->{'remote-action'}{$act_name}{'command-one'}
415               if @action == 1 and exists $config->{'remote-action'}{$act_name}{'command-one'};
416            my @hosts;
417            for my $host (@action) {
418               my $object = $parser->find_object("$host", "Nagios::Host");
419               push @hosts, hostmapping($object->address =~ s/\..*$//r);
420               }
421            my $hosts_list = join ' ', @hosts;
422            $htmlpage .= ' ' . $remote_action =~ s{\%m}{$hosts_list}r;
423            $htmlpage .= "</pre>\n";
424            }
425         }
426      $htmlpage .= "</div>\n";
427      }
428   }
429
430$htmlpage .= <<"ENDH";
431<hr clear="all" />
432<div class="footer">
433 <b><a href="http://servforge.legi.grenoble-inp.fr/projects/soft-trokata/wiki/SoftWare/NagiosVelvice">Velvice</a>
434   - version: $VERSION</b>
435   (<a href="http://servforge.legi.grenoble-inp.fr/pub/soft-trokata/nagios-velvice/velvice.html">online manual</a>)
436   - Written by Gabriel Moreau
437 <ul>
438  <li>Licence GNU GPL version 2 or later and Perl equivalent</li>
439  <li>Copyright (C) 2014-2019, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France</li>
440 </ul>
441</div>
442</body>
443ENDH
444
445$htmlpage .= <<"ENDH" if not $cgi_only;
446</html>
447ENDH
448
449print $htmlpage;
450
451# delayed future check
452if (@futurecheck) {
453   sleep 2;
454   my $nagios_cmd;
455   open $nagios_cmd, '>>', $config->{'nagios-server'}{'nagios-cmd'} or die "Can't open file filename: $!";
456   print $nagios_cmd "$_\n" for @futurecheck;
457   close $nagios_cmd;
458   }
459
460__END__
461
462
463=head1 NAME
464
465velvice.cgi - nagios velvice alert panel
466
467=head1 USAGE
468
469 velvice.cgi
470 velvice.cgi?check=XXX
471
472
473=head1 DESCRIPTION
474
475=begin html
476
477<img width="700" alt="Nagios Velvice Alert Panel" title="Nagios Velvice Alert Panel" style="float:right;" src="velvice.png" />
478
479=end html
480
481Nagios VELVICE is an acronym for "Nagios leVEL serVICE status".
482
483The Nagios web page is sometimes very graphically charged
484and does not necessarily contain the information you need at a glance.
485For example, it is quite complicated to restart controls on multiple hosts in one click.
486
487For example, a server that is down should take only one line and not one per service...
488Similarly, a service that has been down for 5 minutes or since yesterday
489has more weight than a service that has fallen for 15 days.
490
491With Velvice Panel, a broken down server takes only one line.
492Services that have been falling for a long time gradually lose their color and become pastel colors.
493
494With Velvice Panel, it is possible through a single click
495to redo a check of all services that are in the CRITICAL state.
496Similarly, it is possible to restart a check on all SSH services in breakdowns ...
497In order not to clog the Nagios server, checks are shifted by 2 seconds in time.
498
499There is also a link to the web page of the main Nagios server.
500For each computer, you have a direct link to its dedicated web page on this server.
501
502
503=head1 CONFIGURATION FILE SPECIFICATION
504
505The configuration file must be F</etc/nagios3/velvice.yml>.
506This is not a required file.
507The file is in YAML format because this is a human-readable text file style.
508Other formats could have been Plain XML, RDF, JSON... but they are much less readable.
509
510You can find in the software nagios-velvice an example of configuration:
511L<velvice.sample.yml|http://servforge.legi.grenoble-inp.fr/pub/soft-trokata/nagios-velvice/velvice.sample.yml>.
512This one is in fact the master reference specification!
513
514The main keys C<nagios-server> and C<color-downtime> have good default values.
515No secondary key is required...
516The Velvice script try hard to replace ~ by the good value automatically.
517
518 nagios-server:
519   status-file: /var/cache/nagios3/status.dat
520   nagios-cmd:  /var/lib/nagios3/rw/nagios.cmd
521   portal-url:  ~/nagios3/
522   status-cgi:  ~/cgi-bin/nagios3/status.cgi
523   stylesheets: ~/nagios3/stylesheets
524
525The background color of the faulty service line display remains stable with a bright color for at least 3 days.
526Then, it decreases and becomes pastel after 53 days with an intensity of 70% (100% is white and 0% is black).
527
528 color-downtime:
529   day-min:  3
530   day-max: 50
531   factor:   0.7
532
533With key C<host-mapping>,
534it's good to map C<localhost> to the real name of the computer (hostname).
535
536 host-mapping:
537   localhost:  srv-nagios
538   toto:       titi
539
540The only important key is C<remote-action>.
541You can affiliate as many subkeys as you want.
542Let's take an example:
543
544 remote-action:
545   oom-killer:
546     regex: ^OOM Killer
547     title:  OOM Killer
548     command:     tssh -c 'sudo rm /var/lib/nagios3/nagios_oom_killer.log' %m
549     command-one: ssh %m 'sudo rm /var/lib/nagios3/nagios_oom_killer.log'
550     depend: ^SSH
551     status: ALL
552     style: bold
553
554C<oom-killer> is just a key for your remote action.
555The regex is used to find which service has a problem...
556The title is use in the result web page (not mandatory - otherwise, it will be C<Action: oom-killer>).
557The C<command> is just written on this web page.
558You have the responsibility to copy / cut it on a terminal.
559For security reasons, the nagios server does not have the right to launch the command on the remote host.
560The wildcard C<%m> is replaced by the list of the host (separated by the space).
561Sometime, the command could be different if there is only one computer (just SSH and no parallel SSH).
562If your command is based on SSH,
563you can have an SSH action only if the remote SSH is running.
564So you can make the remote action depend on the SSH service through a regular expression of your choice.
565
566The last two keys.
567The C<status> key is for CRITICAL or WARNING (or ALL).
568The key C<style> is there to mark in bold the service in error on the web page.
569
570The web page will be partially updated every 15 minutes by default (if Javascript is enabled in your browser).
571It is possible to have a finer setting depending on the time of day and the day of the week
572by using Perl objects C<DateTime::Event::Recurrence> via some YAML parameters in the configuration file.
573See the sample configuration file
574L<velvice.sample.yml|http://servforge.legi.grenoble-inp.fr/pub/soft-trokata/nagios-velvice/velvice.sample.yml>
575for a very detailed case.
576With the following configuration,
577the refresh of the web page will take place every 5 min (300 s) from 9 am to noon and from 1 pm to 6 pm from Monday to Friday.
578From noon to 1 pm and from 6 pm to 8 pm on weekdays, this will take place every 10 minutes.
579
580 refreshments:
581   -
582     refresh: 300
583     days:  [ 1 .. 5 ]
584     start: [  9, 13 ]
585     end:   [ 12, 18 ]
586   -
587     refresh: 600
588     days:  [ 1 .. 5 ]
589     start: [ 12, 18 ]
590     end:   [ 13, 20 ]
591
592
593=head1 SEE ALSO
594
595yamllint(1), ysh(1), YAML, Nagios::StatusLog, Color::Calc, DateTime::Event::Recurrence
596
597In Debian GNU/Linux distribution, packages for C<yamllint> and C<ysh> are:
598
599=over
600
601=item * C<yamllint> - Linter for YAML files (Python)
602
603=item * C<libyaml-shell-perl> - YAML test shell (Perl)
604
605=back
606
607
608Own project ressources:
609
610=over
611
612=item * L<Web Site|http://servforge.legi.grenoble-inp.fr/projects/soft-trokata/wiki/SoftWare/NagiosVelvice>
613
614=item * L<Online Manual|http://servforge.legi.grenoble-inp.fr/pub/soft-trokata/nagios-velvice/velvice.html>
615
616=item * L<SVN Repository|http://servforge.legi.grenoble-inp.fr/svn/soft-trokata/trunk/nagios-velvice> -
617        L<Forge Browser|http://servforge.legi.grenoble-inp.fr/projects/soft-trokata/browser/trunk/nagios-velvice>
618
619=item * L<Debian Package|http://servforge.legi.grenoble-inp.fr/pub/soft-trokata/nagios-velvice/download/>
620
621=back
622
623
624=head1 VERSION
625
626$Id: velvice.cgi 433 2020-07-27 10:10:33Z g7moreau $
627
628
629=head1 AUTHOR
630
631Written by Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>, LEGI UMR 5519, CNRS, Grenoble - France
632
633
634=head1 LICENSE AND COPYRIGHT
635
636Licence GNU GPL version 2 or later and Perl equivalent
637
638Copyright (C) 2014-2019, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France
Note: See TracBrowser for help on using the repository browser.