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

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