|
@@ -1,18 +1,17 @@
|
|
#!/usr/bin/perl
|
|
#!/usr/bin/perl
|
|
|
|
|
|
-#https://github.com/zorkian/nagios-irc-bot/blob/master/nagiosirc.pl
|
|
|
|
-#http://www.update.uu.se/~zrajm/programs/irssi-scripts/fifo_remote.pl-0.5
|
|
|
|
-#https://github.com/mikegrb/irssi-scripts/blob/master/nagios-ack.pl
|
|
|
|
-
|
|
|
|
-# DONE
|
|
|
|
|
|
+# What this script does :
|
|
|
|
+# -----------------------
|
|
# 1/ check nagios.log
|
|
# 1/ check nagios.log
|
|
# 2/ setup an array of alerts
|
|
# 2/ setup an array of alerts
|
|
# 3/ ability to remove-change alerts on new notification for same host/[service]
|
|
# 3/ ability to remove-change alerts on new notification for same host/[service]
|
|
# 4/ dialog with livestatus to replay full alerts on load/setup : irssi command /nagrefresh
|
|
# 4/ dialog with livestatus to replay full alerts on load/setup : irssi command /nagrefresh
|
|
# 5/ define !recheck to nagios
|
|
# 5/ define !recheck to nagios
|
|
# 6/ ability to define chan/server on irssi configuration instead of bot config.
|
|
# 6/ ability to define chan/server on irssi configuration instead of bot config.
|
|
|
|
+#
|
|
|
|
+# What it should do :
|
|
|
|
+# -------------------
|
|
# TODO
|
|
# TODO
|
|
-# 3/ define an ACK command
|
|
|
|
# define !ack irc command
|
|
# define !ack irc command
|
|
# use %ACK_INDEX by alert type HOST / SERVICE
|
|
# use %ACK_INDEX by alert type HOST / SERVICE
|
|
# use %ACK_INDEX_LEVEL by alert type CRIT/UP/DOWN/WARN/UNK…
|
|
# use %ACK_INDEX_LEVEL by alert type CRIT/UP/DOWN/WARN/UNK…
|
|
@@ -28,14 +27,15 @@ use Term::ANSIColor qw/ :constants /;
|
|
|
|
|
|
use Fcntl; # provides `O_NONBLOCK' and `O_RDONLY' constants
|
|
use Fcntl; # provides `O_NONBLOCK' and `O_RDONLY' constants
|
|
|
|
|
|
|
|
+##########################################################################
|
|
|
|
+# Part A : script configuration / Prototypes
|
|
|
|
+# Put signals to irssi ###################################################
|
|
|
|
+
|
|
our ( $FIFO, # fifo absolute filename (expanded from Irssi config)
|
|
our ( $FIFO, # fifo absolute filename (expanded from Irssi config)
|
|
$FIFO_HANDLE, # fifo filehandle for `open' et al.
|
|
$FIFO_HANDLE, # fifo filehandle for `open' et al.
|
|
$FIFO_TAG ); # fifo signal tag for `input_add'
|
|
$FIFO_TAG ); # fifo signal tag for `input_add'
|
|
|
|
|
|
-
|
|
|
|
-# probably not very useful for other people but who knows?
|
|
|
|
-
|
|
|
|
-$VERSION = "0.2.2";
|
|
|
|
|
|
+$VERSION = "0.3.0";
|
|
%IRSSI = (
|
|
%IRSSI = (
|
|
authors => 'asr',
|
|
authors => 'asr',
|
|
contact => 'root@lautre.net',
|
|
contact => 'root@lautre.net',
|
|
@@ -51,19 +51,20 @@ $VERSION = "0.2.2";
|
|
Irssi::settings_add_str($IRSSI{name}, # default fifo_remote_file
|
|
Irssi::settings_add_str($IRSSI{name}, # default fifo_remote_file
|
|
'fifo_remote_file', '/home/tc-14/var/nagios-fifo'); #
|
|
'fifo_remote_file', '/home/tc-14/var/nagios-fifo'); #
|
|
|
|
|
|
-Irssi::settings_add_str("nagios_ack", "nagios_ack_channel", "#naglautre");
|
|
|
|
-#Irssi::settings_add_str("nagios_ack", "nagios_ack_channel", "#root");
|
|
|
|
-Irssi::settings_add_str("nagios_ack", "nagios_ack_nick", "");
|
|
|
|
|
|
+Irssi::settings_add_str("nagios_ack", "nagios_ack_channel", "#main_channel"); # see also etc/config.template
|
|
|
|
+Irssi::settings_add_str("nagios_ack", "nagios_ack_nick", ""); # any user (none by default)
|
|
Irssi::settings_add_str("nagios_ack", "nagios_command", "/var/lib/nagios3/rw/live");
|
|
Irssi::settings_add_str("nagios_ack", "nagios_command", "/var/lib/nagios3/rw/live");
|
|
#Irssi::command_bind( 'ack', \&nagios_ack );
|
|
#Irssi::command_bind( 'ack', \&nagios_ack );
|
|
#Irssi::command_bind( 'nagstat', \&nagios_status );
|
|
#Irssi::command_bind( 'nagstat', \&nagios_status );
|
|
-Irssi::command_bind( 'nagrefresh', \&query_nagios_status );
|
|
|
|
|
|
+Irssi::command_bind( 'nagrefresh', \&nagios_query_status );
|
|
|
|
|
|
# CONFIG: point this where your Nagios configuration files live
|
|
# CONFIG: point this where your Nagios configuration files live
|
|
#my $nagioslog = "/var/log/nagios3/nagios.log";
|
|
#my $nagioslog = "/var/log/nagios3/nagios.log";
|
|
|
|
|
|
# To be used to check immediately / hosts-stats
|
|
# To be used to check immediately / hosts-stats
|
|
-my $nagioscmd = "/var/lib/nagios3/rw/live";
|
|
|
|
|
|
+my $nagioscmd = Irssi::settings_get_str("nagios_command");
|
|
|
|
+my $nagios_ack_channel= Irssi::settings_get_str("nagios_ack_channel");
|
|
|
|
+my $nagios_ack_nick= Irssi::settings_get_str("nagios_ack_nick");
|
|
|
|
|
|
my %renot; # { "host" or "host:service" => time_last_notification }
|
|
my %renot; # { "host" or "host:service" => time_last_notification }
|
|
|
|
|
|
@@ -92,6 +93,9 @@ my %C = (
|
|
Z => "\x03",
|
|
Z => "\x03",
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+# Numeric to string conversion of nagios status
|
|
|
|
+# 0..4 : hosts
|
|
|
|
+# 10..14 : services
|
|
my @NagStates = qw/UP DOWN WARNING UNKNOWN .. .. .. .. .. ..
|
|
my @NagStates = qw/UP DOWN WARNING UNKNOWN .. .. .. .. .. ..
|
|
OK WARNING CRITICAL UNKNOWN/;
|
|
OK WARNING CRITICAL UNKNOWN/;
|
|
|
|
|
|
@@ -109,6 +113,8 @@ my $state_to_color = {
|
|
UNKNOWN => $C{Gr},
|
|
UNKNOWN => $C{Gr},
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+# Global use to limit memory use. Probably a bad idea : better to check
|
|
|
|
+# where is the memory leak.
|
|
my ($status_line);
|
|
my ($status_line);
|
|
my @match;
|
|
my @match;
|
|
my ($msg,$num);
|
|
my ($msg,$num);
|
|
@@ -117,30 +123,121 @@ my ($type,$data);
|
|
my ($d,$type,$host,$service,$state,$output);
|
|
my ($d,$type,$host,$service,$state,$output);
|
|
my ( $host, $svc, $state, $msg, $id );
|
|
my ( $host, $svc, $state, $msg, $id );
|
|
|
|
|
|
|
|
+my ($server, $msg, $nick, $addr, $target);
|
|
|
|
+my ( $param, $server, $window );
|
|
|
|
+my (@issue, $issue);
|
|
|
|
+
|
|
#my $state_to_color = { OK => '', UP => '', WARNING => '', CRITICAL => '', DOWN => '', UNKNOWN => '' };
|
|
#my $state_to_color = { OK => '', UP => '', WARNING => '', CRITICAL => '', DOWN => '', UNKNOWN => '' };
|
|
|
|
|
|
-# simple subs
|
|
|
|
|
|
+# Alert Acknowledment ####################################################
|
|
|
|
+
|
|
|
|
+my $last_alert;
|
|
|
|
+
|
|
|
|
+my $DEBUG=Irssi::settings_get_str("nagios_ack_channel");
|
|
|
|
+
|
|
|
|
+# Simple subs ############################################################
|
|
sub TRUE() { 1 } # some constants [perlsyn(1)
|
|
sub TRUE() { 1 } # some constants [perlsyn(1)
|
|
sub FALSE() { "" } # "Constant Functions"]
|
|
sub FALSE() { "" } # "Constant Functions"]
|
|
sub DEBUG(@) { print "%B", join(":", @_),"%n" }# DEBUG thingy
|
|
sub DEBUG(@) { print "%B", join(":", @_),"%n" }# DEBUG thingy
|
|
|
|
+
|
|
|
|
+sub time2date($) {
|
|
|
|
+ my ($d)=@_;
|
|
|
|
+ return strftime("%d/%m/%y %H:%M", localtime($d));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# Part B : user Actions ##################################################
|
|
# Acknowledge alerts #####################################################
|
|
# Acknowledge alerts #####################################################
|
|
|
|
|
|
-my $last_alert;
|
|
|
|
|
|
+# Global use to limit memory use. Probably a bad idea : better to check
|
|
|
|
+# where is the memory leak.
|
|
|
|
|
|
-my ($server, $msg, $nick, $addr, $target);
|
|
|
|
-my ( $param, $server, $window );
|
|
|
|
-my (@issue, $issue);
|
|
|
|
|
|
+# Four unused subs. Still there to be implemented later
|
|
|
|
+sub parse_status();
|
|
|
|
+sub nagios_ack($$$);
|
|
|
|
+sub nagios_check($$$);
|
|
|
|
+sub nagios_inject;
|
|
|
|
+#sub nagios_status();
|
|
|
|
|
|
-#sub on_public {
|
|
|
|
-# ($server, $msg, $nick, $addr, $target) = @_;
|
|
|
|
-# # return unless $target eq Irssi::setting_get_str("nagios_ack_channel") && $nick eq Irssi::setting_get_str("nagios_ack_nick");
|
|
|
|
-# $last_alert = $msg if $msg =~ m/^PROBLEM/;
|
|
|
|
-# return;
|
|
|
|
-#}
|
|
|
|
|
|
+# Return alert ID "[FF01]"
|
|
|
|
+# F : caracter to display (! : ; C : change ; + : new alert ; - : green flag ; ? : green but not found)
|
|
|
|
+# I : numeric ID
|
|
|
|
+# state : state string, from @NagStates or %state_to_color
|
|
|
|
+sub format_alert_id($$$); # ($Flag,$I,$state)
|
|
|
|
|
|
-my $DEBUG=Irssi::settings_get_str("nagios_ack_channel");
|
|
|
|
|
|
+# Add alert to array / index
|
|
|
|
+sub insert_alert($$$$$); #( $host, $svc, $state, $msg, $d )
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# Part C : Logfile management ############################################
|
|
|
|
+
|
|
|
|
+# disable fifo and erase fifo file
|
|
|
|
+sub destroy_fifo($); # [2004-08-14]
|
|
|
|
+
|
|
|
|
+# Open logfile/fifo
|
|
|
|
+sub open_fifo($); # [2004-08-14]
|
|
|
|
+
|
|
|
|
+# read from fifo
|
|
|
|
+# (called by fifo input signal)
|
|
|
|
+sub read_fifo(); # [2004-08-14]
|
|
|
|
+
|
|
|
|
+# Read logfile ###########################################################
|
|
|
|
+# create named fifo and open it for input
|
|
|
|
+# (called on script load and fifo name changes)
|
|
|
|
+sub create_fifo($); # [2004-08-14]
|
|
|
|
+
|
|
|
|
+# Query nagios ###########################################################
|
|
|
|
+sub nagios_query_status($);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# Part D : Alert processing ##############################################
|
|
|
|
+
|
|
|
|
+# Search for services/host informations, and post them to IRC ############
|
|
|
|
+# Delimiter : ; for logs; @ for direct nagios custom notification command
|
|
|
|
+# one parameter : the logline to parse.
|
|
|
|
+sub parse_nagios_log($);
|
|
|
|
+
|
|
|
|
+# Use alert fields to print and insert it
|
|
|
|
+# timestamp, alert-type, hostname, state, plugin output, service_name
|
|
|
|
+sub handle_alert($$$$$$$); # $d,$type,$host,$state,$output,$service
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# IRSSI Events ###########################################################
|
|
|
|
+
|
|
|
|
+# create new fifo (erase any old) and get command prefix
|
|
|
|
+# (called on script loading and on user /set)
|
|
|
|
+sub setup(); # [2004-08-13]
|
|
|
|
+
|
|
|
|
+# Interact with IRC chan users
|
|
|
|
+sub event_privmsg ($$$$);
|
|
|
|
+
|
|
|
|
+# REFERENCES
|
|
|
|
+# ----------
|
|
|
|
+#
|
|
|
|
+# This script is mainly adapted from 3 other scripts related to nagios :
|
|
|
|
+#
|
|
|
|
+# https://github.com/zorkian/nagios-irc-bot/blob/master/nagiosirc.pl
|
|
|
|
+# http://www.update.uu.se/~zrajm/programs/irssi-scripts/fifo_remote.pl-0.5
|
|
|
|
+# https://github.com/mikegrb/irssi-scripts/blob/master/nagios-ack.pl
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# CODE ###################################################################
|
|
|
|
+##########################################################################
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# Part B : user Actions ##################################################
|
|
|
|
|
|
-sub nagios_ack {
|
|
|
|
|
|
+
|
|
|
|
+sub parse_status() {
|
|
|
|
+ return $1 if $last_alert =~ /^PROBLEM - (\S+) is DOWN/;
|
|
|
|
+ return ($1, $2) if $last_alert =~ /^PROBLEM - (\S+) on (\S+) is/;
|
|
|
|
+ return;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sub nagios_ack($$$) {
|
|
( $param, $server, $window ) = @_;
|
|
( $param, $server, $window ) = @_;
|
|
@issue = parse_status();
|
|
@issue = parse_status();
|
|
if (!@issue) {
|
|
if (!@issue) {
|
|
@@ -150,7 +247,7 @@ sub nagios_ack {
|
|
Irssi::active_server->command('MSG ' . $DEBUG . $message);
|
|
Irssi::active_server->command('MSG ' . $DEBUG . $message);
|
|
}
|
|
}
|
|
|
|
|
|
-sub nagios_check {
|
|
|
|
|
|
+sub nagios_check($$$) {
|
|
#1412375470;filer2;DISK_all;2;W=10% C=5%
|
|
#1412375470;filer2;DISK_all;2;W=10% C=5%
|
|
( $param, $server, $window ) = @_;
|
|
( $param, $server, $window ) = @_;
|
|
@issue = parse_status();
|
|
@issue = parse_status();
|
|
@@ -159,34 +256,22 @@ sub nagios_check {
|
|
}
|
|
}
|
|
my $message = " CHECK ".$param . join ' ', reverse @issue;
|
|
my $message = " CHECK ".$param . join ' ', reverse @issue;
|
|
Irssi::active_server->command('MSG ' . $DEBUG . $message);
|
|
Irssi::active_server->command('MSG ' . $DEBUG . $message);
|
|
- # validate_alert($$$$$$) { # $d,$type,$host,$state,$output,$service
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-sub nagios_status {
|
|
|
|
- (undef, undef, $window) = @_;
|
|
|
|
- $issue = join ',', map { "'" . $_ . "'" } reverse parse_status();
|
|
|
|
- $window->print("Last issue: '$last_alert' ($issue)");
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-sub parse_status {
|
|
|
|
- return $1 if $last_alert =~ /^PROBLEM - (\S+) is DOWN/;
|
|
|
|
- return ($1, $2) if $last_alert =~ /^PROBLEM - (\S+) on (\S+) is/;
|
|
|
|
- return;
|
|
|
|
|
|
+ # handle_alert($$$$$$) { # $d,$type,$host,$state,$output,$service }
|
|
}
|
|
}
|
|
|
|
|
|
sub nagios_inject {
|
|
sub nagios_inject {
|
|
$last_alert = shift;
|
|
$last_alert = shift;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#sub nagios_status {
|
|
|
|
+# (undef, undef, $window) = @_;
|
|
|
|
+# $issue = join ',', map { "'" . $_ . "'" } reverse parse_status();
|
|
|
|
+# $window->print("Last issue: '$last_alert' ($issue)");
|
|
|
|
+#
|
|
|
|
+#}
|
|
|
|
|
|
-
|
|
|
|
-sub time2date($) {
|
|
|
|
- my ($d)=@_;
|
|
|
|
- return strftime("%d/%m/%y %H:%M", localtime($d));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-sub mark($$$) {
|
|
|
|
|
|
+# Return alert ID
|
|
|
|
+sub format_alert_id($$$) {
|
|
my ($Flag,$I,$state)=@_;
|
|
my ($Flag,$I,$state)=@_;
|
|
my $M=sprintf('%02d', scalar @ACKS % 100);
|
|
my $M=sprintf('%02d', scalar @ACKS % 100);
|
|
my $N=sprintf('%02d', $I % 100);
|
|
my $N=sprintf('%02d', $I % 100);
|
|
@@ -198,7 +283,7 @@ sub mark($$$) {
|
|
}
|
|
}
|
|
|
|
|
|
# Add alert to array / index
|
|
# Add alert to array / index
|
|
-sub ackable {
|
|
|
|
|
|
+sub insert_alert($$$$$) {
|
|
#Irssi::print(">> On vire $host/$svc");
|
|
#Irssi::print(">> On vire $host/$svc");
|
|
my $i;
|
|
my $i;
|
|
( $host, $svc, $state, $msg, $d ) = @_;
|
|
( $host, $svc, $state, $msg, $d ) = @_;
|
|
@@ -223,7 +308,7 @@ sub ackable {
|
|
}
|
|
}
|
|
# New alert, insert.
|
|
# New alert, insert.
|
|
push (@ACKS, [ $host, $svc, $state, $msg, $d ] );
|
|
push (@ACKS, [ $host, $svc, $state, $msg, $d ] );
|
|
- return mark('+',scalar @ACKS,$state);
|
|
|
|
|
|
+ return format_alert_id('+',scalar @ACKS,$state);
|
|
# Clear alert
|
|
# Clear alert
|
|
} else {
|
|
} else {
|
|
# Irssi::print(">> On vire $host/$svc");
|
|
# Irssi::print(">> On vire $host/$svc");
|
|
@@ -234,17 +319,17 @@ sub ackable {
|
|
$ACKS[$i] = pop @ACKS;
|
|
$ACKS[$i] = pop @ACKS;
|
|
$i=$#ACKS;
|
|
$i=$#ACKS;
|
|
Irssi::print(">> found $i");
|
|
Irssi::print(">> found $i");
|
|
- return mark('-',$i+1,$state);
|
|
|
|
|
|
+ return format_alert_id('-',$i+1,$state);
|
|
}
|
|
}
|
|
$i++;
|
|
$i++;
|
|
}
|
|
}
|
|
- return mark('?',0,$state);
|
|
|
|
|
|
+ return format_alert_id('?',0,$state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
##########################################################################
|
|
-# Logfile management #####################################################
|
|
|
|
|
|
+# Part C : Logfile management ############################################
|
|
|
|
|
|
# disable fifo and erase fifo file
|
|
# disable fifo and erase fifo file
|
|
sub destroy_fifo($) { # [2004-08-14]
|
|
sub destroy_fifo($) { # [2004-08-14]
|
|
@@ -288,7 +373,7 @@ sub read_fifo() { # [2004-08-14]
|
|
# Read logfile ###########################################################
|
|
# Read logfile ###########################################################
|
|
foreach (<$FIFO_HANDLE>) { # for each input line
|
|
foreach (<$FIFO_HANDLE>) { # for each input line
|
|
chomp; # strip trailing newline
|
|
chomp; # strip trailing newline
|
|
- parse_naglog($_); #if (/ALERT/ && /HARD;/);
|
|
|
|
|
|
+ parse_nagios_log($_); #if (/ALERT/ && /HARD;/);
|
|
#Irssi::active_win->print( # show incoming commands (debug)
|
|
#Irssi::active_win->print( # show incoming commands (debug)
|
|
# "\u$IRSSI{name} received command: \"$_\"", #
|
|
# "\u$IRSSI{name} received command: \"$_\"", #
|
|
# MSGLEVEL_CLIENTNOTICE); #
|
|
# MSGLEVEL_CLIENTNOTICE); #
|
|
@@ -300,19 +385,6 @@ sub read_fifo() { # [2004-08-14]
|
|
# is to be found on the fifo. (This seems a waste of resources to me.)
|
|
# is to be found on the fifo. (This seems a waste of resources to me.)
|
|
}
|
|
}
|
|
|
|
|
|
-# create new fifo (erase any old) and get command prefix
|
|
|
|
-# (called on script loading and on user /set)
|
|
|
|
-sub setup() { # [2004-08-13]
|
|
|
|
- my $new_fifo = Irssi::settings_get_str # setting from Irssi
|
|
|
|
- 'fifo_remote_file'; # (and add path to it)
|
|
|
|
- return if $new_fifo eq $FIFO and -p $FIFO; # do nada if already exists
|
|
|
|
- destroy_fifo($FIFO) if -p $FIFO; # destroy old fifo
|
|
|
|
- create_fifo($new_fifo) # create new fifo
|
|
|
|
- and $FIFO = $new_fifo; # and remember that fifo
|
|
|
|
- # To ADD :
|
|
|
|
- # request to livestatus to fetch stored alerts
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
# create named fifo and open it for input
|
|
# create named fifo and open it for input
|
|
# (called on script load and fifo name changes)
|
|
# (called on script load and fifo name changes)
|
|
sub create_fifo($) { # [2004-08-14]
|
|
sub create_fifo($) { # [2004-08-14]
|
|
@@ -330,17 +402,20 @@ sub create_fifo($) { # [2004-08-14]
|
|
open_fifo($new_fifo); # open fifo for reading
|
|
open_fifo($new_fifo); # open fifo for reading
|
|
} #
|
|
} #
|
|
|
|
|
|
|
|
+
|
|
# Query nagios ###########################################################
|
|
# Query nagios ###########################################################
|
|
-sub query_nagios_status($){
|
|
|
|
|
|
+
|
|
|
|
+sub nagios_query_status($){
|
|
# 1412478149;hyppocampe;apt;2;CRITICAL : unknown: qemu-utils, qemu-kvm, qemu-keymaps
|
|
# 1412478149;hyppocampe;apt;2;CRITICAL : unknown: qemu-utils, qemu-kvm, qemu-keymaps
|
|
my ($option)=@_;
|
|
my ($option)=@_;
|
|
my @unixcat;
|
|
my @unixcat;
|
|
my $unixline;
|
|
my $unixline;
|
|
|
|
+ $nagioscmd = Irssi::settings_get_str("nagios_command");
|
|
foreach $unixline ( `echo "GET services
|
|
foreach $unixline ( `echo "GET services
|
|
Columns: last_state_change host_name display_name state plugin_output
|
|
Columns: last_state_change host_name display_name state plugin_output
|
|
Filter: state > 1" | unixcat $nagioscmd` ) {
|
|
Filter: state > 1" | unixcat $nagioscmd` ) {
|
|
($d,$host,$service,$state,$output)=split /;/,$unixline;
|
|
($d,$host,$service,$state,$output)=split /;/,$unixline;
|
|
- validate_alert($option,$d,'SERVICE',$host,$NagStates[$state+10],$output,$service);
|
|
|
|
|
|
+ handle_alert($option,$d,'SERVICE',$host,$NagStates[$state+10],$output,$service);
|
|
Irssi::print("%B>>%n $unixline", MSGLEVEL_CLIENTCRAP);
|
|
Irssi::print("%B>>%n $unixline", MSGLEVEL_CLIENTCRAP);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -349,40 +424,36 @@ Filter: state > 1" | unixcat $nagioscmd` ) {
|
|
Columns: last_state_change host_name state plugin_output
|
|
Columns: last_state_change host_name state plugin_output
|
|
Filter: state > 1" | unixcat $nagioscmd` ) {
|
|
Filter: state > 1" | unixcat $nagioscmd` ) {
|
|
($d,$host,$state,$output)=split /;/,$unixline;
|
|
($d,$host,$state,$output)=split /;/,$unixline;
|
|
- validate_alert($option,$d,'HOST',$host,$NagStates[$state],$output,"");
|
|
|
|
|
|
+ handle_alert($option,$d,'HOST',$host,$NagStates[$state],$output,"");
|
|
Irssi::print("%B>>%n $unixline", MSGLEVEL_CLIENTCRAP);
|
|
Irssi::print("%B>>%n $unixline", MSGLEVEL_CLIENTCRAP);
|
|
}
|
|
}
|
|
-
|
|
|
|
-# cat << EOF | unixcat /var/lib/nagios3/rw/live
|
|
|
|
-# GET services
|
|
|
|
-# Columns: last_state_change host_name display_name state plugin_output
|
|
|
|
-# Filter: state > 1
|
|
|
|
-# EOF
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-# Parse alert to find vars ###############################################
|
|
|
|
-sub parse_naglog(){
|
|
|
|
- my $option="";
|
|
|
|
- $d=0; $status_line=""; $host="";$output="";$service="";
|
|
|
|
|
|
+##########################################################################
|
|
|
|
+# Part D : Alert processing ##############################################
|
|
|
|
+
|
|
# Search for services/host informations, and post them to IRC ############
|
|
# Search for services/host informations, and post them to IRC ############
|
|
-#
|
|
|
|
# Delimiter : ; for logs; @ for direct nagios custom notification command
|
|
# Delimiter : ; for logs; @ for direct nagios custom notification command
|
|
-#
|
|
|
|
-# [1412330770] SERVICE ALERT: ella;IMAPs_LOGIN;OK;SOFT;2;OK - CO1N OK LOGIN Ok.
|
|
|
|
-# /\[\d+\] (\w+) ALERT: (\w+);(\w+);(\w+);HARD;(\d+);(.+)/
|
|
|
|
-# [1410969598] HOST ALERT: filou;DOWN;SOFT;1;PING CRITICAL - Paquets perdus = 100%
|
|
|
|
-# PROCESS type ALERT: host;service;STATE1;HARD;num;commentaire
|
|
|
|
|
|
+sub parse_nagios_log($){
|
|
|
|
+ my $option="";
|
|
|
|
+ $d=0; $status_line=""; $host="";$output="";$service="";
|
|
|
|
+
|
|
|
|
+ ### log :
|
|
|
|
+ # [1412330770] SERVICE ALERT: ella;IMAPs_LOGIN;OK;SOFT;2;OK - CO1N OK LOGIN Ok.
|
|
|
|
+ # /\[\d+\] (\w+) ALERT: (\w+);(\w+);(\w+);HARD;(\d+);(.+)/
|
|
|
|
+ # [1410969598] HOST ALERT: filou;DOWN;SOFT;1;PING CRITICAL - Paquets perdus = 100%
|
|
|
|
+ # [TIMESTAMP] PROCESS type ALERT: host;service;STATE1;HARD;num;commentaire
|
|
if (@match=$status_line =~ /\[?(\d+)\]? HOST ALERT: ([^@;]+)[@;](\w+)[@;]HARD[@;].*[@;](.+)/) {
|
|
if (@match=$status_line =~ /\[?(\d+)\]? HOST ALERT: ([^@;]+)[@;](\w+)[@;]HARD[@;].*[@;](.+)/) {
|
|
# HOST ########################
|
|
# HOST ########################
|
|
($d,$host,$state,$output)=@match;
|
|
($d,$host,$state,$output)=@match;
|
|
- validate_alert($option,$d,"HOST",$host,$state,$output,$service);
|
|
|
|
|
|
+ handle_alert($option,$d,"HOST",$host,$state,$output,$service);
|
|
|
|
|
|
# SERVICE #####################
|
|
# SERVICE #####################
|
|
} elsif (@match=$status_line =~ /\[?(\d+)\]? (\w+) ALERT: ([^;@]+)[@;]([^;@]+)[@;](\w+)[@;]HARD[@;].*[@;](.+)/) {
|
|
} elsif (@match=$status_line =~ /\[?(\d+)\]? (\w+) ALERT: ([^;@]+)[@;]([^;@]+)[@;](\w+)[@;]HARD[@;].*[@;](.+)/) {
|
|
($d,$type,$host,$service,$state,$output)=@match;
|
|
($d,$type,$host,$service,$state,$output)=@match;
|
|
|
|
|
|
$service=~s/[^\w\d_-]/_/g;
|
|
$service=~s/[^\w\d_-]/_/g;
|
|
- validate_alert($option,$d,$type,$host,$state,$output,$service);
|
|
|
|
|
|
+ handle_alert($option,$d,$type,$host,$state,$output,$service);
|
|
|
|
|
|
# OTHER #######################
|
|
# OTHER #######################
|
|
} elsif (@match=$status_line =~ /\[\d+\] (\w+) ALERT: (.*)/) {
|
|
} elsif (@match=$status_line =~ /\[\d+\] (\w+) ALERT: (.*)/) {
|
|
@@ -397,15 +468,17 @@ sub parse_naglog(){
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-sub validate_alert($$$$$$$) { # $d,$type,$host,$state,$output,$service
|
|
|
|
|
|
+# Use alert fields to print and insert it
|
|
|
|
+sub handle_alert($$$$$$$) { # $d,$type,$host,$state,$output,$service
|
|
my $option;
|
|
my $option;
|
|
|
|
+
|
|
|
|
+ # Temporisation
|
|
($option,$d,$type,$host,$state,$output,$service)=@_;
|
|
($option,$d,$type,$host,$state,$output,$service)=@_;
|
|
next if exists $renot{"$host:$service"} && $renot{"$host:$service"} >= time() - 5;
|
|
next if exists $renot{"$host:$service"} && $renot{"$host:$service"} >= time() - 5;
|
|
$renot{"$host:$service"} = time();
|
|
$renot{"$host:$service"} = time();
|
|
|
|
|
|
- #################
|
|
|
|
- # HOST
|
|
|
|
- $id = ackable($host,$service,$state,$output,$d);
|
|
|
|
|
|
+ # HOST or SERVICE ?
|
|
|
|
+ $id = insert_alert($host,$service,$state,$output,$d);
|
|
$msg = "$id".$state_to_color->{$state} . "$host:$service".$C{Z}." is $state : $output";
|
|
$msg = "$id".$state_to_color->{$state} . "$host:$service".$C{Z}." is $state : $output";
|
|
#Irssi::print( "%B>>%n $IRSSI{name} $msg", MSGLEVEL_CLIENTCRAP);
|
|
#Irssi::print( "%B>>%n $IRSSI{name} $msg", MSGLEVEL_CLIENTCRAP);
|
|
|
|
|
|
@@ -414,12 +487,29 @@ sub validate_alert($$$$$$$) { # $d,$type,$host,$state,$output,$service
|
|
$message = " $d - $last_alert - $msg";
|
|
$message = " $d - $last_alert - $msg";
|
|
# Silently ignore previously sent alerts
|
|
# Silently ignore previously sent alerts
|
|
return if $id =~ '\[!' ;
|
|
return if $id =~ '\[!' ;
|
|
- Irssi::active_server->command('MSG ' . Irssi::settings_get_str("nagios_ack_channel") .
|
|
|
|
|
|
+ $nagios_ack_channel= Irssi::settings_get_str("nagios_ack_channel");
|
|
|
|
+ Irssi::active_server->command('MSG ' . $nagios_ack_channel .
|
|
" ".$message) unless ($option eq "silent");
|
|
" ".$message) unless ($option eq "silent");
|
|
# Irssi::print( "%B>>%n $IRSSI{name} $msg", MSGLEVEL_CLIENTCRAP);
|
|
# Irssi::print( "%B>>%n $IRSSI{name} $msg", MSGLEVEL_CLIENTCRAP);
|
|
}
|
|
}
|
|
|
|
|
|
-sub event_privmsg {
|
|
|
|
|
|
+##########################################################################
|
|
|
|
+# IRSSI Events ###########################################################
|
|
|
|
+# create new fifo (erase any old) and get command prefix
|
|
|
|
+# (called on script loading and on user /set)
|
|
|
|
+sub setup() { # [2004-08-13]
|
|
|
|
+ my $new_fifo = Irssi::settings_get_str # setting from Irssi
|
|
|
|
+ 'fifo_remote_file'; # (and add path to it)
|
|
|
|
+ return if $new_fifo eq $FIFO and -p $FIFO; # do nada if already exists
|
|
|
|
+ destroy_fifo($FIFO) if -p $FIFO; # destroy old fifo
|
|
|
|
+ create_fifo($new_fifo) # create new fifo
|
|
|
|
+ and $FIFO = $new_fifo; # and remember that fifo
|
|
|
|
+ # To ADD :
|
|
|
|
+ # request to livestatus to fetch stored alerts
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# Interact with IRC chan users
|
|
|
|
+sub event_privmsg($$$$) {
|
|
# Commamd channel
|
|
# Commamd channel
|
|
my $K;
|
|
my $K;
|
|
my ($server, $data, $nick, $mask) =@_;
|
|
my ($server, $data, $nick, $mask) =@_;
|
|
@@ -428,49 +518,54 @@ sub event_privmsg {
|
|
#print ( "C:$target X:$text A:$admin D:$warndate L:$last W:$warn N:$nick D:$data" );
|
|
#print ( "C:$target X:$text A:$admin D:$warndate L:$last W:$warn N:$nick D:$data" );
|
|
if ( $text =~ /^!nagios ?(.*)/i ) {
|
|
if ( $text =~ /^!nagios ?(.*)/i ) {
|
|
$arg=$1;
|
|
$arg=$1;
|
|
|
|
+ # If we are not in command channel : NoOP
|
|
|
|
+ $nagios_ack_channel=Irssi::settings_get_str("nagios_ack_channel");
|
|
|
|
+ Irssi::print(">> $arg - $nagios_ack_channel - $target");
|
|
|
|
+ return if $target ne $nagios_ack_channel ;
|
|
|
|
+
|
|
# !nagios [*] :
|
|
# !nagios [*] :
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
- " ".scalar @ACKS." alertes");
|
|
|
|
|
|
|
|
# !nagios list [*] :
|
|
# !nagios list [*] :
|
|
if ($arg =~ /^refresh ?(.*)/i) {
|
|
if ($arg =~ /^refresh ?(.*)/i) {
|
|
$arg=$1;
|
|
$arg=$1;
|
|
Irssi::print(">> $arg");
|
|
Irssi::print(">> $arg");
|
|
if ($arg =~ /^silent/) {
|
|
if ($arg =~ /^silent/) {
|
|
- query_nagios_status("silent");
|
|
|
|
|
|
+ nagios_query_status("silent");
|
|
} else {
|
|
} else {
|
|
- query_nagios_status("");
|
|
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
|
|
+ nagios_query_status("");
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
'Refresh nagios. Use "silent" keyword to disable display.');
|
|
'Refresh nagios. Use "silent" keyword to disable display.');
|
|
}
|
|
}
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
|
|
+ " ".scalar @ACKS." alertes");
|
|
}
|
|
}
|
|
elsif ($arg =~ /^list/i) {
|
|
elsif ($arg =~ /^list/i) {
|
|
- Irssi::print(">> $arg");
|
|
|
|
- return unless $#ACKS > 0;
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
|
|
+ " ".scalar @ACKS." alertes");
|
|
my $i=0;
|
|
my $i=0;
|
|
foreach $K (@ACKS) {
|
|
foreach $K (@ACKS) {
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
- " ". mark(' ',$i++,$K->[2]) ." ".$K->[0]." / $K->[1] / $K->[2] / $K->[3] / ".time2date $K->[4]);
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
|
|
+ " ". format_alert_id(' ',$i++,$K->[2]) ." ".$K->[0]." / $K->[1] / $K->[2] / $K->[3] / ".time2date $K->[4]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
elsif ($arg =~ /^help/i) {
|
|
elsif ($arg =~ /^help/i) {
|
|
- Irssi::print(">> $arg");
|
|
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
" !nagios list : liste des alertes nagios reçues ici");
|
|
" !nagios list : liste des alertes nagios reçues ici");
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
" !nagios help : l'aide");
|
|
" !nagios help : l'aide");
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
" !nagios ack <#ALERTE> <message> : aquitte l'alerte");
|
|
" !nagios ack <#ALERTE> <message> : aquitte l'alerte");
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
" !nagios check <#ALERTE> : recheck une alerte donnée (service/host)");
|
|
" !nagios check <#ALERTE> : recheck une alerte donnée (service/host)");
|
|
- $server->command ( "msg ".Irssi::settings_get_str("nagios_ack_channel").
|
|
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
" !nagios refresh [silent] : interroge le nagios pour avoir la liste de toutes les alertes");
|
|
" !nagios refresh [silent] : interroge le nagios pour avoir la liste de toutes les alertes");
|
|
} elsif ( $arg =~ /^check ?(.*)/i ){
|
|
} elsif ( $arg =~ /^check ?(.*)/i ){
|
|
- Irssi::print(">> $arg");
|
|
|
|
nagios_check($1,$server,undef);
|
|
nagios_check($1,$server,undef);
|
|
} elsif ( $arg =~ /^ack ?(.*)/i ){
|
|
} elsif ( $arg =~ /^ack ?(.*)/i ){
|
|
- Irssi::print(">> $arg");
|
|
|
|
nagios_ack($1,$server,undef);
|
|
nagios_ack($1,$server,undef);
|
|
|
|
+ } else {
|
|
|
|
+ $server->command ( "msg ".$nagios_ack_channel.
|
|
|
|
+ " ".scalar @ACKS." alertes");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
return 1;
|
|
@@ -498,9 +593,20 @@ setup(); # initialize setup values
|
|
|
|
|
|
Irssi::signal_add('event privmsg', 'event_privmsg');
|
|
Irssi::signal_add('event privmsg', 'event_privmsg');
|
|
Irssi::signal_add("message public", "event_privmsg");
|
|
Irssi::signal_add("message public", "event_privmsg");
|
|
-#Irssi::signal_add_first("message public", "on_public");
|
|
|
|
Irssi::signal_add('setup changed', \&setup); # re-read setup when it changes
|
|
Irssi::signal_add('setup changed', \&setup); # re-read setup when it changes
|
|
print CLIENTCRAP "%B>>%n $IRSSI{name} $VERSION (by $IRSSI{authors}) loaded";
|
|
print CLIENTCRAP "%B>>%n $IRSSI{name} $VERSION (by $IRSSI{authors}) loaded";
|
|
|
|
|
|
|
|
|
|
1;
|
|
1;
|
|
|
|
+
|
|
|
|
+##########################################################################
|
|
|
|
+# References #############################################################
|
|
|
|
+##########################################################################
|
|
|
|
+# REFERENCES
|
|
|
|
+# ----------
|
|
|
|
+#
|
|
|
|
+# This script is mainly adapted from 3 other scripts related to nagios :
|
|
|
|
+#
|
|
|
|
+# https://github.com/zorkian/nagios-irc-bot/blob/master/nagiosirc.pl
|
|
|
|
+# http://www.update.uu.se/~zrajm/programs/irssi-scripts/fifo_remote.pl-0.5
|
|
|
|
+# https://github.com/mikegrb/irssi-scripts/blob/master/nagios-ack.pl
|