#!/usr/bin/perl # # nagios2psyc: psyc notification script for nagios # written by Gabor Adam Toth # based on git2psyc and rss4nagios. # # This script uses nagios environment variables, # enable it by setting enable_environment_macros=1 in nagios.cfg # (or set manually at the command_line with NAGIOS_FOO="$FOO$") # for some reason i had to set an additional dummy env var to enable it: # # define command { # command_name notify-by-psyc # command_line NAGIOS_ENV=1 /usr/local/bin/nagios2psyc # } # # CONFIGURATION # - set address directives in contact definitions # - add notify-by-psyc command and set service/host_notification_commands # - create a psyc.cfg in /etc/nagios (copy the part between =pod & =cut below) =pod # Options for nagios2psyc # Use address directives in contact definitions, write ADDRESS here # this will use address1: $contact_directive = 'ADDRESS0'; $nagios_url = "https://nagios.example.org/cgi-bin/extinfo.cgi"; =cut #use warnings; use strict; use URI::Escape; use Socket; { package Settings; do "/etc/nagios/psyc.cfg" } my $dir = uc $Settings::contact_directive; my $target = $ENV{"NAGIOS_CONTACT$dir"}; #exit if contact has no psyc address defined exit unless $target; #use Data::Dumper; #open LOG, '>>/tmp/nagios-psyc.log'; #print "target: $target\n\n"; #print LOG Dumper(\%ENV); #close LOG; my ($method,$data,$ack,%packet); $ack = "ACKNOWLEDGEMENT" if $ENV{NAGIOS_NOTIFICATIONTYPE} eq "ACKNOWLEDGEMENT"; # variable names aren't all psyc conformant.. FIXME someday if ($ENV{NAGIOS_SERVICESTATE}) { %packet = ( _state => $ack || $ENV{NAGIOS_SERVICESTATE}, _host => $ENV{NAGIOS_HOSTNAME}, _desc => $ENV{NAGIOS_SERVICEDESC}, _output => $ENV{NAGIOS_SERVICEOUTPUT}, _ackauthor => $ENV{NAGIOS_SERVICEACKAUTHOR}, _ackcomment => $ENV{NAGIOS_SERVICEACKCOMMENT}, _url => "${Settings::nagios_url}?type=2&host=$ENV{NAGIOS_HOSTNAME}&service=".uri_escape($ENV{NAGIOS_SERVICEDESC}), ); $method = "_notice_service_" . lc $packet{_state}; $data = "SERVICE [_state]: [_host] [_desc] - [_output] - [_url]"; } elsif ($ENV{NAGIOS_HOSTSTATE}) { %packet = ( _state => $ack || $ENV{NAGIOS_HOSTSTATE}, _host => $ENV{NAGIOS_HOSTNAME}, _output => $ENV{NAGIOS_HOSTOUTPUT}, _ackauthor => $ENV{NAGIOS_HOSTACKAUTHOR}, _ackcomment => $ENV{NAGIOS_HOSTACKCOMMENT}, _url => "${Settings::nagios_url}?type=1&host=$ENV{NAGIOS_HOSTNAME}", ); $method = '_notice_host_' . lc $packet{dt}; $data = "HOST [_state]: [_host] - [_output] - [_url]"; } else { die "no host/service data"; } # PSYC socket stuff: my ($delim, $delimre); if ($psycver >= 1.0) { $delim = '|'; $delimre = qr/\|/; } else { $delim = '.'; $delimre = qr/\./; } my ($host, $port); if ($target =~ m#^psyc://([\w.-]+)(?::(\d+))?#i) { $host = $1; $port = $2 || 4404; } else { die "target invalid: $target"; } my $iaddr = inet_aton($host) || die "no host: $host"; my $paddr = sockaddr_in($port, $iaddr); # there is no real reason why we aren't using UDP here... socket(S, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die "socket: $!"; connect(S, $paddr) || die "connect: $!"; select S; $|=1; select STDOUT; print S <) && !/^$delim/) { die "Error while establishing circuit: invalid greeting"; } while (defined($_ = ) && !/^$delim/) { # print if s/^=//; } #print "\n"; # THE MESSAGE: print S ":_target\t$target\n\n"; print S ":$_\t$packet{$_}\n" for (keys %packet); print S <