|
@@ -72,7 +72,7 @@ my %renot; # { "host" or "host:service" => time_last_notification }
|
|
|
|
|
|
my @cmdqueue = ();
|
|
|
my %ignore = ();
|
|
|
-my @ACKS;
|
|
|
+my @ACKS; # [ hostname, service, state, plugin_output, last_state_change, ACKnowledged ] );
|
|
|
my %ACK_Ind;
|
|
|
|
|
|
my %C = (
|
|
@@ -165,10 +165,10 @@ sub nagios_inject;
|
|
|
# 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)
|
|
|
+sub format_alert_id($$$$); # ($Flag,$I,$state,$acked)
|
|
|
|
|
|
# Add alert to array / index
|
|
|
-sub insert_alert($$$$$); #( $host, $svc, $state, $msg, $d )
|
|
|
+sub insert_alert($$$$$$); #( $host, $svc, $state, $msg, $d )
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
@@ -203,7 +203,7 @@ 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
|
|
|
+sub handle_alert($$$$$$$$); # $d,$type,$host,$state,$output,$service,$acked
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
@@ -258,7 +258,7 @@ sub nagios_check($$$) {
|
|
|
}
|
|
|
my $message = " CHECK ".$param . join ' ', reverse @issue;
|
|
|
Irssi::active_server->command('MSG ' . $DEBUG . $message);
|
|
|
- # handle_alert($$$$$$) { # $d,$type,$host,$state,$output,$service }
|
|
|
+ # handle_alert($$$$$$$) { # $d,$type,$host,$state,$output,$service }
|
|
|
}
|
|
|
|
|
|
sub nagios_inject {
|
|
@@ -273,22 +273,23 @@ sub nagios_inject {
|
|
|
#}
|
|
|
|
|
|
# Return alert ID
|
|
|
-sub format_alert_id($$$) {
|
|
|
- my ($Flag,$I,$state)=@_;
|
|
|
+sub format_alert_id($$$$) {
|
|
|
+ my ($Flag,$I,$state,$acked)=@_;
|
|
|
my $M=sprintf('%02d', scalar @ACKS % 100);
|
|
|
my $N=sprintf('%02d', $I % 100);
|
|
|
if (($I == 0) && (scalar @ACKS == 0)) {
|
|
|
- return "[".$Flag.$Flag." ]/$M ";
|
|
|
+ return "[".($acked==0?'!':' ').$Flag." ]/$M ";
|
|
|
} else {
|
|
|
- return "[".$Flag.$Flag.$state_to_color->{$state}.$N.$C{Z}."]/$M ";
|
|
|
+ return "[".($acked==0?'!':' ').$Flag.$state_to_color->{$state}.$N.$C{Z}."]/$M ";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
# Add alert to array / index
|
|
|
-sub insert_alert($$$$$) {
|
|
|
+sub insert_alert($$$$$$) {
|
|
|
#Irssi::print(">> On vire $host/$svc");
|
|
|
- my $i;
|
|
|
- ( $host, $svc, $state, $msg, $d ) = @_;
|
|
|
+ my $i;
|
|
|
+ my $acked;
|
|
|
+ ( $host, $svc, $state, $msg, $d, $acked ) = @_;
|
|
|
# ALERT
|
|
|
if ( $state eq 'WARNING' || $state eq 'CRITICAL' || $state eq 'UNKNOWN' || $state eq 'DOWN' ) {
|
|
|
while ($i <= $#ACKS) {
|
|
@@ -299,18 +300,18 @@ sub insert_alert($$$$$) {
|
|
|
if ($ACKS[$i]->[2] ne $state) {
|
|
|
# Same alert, but different level
|
|
|
$ACKS[$i]->[2]=$state;
|
|
|
- return format_alert_id('C', $i, $state);
|
|
|
+ return format_alert_id('c', $i+1, $state,0);
|
|
|
} else {
|
|
|
# Same alert
|
|
|
- return format_alert_id('!', $i, $state);
|
|
|
+ return format_alert_id('!', $i+1, $state,0);
|
|
|
# No need to display...
|
|
|
}
|
|
|
}
|
|
|
$i++;
|
|
|
}
|
|
|
# New alert, insert.
|
|
|
- push (@ACKS, [ $host, $svc, $state, $msg, $d ] );
|
|
|
- return format_alert_id('+',scalar @ACKS,$state);
|
|
|
+ push (@ACKS, [ $host, $svc, $state, $msg, $d, $acked ] );
|
|
|
+ return format_alert_id('+',scalar @ACKS,$state,0);
|
|
|
# Clear alert
|
|
|
} else {
|
|
|
# Irssi::print(">> On vire $host/$svc");
|
|
@@ -321,11 +322,11 @@ sub insert_alert($$$$$) {
|
|
|
$ACKS[$i] = pop @ACKS;
|
|
|
$i=$#ACKS;
|
|
|
Irssi::print(">> found $i");
|
|
|
- return format_alert_id('-',$i+1,$state);
|
|
|
+ return format_alert_id('-',$i+1,$state,1);
|
|
|
}
|
|
|
$i++;
|
|
|
}
|
|
|
- return format_alert_id('?',0,$state);
|
|
|
+ return format_alert_id('?',0,$state,1);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -412,27 +413,34 @@ sub nagios_query_status($){
|
|
|
my ($option)=@_;
|
|
|
my @unixcat;
|
|
|
my $unixline;
|
|
|
+ my $acked;
|
|
|
$nagioscmd = Irssi::settings_get_str("nagios_command");
|
|
|
+ foreach $acked (0,1) {
|
|
|
foreach $unixline ( `echo "GET services
|
|
|
-Columns: last_state_change host_name display_name state plugin_output
|
|
|
+Columns: last_state_change host_alias display_name state plugin_output
|
|
|
Filter: state > 0
|
|
|
-Filter: acknowledged = 0
|
|
|
+Filter: acknowledged = $acked
|
|
|
And: 2" | unixcat $nagioscmd` ) {
|
|
|
+ chomp $unixline;
|
|
|
($d,$host,$service,$state,$output)=split /;/,$unixline;
|
|
|
- handle_alert($option,$d,'SERVICE',$host,$NagStates[$state+10],$output,$service);
|
|
|
+ handle_alert($option,$d,'SERVICE',$host,$NagStates[$state+10],$output,$service,$acked);
|
|
|
Irssi::print("%B>>%n $unixline", MSGLEVEL_CLIENTCRAP);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
return;
|
|
|
+ foreach $acked (0,1) {
|
|
|
foreach $unixline ( `echo "GET hosts
|
|
|
-Columns: last_state_change host_name state plugin_output
|
|
|
+Columns: last_state_change host_alias state plugin_output
|
|
|
Filter: state > 0
|
|
|
Filter: acknowledged = 0
|
|
|
And: 2" | unixcat $nagioscmd` ) {
|
|
|
+ chomp $unixline;
|
|
|
($d,$host,$state,$output)=split /;/,$unixline;
|
|
|
- handle_alert($option,$d,'HOST',$host,$NagStates[$state],$output,"");
|
|
|
+ handle_alert($option,$d,'HOST',$host,$NagStates[$state],$output,"",$acked);
|
|
|
Irssi::print("%B>>%n $unixline", MSGLEVEL_CLIENTCRAP);
|
|
|
}
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
##########################################################################
|
|
@@ -454,14 +462,14 @@ sub parse_nagios_log($){
|
|
|
if (@match=$status_line =~ /\[?(\d+)\]? HOST ALERT: ([^@;]+)[@;]([^;@]+)[@;]HARD[@;][^;@]*[@;](.+)/) {
|
|
|
# HOST ########################
|
|
|
($d,$host,$state,$output)=@match;
|
|
|
- handle_alert($option,$d,"HOST",$host,$state,$output,$service);
|
|
|
+ handle_alert($option,$d,"HOST",$host,$state,$output,$service,0);
|
|
|
|
|
|
# SERVICE #####################
|
|
|
} elsif (@match=$status_line =~ /\[?(\d+)\]? (\w+) ALERT: ([^;@]+)[@;]([^;@]+)[@;]([^;@]+)[@;]HARD[@;][^;@]*[@;](.+)/) {
|
|
|
($d,$type,$host,$service,$state,$output)=@match;
|
|
|
|
|
|
$service=~s/[^\w\d_-]/_/g;
|
|
|
- handle_alert($option,$d,$type,$host,$state,$output,$service);
|
|
|
+ handle_alert($option,$d,$type,$host,$state,$output,$service,0);
|
|
|
|
|
|
# OTHER #######################
|
|
|
} elsif (@match=$status_line =~ /\[\d+\] (\w+) ALERT: (.*)/) {
|
|
@@ -477,16 +485,17 @@ sub parse_nagios_log($){
|
|
|
}
|
|
|
|
|
|
# Use alert fields to print and insert it
|
|
|
-sub handle_alert($$$$$$$) { # $d,$type,$host,$state,$output,$service
|
|
|
+sub handle_alert($$$$$$$$) { # $d,$type,$host,$state,$output,$service,acked
|
|
|
my $option;
|
|
|
+ my $acked;
|
|
|
|
|
|
# Temporisation
|
|
|
- ($option,$d,$type,$host,$state,$output,$service)=@_;
|
|
|
+ ($option,$d,$type,$host,$state,$output,$service,$acked)=@_;
|
|
|
next if exists $renot{"$host:$service"} && $renot{"$host:$service"} >= time() - 5;
|
|
|
$renot{"$host:$service"} = time();
|
|
|
|
|
|
# HOST or SERVICE ?
|
|
|
- $id = insert_alert($host,$service,$state,$output,$d);
|
|
|
+ $id = insert_alert($host,$service,$state,$output,$d,$acked);
|
|
|
$msg = "$id".$state_to_color->{$state} . "$host:$service".$C{Z}." is $state : $output";
|
|
|
#Irssi::print( "%B>>%n $IRSSI{name} $msg", MSGLEVEL_CLIENTCRAP);
|
|
|
|
|
@@ -547,24 +556,42 @@ sub event_privmsg($$$$) {
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
" ".scalar @ACKS." alertes");
|
|
|
}
|
|
|
- elsif ($arg =~ /^list/i) {
|
|
|
+ elsif ($arg =~ /^list ?(.*)/i) {
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
" ".scalar @ACKS." alertes");
|
|
|
my $i=0;
|
|
|
+
|
|
|
+ # Do you search on pattern (whole database), or a list (reduced database) ?
|
|
|
+ my $grepto;
|
|
|
+ my $motif=$1;
|
|
|
+ $motif="" unless defined($motif) ;
|
|
|
+ my $search_unack=0;
|
|
|
+ $search_unack="1" if $motif eq "";
|
|
|
+
|
|
|
foreach $K (@ACKS) {
|
|
|
+ my $grepto="@$K";
|
|
|
+ # just display alert fields, with colors.
|
|
|
+ # See ACKS fields organization
|
|
|
+ # Field 5 is "Alert has been previously acknowledged"
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
- " ". format_alert_id(' ',$i++,$K->[2]) ." ".$K->[0]." / $K->[1] / $K->[2] / $K->[3] / ".time2date $K->[4]);
|
|
|
+ " ". time2date ($K->[4])." ".
|
|
|
+ format_alert_id(' ', $i, $K->[2], $K->[5]).
|
|
|
+ " ". $state_to_color->{$K->[2]}.$K->[0]."/".$K->[1].$C{Z}.
|
|
|
+ " / $K->[2]".($K->[5]?" Acked":"")." : $K->[3]"
|
|
|
+ ) if ( ($grepto =~ /$motif/i) || ($search_unack && ($K->[5]==0)) );
|
|
|
+ # Display only if : $motif is found, or $motif is empty, and alert is unack
|
|
|
+ $i++;
|
|
|
}
|
|
|
}
|
|
|
elsif ($arg =~ /^help/i) {
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
- " !nagios list : liste des alertes nagios reçues ici");
|
|
|
+ " !nagios list [pattern] : liste des alertes nagios reçues ici");
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
" !nagios help : l'aide");
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
- " !nagios ack <#ALERTE> <message> : aquitte l'alerte");
|
|
|
+ " !nagios ack <#ALERTE> <message> TODO : aquitte l'alerte");
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
- " !nagios check <#ALERTE> : recheck une alerte donnée (service/host)");
|
|
|
+ " !nagios check <#ALERTE> TODO : recheck une alerte donnée (service/host)");
|
|
|
$server->command ( "msg ".$nagios_ack_channel.
|
|
|
" !nagios refresh [silent] : interroge le nagios pour avoir la liste de toutes les alertes");
|
|
|
} elsif ( $arg =~ /^check ?(.*)/i ){
|