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

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