Jump to content
Fórum Script Brasil

Search the Community

Showing results for tags 'nagios'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Programação & Desenvolvimento
    • ASP
    • PHP
    • .NET
    • Java
    • C, C++
    • Delphi, Kylix
    • Lógica de Programação
    • Mobile
    • Visual Basic
    • Outras Linguagens de Programação
  • WEB
    • HTML, XHTML, CSS
    • Ajax, JavaScript, XML, DOM
    • Editores
  • Arte & Design
    • Corel Draw
    • Fireworks
    • Flash & ActionScript
    • Photoshop
    • Outros Programas de Arte e Design
  • Sistemas Operacionais
    • Microsoft Windows
    • GNU/Linux
    • Outros Sistemas Operacionais
  • Softwares, Hardwares e Redes
    • Microsoft Office
    • Softwares Livres
    • Outros Softwares
    • Hardware
    • Redes
  • Banco de Dados
    • Access
    • MySQL
    • PostgreSQL
    • SQL Server
    • Demais Bancos
  • Segurança e Malwares
    • Segurança
    • Remoção De Malwares
  • Empregos
    • Vagas Efetivas
    • Vagas para Estágios
    • Oportunidades para Freelances
  • Negócios & Oportunidades
    • Classificados & Serviços
    • Eventos
  • Geral
    • Avaliações de Trabalhos
    • Links
    • Outros Assuntos
    • Entretenimento
  • Script Brasil
    • Novidades e Anúncios Script Brasil
    • Mercado Livre / Mercado Sócios
    • Sugestões e Críticas
    • Apresentações

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

Found 1 result

  1. #!/usr/bin/perl -w # # ########################### nagios_send_host_mail.pl ################ # # Date : July 16, 2012 # # Purpose : Script to send out Nagios e-mails.\n"; # # Author : Frank Migge (support at frank4dd dot com) # # Help : http://nagios.frank4dd.com/howto # # Licence : GPL - http://www.fsf.org/licenses/gpl.txt # # Written for and verified with Nagios version 3.4.1 # # Help : ./nagios_send_host_mail.pl -h # # Depends : perl-Mail-Sendmail (Mail::Sendmail) # # perl-MIME-tools (MIME::Base64) # # rrdtool-devel # # libnetpbm (conversion png-to-jpg) # # netpbm (see above) # # ##################################################################### # use Getopt::Long; use Mail::Sendmail; use Digest::MD5 qw(md5_hex); use MIME::Base64; use File::Temp; use RRDs; use strict; use warnings; use vars qw( $logo_id $graph_id $tmpfile $land $tbl $var %param_vars $elapse $tstamp $tstart $img_get); # The version of this script my $Version ='1.7.3'; # the sender e-mail address to be seen by recipients my $mail_sender = "Nagios Monitoring <nagios\@frank4dd.com>"; # The Nagios CGI URL for integrated links my $nagios_cgiurl = "http://nagios.frank4dd.com/nagios/cgi-bin"; # Here we define a simple HTML stylesheet to be used in the HTML header. my $html_style = "body {text-align: center; font-family: Verdana, sans-serif; font-size: 10pt;}\n" . "img.logo {float: left; margin: 10px 10px 10px; vertical-align: middle}\n" . "span {font-family: Verdana, sans-serif; font-size: 12pt;}\n" . "table {text-align:center; margin-left: auto; margin-right: auto;}\n" . "th {white-space: nowrap;}\n" . "th.even {background-color: #D9D9D9;}\n" . "td.even {background-color: #F2F2F2;}\n" . "th.odd {background-color: #F2F2F2;}\n" . "td.odd {background-color: #FFFFFF;}\n" . "th,td {font-family: Verdana, sans-serif; font-size: 10pt; text-align:left;}\n" . "th.customer {width: 600px; background-color: #004488; color: #ffffff;}"; my $table_size = "600px"; my $header_size = "180px"; my $data_size = "420px"; my $debugtables = "<br>\n"; # ######################################################################## # For tests using the -t/--test option, if we want to see Nagiosgraph # graphs we need to set a valid host name and service name below. # ######################################################################## my $test_host = "susie114"; # existing host in Nagios # ######################################################################## # Here we set the information where to pick up the RRD data files for the # optional graph image generation, plus the graph size width x height px # ######################################################################## my $ngraph_cgiurl = "http://nagios.frank4dd.com/nagios/cgi-bin/show.cgi"; my $rrd_basedir = "/srv/app/nagiosgraph/rrd"; my $graph_img_size = "521x60"; my $graph_bgcolor = "#F2F2F2"; my $graph_border = "#999999"; # ######################################################################## # SMTP related data: If the commandline argument -H/--smtphost was not # given, we use the provided value in $o_smtphost below as the default. # If the mailserver requires auth, an example is further down the code. # ######################################################################## my $o_smtphost = "192.168.1.64"; my $domain = "\@yourdomain"; # only for -g group my @listaddress = (); # ######################################################################## # This is the logo image file, the path must point to a valid JPG, GIF or # PNG file, i.e. the nagios logo. Best size is rectangular up to 160x80px. # example: [nagioshome]/share/images/NagiosEnterprises-whitebg-112x46.png # ######################################################################## my $logofile = "/srv/www/std-root/nagios.frank4dd.com/images/nagios-logo.gif"; # ######################################################################## # Because our mail system being Lotus Notes, which is not supporting PNG # images, we must convert them from PNG to JPG before we can continue. # Set $jpg_workaround = true if your mail client has the same trouble. # ######################################################################## my $jpg_workaround = undef; # ######################################################################## # Here I define the HTML color values for each Nagios notification type. # There is one extra called TEST for sending a test e-mail from the cmdline # outside of Nagios. The color values are used for highlighting the # background of the notification type cell. # ######################################################################## my %NOTIFICATIONCOLOR=('PROBLEM'=>'#FF8080','RECOVERY'=>'#80FF80','ACKNOWLEDGEMENT'=>'FFFF80', 'DOWNTIMESTART'=>'80FFFF','DOWNTIMEEND'=>'80FF80','DOWNTIMECANCELLED'=>'FFFF80', 'FLAPPINGSTART'=>'#FF8080','FLAPPINGSTOP'=>'#80FF80',' FLAPPINGDISABLED'=>'FFFF80', 'TEST'=>'80FFFF'); # ######################################################################## # language translated message text: $language{$land}{'A'} (=Customer) # You can simply add here your translation... # ######################################################################## my %language = ('en' => { 'A' => 'Customer', 'B' => 'Notification Type', 'C' => 'Host Status', 'D' => 'Hostname', 'E' => 'Hostalias', 'F' => 'IP Address', 'G' => 'Hostgroup', 'H' => 'Event Time', 'I' => 'Host Output', 'J' => 'Author', 'K' => 'Comment', 'L' => 'Nagios Monitoring System Notification', 'M' => 'Generated by Nagios, the OpenSource monitoring solution' }, 'fr' => { 'A' => 'Utilisateur', 'B' => 'Type de notification', 'C' => 'Statut d\'hôte', 'D' => 'Nom d\'hôte', 'E' => 'Alias d\'hôte', 'F' => 'Adresse IP', 'G' => 'Groupe d\'hôte', 'H' => 'Heure de la notification', 'I' => 'Données', 'J' => 'Auteur', 'K' => 'Commentaire', 'L' => 'Notification de la surveillance Nagios', 'M' => 'Généré par Nagios, le système de surveillance OpenSource' }, 'de' => { 'A' => 'Anwender', 'B' => 'Nachrichtentyp', 'C' => 'Systemzustand', 'D' => 'Systemname', 'E' => 'Systemalias', 'F' => 'System IP Adresse', 'G' => 'Systemgruppe', 'H' => 'Meldungsdatum', 'I' => 'Systemnachricht', 'J' => 'Author', 'K' => 'Kommentar', 'L' => 'Nagios Überwachungssytem Meldung', 'M' => 'Erstellt mit Nagios, dem OpenSource Überwachungssytem' }, 'jp' => { 'A' => '顧客名', 'B' => '通知の種類', 'C' => 'ホストの状態', 'D' => 'ホスト名', 'E' => 'ホストの別名', 'F' => 'IPアドレス', 'G' => 'ホストグループ', 'H' => 'イベントの日付と時刻', 'I' => 'ホストデータ出力', 'J' => '投稿者', 'K' => 'コメント', 'L' => 'Nagios 監視システムの通知', 'M' => 'このメッセージはオープンソースの監視システムNagiosで生成されています。' }); ####### Global Variables - No changes necessary below this line ########## # Nagios notification type, i.e. PROBLEM my $o_notificationtype = $ENV{NAGIOS_NOTIFICATIONTYPE}; # Nagios notification author (if avail.) my $o_notificationauth = $ENV{NAGIOS_NOTIFICATIONAUTHOR}; # Nagios notification comment (if avail.) my $o_notificationcmt = $ENV{NAGIOS_NOTIFICATIONCOMMENT}; # Nagios monitored host name my $o_hostname = $ENV{NAGIOS_HOSTNAME}; # Nagios monitored host alias my $o_hostalias = $ENV{NAGIOS_HOSTALIAS}; # Nagios host group the host belongs to my $o_hostgroup = $ENV{NAGIOS_HOSTGROUPNAME}; # Nagios monitored host IP address my $o_hostaddress = $ENV{NAGIOS_HOSTADDRESS}; # Nagios monitored host state, i.e. DOWN my $o_hoststate = $ENV{NAGIOS_HOSTSTATE}; # Nagios monitored host check output data my $o_hostoutput = $ENV{NAGIOS_HOSTOUTPUT}; # Nagios date when the event was recorded my $o_datetime = $ENV{NAGIOS_LONGDATETIME}; # The recipients defined in $CONTACTEMAIL$ my $o_to_recipients = $ENV{NAGIOS_CONTACTEMAIL}; # Modified by Robert Becht for using $CONTACTGROUPEMEMBERS$ in nagios.conf my $recipient_group = $ENV{NAGIOS_CONTACTGROUPMEMBERS}; # The next variables are provided through args my $o_to_group = undef; # this flag is only set with the -g option my $o_cc_recipients = undef; # The recipients defined in $CONTACTADDRESS1$ my $o_bcc_recipients = undef; # The recipients defined in $CONTACTADDRESS2$ my $o_format = "text";# The e-mail output format (default: text) my $o_addurl = undef; # flag to add Nagios GUI URLs to HTML e-mails my $o_language = undef; # The e-mail output language my $o_lang_def = "en"; # The e-mail output language default my $o_customer = undef; # Company name and contract number for service providers my $o_help = undef; # We want help my $o_verb = undef; # verbose mode my $o_version = undef; # print version my $o_test = undef; # generate a test message # These variables are used in various subroutines my $text_msg = undef; # the plaintext notification my $html_msg = undef; # the HTML-formatted notification my $graphfile = undef; # if we generate graphs, the tmp file location my $logo_img = undef; # base64-encoded logo my $logo_type = undef; # logo image file format (jpg, gif, or png) my $graph_img = undef; # base64-encoded graph my $graph_type = undef; # graph image file format (jpg, gif, or png) my $boundary = undef; # unique string for multi-part emails my %mail; # $empty_img is a base64-encoded, white 1x1 pixel gif image, we # use it if the logo or the Nagiosgraph data cannot be found. my $empty_img = "R0lGODlhAQABAJEAAAAAAP///////wAAACH5BAEAAAIALAAAAAABAAEAAAICTAEAOw=="; # ######################################################################## # subroutine defintions below # ######################################################################## # ######################################################################## # p_version returns the program version # ######################################################################## sub p_version { print "nagios_send_host_mail.pl version : $Version\n"; } # ######################################################################## # print_usage returns the program usage # ######################################################################## sub print_usage { print "Usage: $0 [-v] [-V] [-h] [-t] [-H <SMTP host>] [-p <customername>] [-r <to_recipients>] or -g <to_group>] [-c <cc_recipients>] [-b <bcc_recipients>] [-f <text|html|multi|graph>] [-u] [-l <en|jp|fr|de>(or other languages if added]\n"; } # ######################################################################## # help returns the program help message # ######################################################################## sub help { print "\nNagios e-mail notification script for host events, version ",$Version,"\n"; print "This version was developed for inclusion of Nagiosgraph performance graphs.\n"; print "GPL licence, (c)2012 Frank Migge\n\n"; print_usage(); print <<EOT; This script takes over Nagios e-mail notifications by receiving the Nagios state information, formatting the e-mail and sending it out through an SMTP gateway. -v, --verbose print extra debugging information -V, --version prints version number -h, --help print this help message -t, --test generates a test message together with -r, --to-recipients -H, --smtphost=HOST name or IP address of SMTP gateway -p, --customer="customer name and contract #" optionally, add the customer name and contract for service providers -r, --to-recipients override the Nagios-provided \$CONTACTEMAIL\$ list of to: recipients -g, --to-group-recipients in \$CONTACTGROUPMEMBERS\$ instead of -r, use the list of contactgroup members and complete the mail address with the hard defined \$domain in this script. This is only possible when the contact name "abcd" works under the address "abcd\@domain". -c, --cc-recipients the Nagios-provided \$CONTACTADDRESS1\$ list of cc: recipients -b, --bcc-recipients the Nagios-provided \$CONTACTADDRESS2\$ list of bcc: recipients -f, --format='text|html|multi|graph' the email format to generate: plain ASCII text, HTML, multipart S/MIME with a logo, or multipart S/MIME - adding the Nagiosgraph performance graph image -u, --addurl this adds URL's to the Nagios web GUI for check status, host and hostgroup views into the html mail, requires -f html, multi or graph -l, --language='en|jp|fr|de|(or what you defined in this script)' the prefered e-mail language. The content-type header is hard-coded to UTF-8. Check if your recipients require a different characterset encoding. Extra: Additional debug output can be generated. Within Nagios, select a host and choose "Send custom host notification". Entering text, including the keyword "email-debug" into the "Comment" field will add additional tables containing a list of values for important Nagios and script variables. EOT } # ######################################################################## # verb creates verbose output # ######################################################################## sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } # ######################################################################## # unique content ID are needed for mulitpart messages with inline logos # ######################################################################## sub create_content_id { my $unique_string = rand(100); $unique_string = $unique_string . substr(md5_hex(time()),0,23); $unique_string =~ s/(.{5})/$1\./g; my $content_id = qq(part.${unique_string}\@) . "MAIL"; $unique_string = undef; return $content_id; } # ######################################################################## # create_boundary creates the S/MIME multipart boundary strings # ######################################################################## sub create_boundary { my $unique_string = substr(md5_hex(time()),0,24); $boundary = '======' . $unique_string ; $unique_string = undef; } sub unknown_arg { print_usage(); exit -1; } # ######################################################################## # create_address adds the domain to the groupmembers list (Robert Becht) # ######################################################################## sub create_address { chomp($recipient_group); my @mlist = split(",",$recipient_group); foreach (@mlist) { my $maddress = "$_"."$domain"; push(@listaddress,$maddress); } $recipient_group = join(",",@listaddress); return ($recipient_group); } # ######################################################################## # check_options checks and processes the commandline options given # ######################################################################## sub check_options { Getopt::Long::Configure ("bundling"); GetOptions( 'v' => \$o_verb, 'verbose' => \$o_verb, 'V' => \$o_version, 'version' => \$o_version, 'h' => \$o_help, 'help' => \$o_help, 't' => \$o_test, 'test' => \$o_test, 'H:s' => \$o_smtphost, 'smtphost:s' => \$o_smtphost, 'p:s' => \$o_customer, 'customer:s' => \$o_customer, 'r:s' => \$o_to_recipients, 'to-recipients:s' => \$o_to_recipients, 'g:s' => \$o_to_group, 'to-group-recipients' => \$o_to_group, 'c:s' => \$o_cc_recipients, 'cc-recipients:s' => \$o_cc_recipients, 'b:i' => \$o_bcc_recipients, 'bcc-recipients:s' => \$o_bcc_recipients, 'f:s' => \$o_format, 'format:s' => \$o_format, 'u' => \$o_addurl, 'addurl' => \$o_addurl, 'l:s' => \$o_language, 'language:s' => \$o_language, ) or unknown_arg(); # Basic checks if (defined ($o_help) ) { help(); exit 0}; if (defined($o_version)) { p_version(); exit 0}; if ( ! defined($o_to_recipients) ) # no recipients provided { print "Error: no recipients have been provided\n"; print_usage(); exit -1} else { if (! defined($o_to_group)) { %mail = ( To => $o_to_recipients, From => $mail_sender, Sender => $mail_sender ); } else { &create_address; %mail = ( To => $recipient_group, From => $mail_sender, Sender => $mail_sender ); } } if ( $o_format ne "text" && $o_format ne "html" && $o_format ne "multi" && $o_format ne "graph") # wrong mail format { print "Error: wrong e-mail format.\n"; print_usage(); exit -1} if (defined($o_addurl) && $o_format eq "text") { print "Error: cannot add URL's to text.\n"; print_usage(); exit -1} if (defined($o_test)) { create_test_data(); }; # Modified by Robert Becht to support additional languages # if no language has been requested, try to determine default from OS if (! defined($o_language)) { # if environment $LANG is set, try to extract the first two country chars, i.e. "en|de|fr" if ($ENV{LANG} eq "C" || $ENV{LANG} eq "POSIX") { $land = "en"; } else { ($land, my $rem) = split('_',$ENV{LANG}, 2); } } else { $land = $o_language; } # Last resort: Set "English" if the requested language is not supported by our script if (! $language{$land}{'A'}) { $land = $o_lang_def; } } # ######################################################################## # if -t or --test, we need to create sample test data to for sending out. # Most data is hardcoded. For graph generation, host and service names # must be valid so the script can pick up data from Nagiosgraph. # ######################################################################## sub create_test_data { if (! defined($o_customer)){ $o_customer = "ACME Corporation";} if (! defined($o_notificationtype)){ $o_notificationtype = "TEST";} if (! defined($o_hoststate)){ $o_hoststate = "UNKNOWN";} if (! defined($o_hostname)){ $o_hostname = $test_host;} if (! defined($o_hostalias)){ $o_hostalias = "Test host alias (placeholder)";} if (! defined($o_hostaddress)){ $o_hostaddress = "192.168.1.1";} if (! defined($o_hostgroup)){ $o_hostgroup = "Linux Servers";} if (! defined($o_datetime)){ $o_datetime = `date`;} if (! defined($o_hostoutput)){ $o_hostoutput = "Test output for this host";} if (! defined($o_notificationauth)){ $o_notificationauth = "John Doe";} # Setting the keyword "email-debug" in the notification comment below triggers the creation of debug tables if (! defined($o_notificationcmt)){ $o_notificationcmt = "Host notification test message including email-debug";} } # ######################################################################## # Create a plaintext message -> $text_msg # ######################################################################## sub create_message_text { $text_msg = $language{$land}{'L'}."\n" . "=====================================\n\n"; # if customer name was given for service providers, display it here if ( defined($o_customer)) { $text_msg .= $language{$land}{'A'} . ": $o_customer\n"; } $text_msg = $text_msg . $language{$land}{'B'} . ": $o_notificationtype\n" . $language{$land}{'C'} . ": $o_hoststate\n" . $language{$land}{'D'} . ": $o_hostname\n" . $language{$land}{'E'} . ": $o_hostalias\n" . $language{$land}{'F'} . ": $o_hostaddress\n" . $language{$land}{'G'} . ": $o_hostgroup\n" . $language{$land}{'H'} . ": $o_datetime\n" . $language{$land}{'I'} . ": $o_hostoutput\n\n"; # if author and comment data has been passed from Nagios # and these variables have content, then we add two more columns if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) && ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) { $text_msg .= $language{$land}{'J'} . ": $o_notificationauth\n" . $language{$land}{'K'} . ": $o_notificationcmt\n\n"; } $text_msg .= "-------------------------------------\n" . $language{$land}{'M'} . "\n"; } # ######################################################################## # Create a HTML message -> $html_msg, per flags include URL's and IMG's # ######################################################################## sub create_message_html { # Start HTML message definition $html_msg = "<html><head><style type=\"text/css\">$html_style</style></head><body>\n" . "<table width=$table_size><tr>\n"; if ($o_format eq "multi" || $o_format eq "graph") { $logo_id = create_content_id(); $html_msg .= "<td><img class=\"logo\" src=\"cid:$logo_id\"></td>" . "<td><span>$language{$land}{'L'}</span></td></tr><tr>\n"; } else { $html_msg .= "<th colspan=2><span>$language{$land}{'L'}</span></th></tr><tr>\n"; } if ( defined($o_customer)) { $html_msg .= "<th colspan=2 class=customer>$o_customer</th></tr><tr>\n"; } $html_msg = $html_msg . "<th width=$header_size class=even>$language{$land}{'B'}:</th>\n" . "<td bgcolor=$NOTIFICATIONCOLOR{$o_notificationtype}>\n" . "$o_notificationtype</td></tr>\n" . "<tr><th class=odd>$language{$land}{'C'}:</th><td>$o_hoststate</td></tr>\n" . "<tr><th class=even>$language{$land}{'D'}:</th><td class=even>\n"; if (defined($o_addurl)) { $html_msg .= "<a href=\"$nagios_cgiurl/status.cgi?host=" . urlencode($o_hostname) ."&style=detail\">$o_hostname</a>"; } else { $html_msg .= $o_hostname; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'E'}:</th><td>$o_hostalias</td></tr>\n" . "<tr><th class=even>$language{$land}{'F'}:</th><td class=even>$o_hostaddress</td></tr>\n" . "<tr><th class=odd>$language{$land}{'G'}:</th><td>\n"; if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?hostgroup=" . urlencode($o_hostgroup) ."&style=overview\">$o_hostgroup</a>"; } else { $html_msg .= $o_hostgroup; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=even>$language{$land}{'H'}:</th><td class=even>$o_datetime</td></tr>\n" . "<tr><th class=odd>$language{$land}{'I'}:</th><td>\n"; if (defined($o_addurl)) { $html_msg .= "<a href=\"$nagios_cgiurl/status.cgi?type=1&host=" . urlencode($o_hostname) . "\">$o_hostoutput</a>\n"; # If the graph image wasn't empty, We add an additional link for Nagiosgraph if ($o_format eq "graph" && $graph_type ne "gif") { $html_msg .= ", see also <a href=\"$ngraph_cgiurl?host=" . urlencode($o_hostname) ."&service=check-host-alive&geom=". $graph_img_size ."\">Nagiosgraph</a>\n"; } } else { $html_msg = $html_msg . $o_hostoutput; } $html_msg = $html_msg . "</td></tr>\n"; # If the author and comment data has been passed from Nagios # and these variables have content, then we add two more columns if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) && ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) { $html_msg .= "<tr><th class=even>$language{$land}{'J'}:</th>\n" . "<td class=even>$o_notificationauth</td></tr>\n" . "<tr><th class=odd>$language{$land}{'K'}:</th>\n" . "<td>$o_notificationcmt</td></tr>\n"; } $html_msg .= "</table><br>\n"; # if we got the graph format and a image has been generated, we add it here if (defined($graph_img) && $o_format eq "graph") { $graph_id = create_content_id(); $html_msg .= "<img src=\"cid:$graph_id\">\n"; } # add the Nagios footer tag line here $html_msg .= "<br><hr>\n$language{$land}{'M'}\n<hr>\n"; # add the extra debugtables if verbose output had been requested, # or if the notification command contains the keyword "email-debug" if (defined($o_notificationcmt) && ($o_notificationcmt =~ m/email-debug/i) || defined($o_verb)) { &create_debugtable; $html_msg .= $debugtables; } # End HTML message definition $html_msg .= "</body></html>\n"; } # ####################################################################### # urlencode() URL encode a string # ####################################################################### sub urlencode { my $urldata = $_[0]; my $MetaChars = quotemeta( '-;,/?\|=+)(*&^%$#@!~`:'); $urldata =~ s/([$MetaChars\"\'\x80-\xFF])/"%" . uc(sprintf("%2.2x", ord($1)))/eg; $urldata =~ s/ /\+/g; return $urldata; } # ######################################################################## # b64encode_image(filename) converts a existing binary source image file # into a base64-image string. # ######################################################################## sub b64encode_img { my($inputfile) = @_; open (IMG, $inputfile) or verb("b64encode_img: Cannot read source image file: $inputfile - $!"); binmode IMG; undef $/; my $b64encoded_img = encode_base64(<IMG>); close IMG; verb("b64encode_img: completed conversion of source image file: $inputfile - $!"); return $b64encoded_img; } # ####################################################################### # hashcolor() Choose a color for the Nagiosgraph RRD service # ####################################################################### sub hashcolor { my $c=0; map{$c=(51*$c+ord)%(216)}split//,"$_[0]x"; my $i = 0; my $n = 0; my $m = 0; my @h=(51*int $c/36,51*int $c/6%6,51*($c%6)); for$i(0..2){$m=$i if$h[$i]<$h[$m];$n=$i if$h[$i]>$h[$n]} $h[$m]=102if$h[$m]>102;$h[$n]=153if$h[$n]<153; $c=sprintf"%06X",$h[2]+$h[1]*256+$h[0]*16**4; return $c; } # ####################################################################### # dbfilelist() Get list of matching Nagiosgraph RRD files # ####################################################################### sub dbfilelist { my($host,$service, $rrddir) = @_; my $hs; # New style, files inside a <hostname> directory $rrddir .= "/" . $host; $hs = urlencode "$service" . "___"; verb("sub dbfilelist: Checking files inside directory: ".$rrddir."/".$hs); my @rrd; opendir DH, $rrddir; @rrd = grep s/^${hs}(.+)\.rrd$/$1/, readdir DH; closedir DH; verb("sub dbfilelist: We found number of files: ".@rrd); return @rrd; } # ####################################################################### # graphinfo() Find graphs and values in Nagiosgraph # ####################################################################### sub graphinfo { my($host,$service,$rrddir) = @_; my(@rrd,$ds,$f,$dsout,@values,$hs,%H,%R); $hs = $host . "/"; $hs .= urlencode "$service" . "___"; # Determine which files to read lines from @rrd = map {{ file=>$_ }} map { "${hs}${_}.rrd" } dbfilelist($host,$service, $rrddir); # we stop processing here if we could not find a file if (@rrd < 1) { verb("sub graphinfo: Could not find any graph file."); return undef; } else { verb("sub graphinfo: Listing $hs db files in $rrddir: " . join ', ', map { $_->{file} } @rrd); } for $f ( @rrd ) { unless ( $f->{line} ) { $ds = RRDs::info "$rrddir/$f->{file}"; verb("sub graphinfo: RRDs::info ERR " . RRDs::error) if RRDs::error; map { $f->{line}{$_} = 1} grep {!$H{$_}++} map { /ds\[(.*)\]/; $1 } grep /ds\[(.*)\]/, keys %$ds; } verb("DS $f->{file} lines: " . join ', ', keys %{ $f->{line} } ); } return \@rrd; } # ####################################################################### # rrdline() Generate the Nagiosgraph RRD parameters to produce a graph # ####################################################################### sub rrdline { my($host,$service,$geom,$G,$rrddir,$tmpfile) = @_; my($g,$f,$v,$c,@ds); my $directory = $rrddir; @ds = ($tmpfile, '-a', 'PNG', '-t', $service); push @ds, "--color=BACK$graph_bgcolor", "--color=SHADEA$graph_border", "--color=SHADEB$graph_border"; # Identify where to pull data from and what to call it for $g ( @$G ) { $f = $g->{file}; verb("file=$f"); # Compute the longest label length my $longest = (sort map(length,keys(%{ $g->{line} })))[-1]; for $v ( sort keys %{ $g->{line} } ) { $c = hashcolor($v); verb("sub rrdline: file=$f line=$v color=$c"); my $sv = "$v"; my $label = sprintf("%-${longest}s", $sv); push @ds , "DEF:$sv=$directory/$f:$v:AVERAGE" , "LINE2:${sv}#$c:$label"; my $format = '%6.2lf%s'; # Graph labels push @ds, "GPRINT:$sv:MAX:Max\\: $format" , "GPRINT:$sv:AVERAGE:Avg\\: $format" , "GPRINT:$sv:MIN:Min\\: $format" , "GPRINT:$sv:LAST:Cur\\: ${format}\\n"; } } # Dimensions of graph if geom is specified if ( $geom ) { my($w,$h) = split 'x', $geom; push @ds, '-w', $w, '-h', $h; } return @ds; } # ####################################################################### # create_graph_img() tries to create a base64-encoded performance graph # image. It takes the hostname and servicename and tries to find a # matching RRD file according to the Nagiosgraphs layout. If there is one, # queries the RRD information and graphs the last 24 hours similar to # Nagiosgraph. # ####################################################################### sub create_graph_image { use FileHandle; my $G = undef; # Figure out the correct RRD db files and their line labels $G = graphinfo($o_hostname,"check-host-alive",$rrd_basedir); # if we could not find RRD data, we return the empty $graph_img if(! defined($G)) { verb("create_graph_image: Cannot generate the Nagiosgraph image file."); # In this case, we use the 1x1px empty image and return $graph_type = "gif"; $graph_img = $empty_img; verb("create_graph_image: Returning empty image file, format: ".$graph_type."\n"); return $graph_img; } # generate temporary graph file my $fhandle = File::Temp->new(UNLINK =>1) or verb("import_pnp_graph: Cannot create temporary image file."); $fhandle->autoflush(1); $tmpfile = $fhandle->filename; my @ds = rrdline($o_hostname,"check-host-alive",$graph_img_size,$G,$rrd_basedir,$tmpfile); verb("sub create_graph_image: RRDs::graph ". join ' ', @ds); RRDs::graph(@ds); verb("sub create_graph_image: RRDs::graph ERR " . RRDs::error) if RRDs::error; # Because our mail system being Lotus Notes, which is not supporting PNG # images, we must convert them from PNG to JPG before we can continue. # Set $jpg_workaround = true if your mail client has the same trouble. if (defined($jpg_workaround)) { my $tmpfile_new = $tmpfile.".jpg"; `pngtopnm $tmpfile | pnmtojpeg >$tmpfile_new`; `mv $tmpfile_new $tmpfile`; $graph_type = "jpg"; } else { $graph_type = "png"; } # Since the graph images are raw png files, we need to encode them $graph_img = b64encode_img($tmpfile); verb("import_pnp_graph: Encoded Nagiosgraph image file, format: ".$graph_type."\n"); return $graph_img; } # ######################################################################## # language translated email subject: $lang{$land} # ######################################################################## sub set_subject { my $subject; my $b64_sub = ""; # special base64 encoding is required for subject parts send in Japanese if ($land eq "jp") { $b64_sub = " =?utf-8?B?" . encode_base64("ホスト $o_hostname($o_hostgroup)は"); chomp $b64_sub; $b64_sub = $b64_sub . "?= "; } # special base64 encoding is required for subject parts send in French if ($land eq "fr") { $b64_sub = " =?utf-8?B?" . encode_base64("d\'hôte $o_hostname ($o_hostgroup) est"); chomp $b64_sub; $b64_sub = $b64_sub . "?= "; } my %lang = ('en' => "Nagios: $o_notificationtype Host $o_hostname ($o_hostgroup) is $o_hoststate", 'de' => "Nagios: $o_notificationtype System $o_hostname($o_hostgroup) ist $o_hoststate", 'jp' => "Nagios: $o_notificationtype" . $b64_sub . "$o_hoststate", 'fr' => "Nagios: $o_notificationtype" . $b64_sub . "$o_hoststate" ); if (!defined($lang{$land})) { $subject = $lang{'en'}; } else { $subject = $lang{$land}; } return $subject; } ######################################################################### # main ######################################################################### check_options(); if (! defined ($o_notificationtype) && ! defined($o_test)) { p_version(); print "\nError, no notification type available. Are you trying to send a test message?\n"; print "For a manual test from the commandline, we need to give the -t option.\n"; exit -1; } $mail{Cc} = $o_cc_recipients if ($o_cc_recipients); $mail{Bcc} = $o_bcc_recipients if ($o_bcc_recipients); $mail{smtp} = $o_smtphost; $mail{subject} = set_subject(); # If the mail server requires authentication, try this line: # $mail{auth} = {user => "<username>", password => "<mailpw>", method="">"LOGIN PLAIN", required=>1}; if ($o_format eq "graph") { verb("main: trying to create the Nagiosgraph image."); $graph_img = create_graph_image(); } if ($o_format eq "multi" || $o_format eq "graph") { verb("main: Sending HTML email (language: $land) with inline logo."); # check if the logo file exists if (-e $logofile) { # In e-mails, images need to be base64 encoded, we encode the logo here $logo_img = b64encode_img($logofile); # extract the image format from the file extension $logo_type = ($logofile =~ m/([^.]+)$/)[0]; verb("main: Converted logo data to base64 and set type to $logo_type."); # create the second boundary marker for the logo } else { verb("main: Could not find logo file at $logofile, setting empty logo."); # If the logo file cannot be found, we send a 1x1px empty logo image instead $logo_img = $empty_img; $logo_type = "gif"; } create_boundary(); create_message_html(); $mail{'content-type'} = qq(multipart/related; boundary="$boundary"); $boundary = '--' . $boundary; # Here we define the mail content to be send my $mail_content = "This is a multi-part message in MIME format.\n" # create the first boundary start marker for the main message . "$boundary\n" . "Content-Type: text/html; charset=utf-8\n" . "Content-Transfer-Encoding: 8bit\n\n" . "$html_msg\n"; # create the second boundary marker for the logo image $mail_content = $mail_content . "$boundary\n" . "Content-Type: image/$logo_type; name=\"logo.$logo_type\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-ID: <$logo_id>\n" . "Content-Disposition: inline; filename=\"logo.$logo_type\"\n\n" . "$logo_img\n"; # if we got the graph format and a image has been generated, we add it here # create the third boundary marker for the graph if (defined($graph_img) && $o_format eq "graph") { $mail_content = $mail_content . "\n" . "$boundary\n" . "Content-Type: image/$graph_type; name=\"graph.$graph_type\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-ID: <$graph_id>\n" . "Content-Disposition: inline; filename=\"graph.$graph_type\"\n\n" . "$graph_img\n"; } # create the final end boundary marker $mail_content = $mail_content . $boundary . "--\n"; # put the completed message body into the mail $mail{body} = $mail_content ; } elsif ($o_format eq "html") { create_message_html(); $mail{'content-type'} = qq(text/html; charset="utf-8"); $mail{body} = $html_msg ; } else { create_message_text(); $mail{'content-type'} = qq(text/plain; charset="utf-8"); $mail{body} = $text_msg ; } sendmail(%mail) or die $Mail::Sendmail::error; verb("Sendmail Log says:\n$Mail::Sendmail::log\n"); exit 0; # ####################################################################### # Create a debugging table to check on Nagios and script variables # Added by Robert Becht to create a HTML table for debugging # ####################################################################### sub create_debugtable() { my $varcount = 0; my $oddcheck = "odd"; # Check if the following variables are defined my %param_vars = ( 'script' => { "title" => 'Script debug data', "o_verb" => \$o_verb, "o_version" => \$o_version, "o_help" => \$o_help, "o_smtphost" => \$o_smtphost, "o_customer" => \$o_customer, "o_to_recipients" => \$o_to_recipients, "o_to_group" => \$o_to_group, "o_cc_recipients" => \$o_cc_recipients, "o_bcc_recipients" => \$o_bcc_recipients, "o_format" => \$o_format, "o_addurl" => \$o_addurl, "o_language" => \$o_language, "o_test" => \$o_test, "o_smtphost" => \$o_smtphost, "domain" => \$domain, "land" => \$land, "logo file" => \$logofile, "logo format" => \$logo_type, "temporary file" => \$tmpfile, "boundary" => \$boundary }, 'nagios' => { "title" => 'Nagios debug data', "o_notificationtype" => \$o_notificationtype, "o_notificationauth" => \$o_notificationauth, "o_notificationcmt" => \$o_notificationcmt, "o_hoststate" => \$o_hoststate, "o_hostname" => \$o_hostname, "o_hostalias" => \$o_hostalias, "o_hostgroup" => \$o_hostgroup, "o_hostaddress" => \$o_hostaddress, "o_datetime" => \$o_datetime, "o_hostoutput" => \$o_hostoutput, "o_to_recipients" => \$o_to_recipients, "o_to_group" => \$o_to_group }, 'nagiosgraph' => { "title" => 'Nagiosgraph debug data', "access URL" => \$ngraph_cgiurl, "rrd_basedir" => \$rrd_basedir, "graph_img_size" => \$graph_img_size, "graph_bgcolor" => \$graph_bgcolor, "graph_type" => \$graph_type } ); # loop to display the script variable tables foreach $tbl (keys %param_vars) { $debugtables .= "<br>\n" . "<table width=$table_size>\n" . "<tr><th colspan=2 class=customer>$param_vars{$tbl}->{'title'}</th></tr>\n"; $varcount = 0; # Data loop foreach $var (keys %{$param_vars{$tbl}}) { if ($var ne 'title') { if ($varcount%2) {$oddcheck = "odd";} else {$oddcheck = "even";} $debugtables .= "<tr><th class=$oddcheck>$var</th>"; if ((! defined(${$param_vars{$tbl}->{$var}})) || (${$param_vars{$tbl}->{$var}} eq '')) { $debugtables .= "<td class=$oddcheck>&nbsp;</td></tr>\n"; } else { $debugtables .= "<td class=$oddcheck>${$param_vars{$tbl}->{$var}}</td></tr>\n"; } $varcount++; } } $debugtables .= "</table>"; $debugtables .="<br>\n"; } } # #################### End of nagios_send_host_mail.pl #################### Eu tenho script acima para enviar e-mails personalizados em HTML com alertas do Nagios referentes a hosts. Esse script funciona normalmente. Envia um email para cada contato do nagios. Porém o script abaixo - com a mesma funcionalidade porém para enviar emails de alertas de serviços do Nagios - não funciona como deveria. Ele enviar mais de um email - dependendo da quantidade de contatos - Ex: Preciso enviar o alerta do nagios para 4 emails, então ele envia o alerta para cada um dos contatos 4 vezes, outro problema é que ele ao invês de pegar o endereço de email de cada contato, ele pega o nome do contato e adiciona o sufixo @domain.com, ou seja, um usuário que o contato no nagios é joaojunior porém o email é joao@domain.com, o script acaba enviando email para joaojunior@domain.com. O script com problema está abaixo. #!/usr/bin/perl -w # # First we explicitly switch off the Nagios embbeded Perl Interpreter # nagios: -epn # ######################### pnp4n_send_service_mail.pl ################ # # Date : Mar 18 2012 # # Purpose : Script to send out Nagios service e-mails.\n"; # # Author : Frank Migge (support at frank4dd dot com), Robert Becht # # Help : http://nagios.frank4dd.com/howto # # Licence : GPL - http://www.fsf.org/licenses/gpl.txt # # Written for and verified with Nagios version 3.2.3 # # Help : ./pnp4n_send_service_mail.pl -h # # # # Version : 1.0 initial release # # Version : 1.1 add multipart MIME and logo # # Version : 1.2 cleanup mail body generation code # # Version : 1.3 use environment variables for Nagios data handoff # # Version : 1.4 add the performance graph image if available # # this has been implemented for Nagiosgraph v0.9.1 # # Version : 1.5 add -g for using $CONTACTGROUPMEMBERS$ macro # # multi-language support for en|de|fr|jp, extendable # # enhanced debug, version by Robert Becht # # the script now reads logo's from file # # # # Depends : perl-Mail-Sendmail # # perl-MIME-tools # # rrdtool-devel # # libnetpbm (if image conversion from PNG to JPG is required) # # netpbm (if image conversion from PNG to JPG is required) # # ##################################################################### # use Getopt::Long; use Mail::Sendmail; use Digest::MD5 qw(md5_hex); use MIME::Base64; use RRDs; use File::Temp; use strict; use warnings; use vars qw( $o_verb $o_version $o_help $o_to_group $o_cc_recipients $o_bcc_recipients $o_addurl $inputfile $ftemp $logo_id $graph_id $rrdfile $tmpfile $land $debugtables $tbl $var %param_vars $hs $G $elapse $tstamp $tstart $img_get $ds ); # The version of this script my $Version ='1.6'; my $authors = 'Frank Migge, Robert Becht'; # the sender e-mail address to be seen by recipients my $mail_sender = "Nagios Monitoring <nagiosadmin\@yourdomain>"; # The nagios CGI URL my $nagios_cgiurl = "http://192.168.1.1/nagios/cgi-bin"; # Modified by Robert Becht that to use PNP4Nagios links # The PNP4Nagios URL : il not use, simply make to equal 'undef'. my $nagios_pnpurl = "http://192.168.1.1/pnp4nagios"; my ($ra, $rb, $rc, $pnp_uri) = split('/',$nagios_pnpurl); # Otherwise you can set $pnp_uri manualy # Here we define a simple HTML stylesheet to be used in the HTML header. my $html_style = "body {text-align: center; font-family: Verdana, sans-serif; font-size: 10pt;}\n" . "img.logo {float: left; margin: 10px 10px 10px; vertical-align: middle}\n" . "span {font-family: Verdana, sans-serif; font-size: 12pt;}\n" . "table {text-align:center; margin-left: auto; margin-right: auto;}\n" . "th {white-space: nowrap;}\n" . "th.even {background-color: #D9D9D9;}\n" . "td.even {background-color: #F2F2F2;}\n" . "th.odd {background-color: #F2F2F2;}\n" . "td.odd {background-color: #FFFFFF;}\n" . "th,td {font-family: Verdana, sans-serif; font-size: 10pt; text-align:left;}\n" . "th.customer {width: 600px; background-color: #004488; color: #ffffff;}"; my $table_size = "600px"; my $header_size = "180px"; my $data_size = "420px"; my $debugtables = "</br>\n"; # ######################################################################## # SMTP related data: If the commandline argument -H/--smtphost was not # given, we use the provided value in $o_smtphost below as the default. # ######################################################################## my $o_smtphost = "192.168.1.64"; my $domain = "\@yourdomain"; my @listaddress = (); # ######################################################################## # This is the logo image file, the path must point to a valid JPG, GIF or # PNG file, i.e. the nagios logo. Best size is rectangular up to 160x80px. # example: [nagioshome]/share/images/NagiosEnterprises-whitebg-112x46.png # ######################################################################## my $logofile = "/usr/lib64/nagios/local/logo_devsys.png"; # ######################################################################## # Here I define the HTML color values for each Nagios notification type. # There is one extra called TEST for sending a test e-mail from the cmdline # outside of Nagios. The color values are used for highlighting the # background of the notification type cell. # ######################################################################## my %NOTIFICATIONCOLOR=('PROBLEM'=>'#FF8080','RECOVERY'=>'#80FF80','ACKNOWLEDGEMENT'=>'FFFF80', 'DOWNTIMESTART'=>'80FFFF','DOWNTIMEEND'=>'80FF80','DOWNTIMECANCELLED'=>'FFFF80', 'FLAPPINGSTART'=>'#FF8080','FLAPPINGSTOP'=>'#80FF80',' FLAPPINGDISABLED'=>'FFFF80', 'TEST'=>'80FFFF'); # ######################################################################## # Here we set the information where to pick up the RRD data files for the # optional graph image generation, plus the graph size width x height px # ######################################################################## my $rrd_basedir = "/var/nagios/perfdata"; my $graph_img_size = "521x60"; my $graph_bgcolor = "#F2F2F2"; my $graph_border = "#999999"; # ######################################################################## # language translated message text: $language{$land}{'A'} (=Customer) # You can simply add here your translation... # ######################################################################## my %language = ('en' => { 'A' => 'Customer', 'B' => 'Notification Type', 'C' => 'Service Name', 'D' => 'Service Status', 'E' => 'Service Group', 'F' => 'Service Data', 'G' => 'Hostname', 'H' => 'Hostalias', 'I' => 'IP Address', 'J' => 'Hostgroup', 'K' => 'Event Time', 'L' => 'Author', 'M' => 'Comment', 'N' => 'Nagios Monitoring System Notification', 'O' => 'Generated by Nagios, the OpenSource monitoring solution' }, 'fr' => { 'A' => 'Utilisateur', 'B' => 'Type de notification', 'C' => 'Nom du service', 'D' => 'Statut du service', 'E' => 'Groupe du service', 'F' => 'Données', 'G' => 'Nom d\'hôte', 'H' => 'Alias d\'hôte', 'I' => 'Adresse IP', 'J' => 'Groupe d\'hôte', 'K' => 'Heure de la notification', 'L' => 'Auteur', 'M' => 'Commentaire', 'N' => 'Notification de la surveillance Nagios', 'O' => 'Généré par Nagios, le système de surveillance OpenSource' }, 'de' => { 'A' => 'Anwender', 'B' => 'Nachrichtentyp', 'C' => 'Dienstname', 'D' => 'Dienstzustand', 'E' => 'Dienstgruppe', 'F' => 'Dienstinformationen', 'G' => 'Systemname', 'H' => 'Systemalias', 'I' => 'System IP Adresse', 'J' => 'Systemgruppe', 'K' => 'Meldungsdatum', 'L' => 'Author', 'M' => 'Kommentar', 'N' => 'Nagios Überwachungssytem Meldung', 'O' => 'Erstellt mit Nagios, dem OpenSource Überwachungssytem' }, 'jp' => { 'A' => '顧客名', 'B' => '通知の種類', 'C' => 'サービス名', 'D' => 'サービスの状態', 'E' => 'サービスグループ', 'F' => 'サービスデータ出力', 'G' => 'ホスト名', 'H' => 'ホストの別名', 'I' => 'IPアドレス', 'J' => 'ホストグループ', 'K' => 'イベントの日付と時刻', 'L' => '投稿者', 'M' => 'コメント', 'N' => 'Nagios 監視システムの通知', 'O' => 'このメーセジはオープンソースの監視システムNagiosで生成されています。' }); ####### Global Variables - No changes necessary below this line ########## # Nagios notification type, i.e. PROBLEM my $o_notificationtype = $ENV{NAGIOS_NOTIFICATIONTYPE}; # Nagios notification author (if avail.) my $o_notificationauth = $ENV{NAGIOS_NOTIFICATIONAUTHOR}; # Nagios notification comment (if avail.) my $o_notificationcmt = $ENV{NAGIOS_NOTIFICATIONCOMMENT}; # Nagios service description my $o_servicedesc = $ENV{NAGIOS_SERVICEDESC}; # Nagios service state my $o_servicestate = $ENV{NAGIOS_SERVICESTATE}; # Nagios service group the service belongs to my $o_servicegroup = $ENV{NAGIOS_SERVICEGROUPNAME}; # Nagios monitored host name my $o_hostname = $ENV{NAGIOS_HOSTNAME}; # Nagios monitored host alias my $o_hostalias = $ENV{NAGIOS_HOSTALIAS}; # Nagios host group the host belongs to my $o_hostgroup = $ENV{NAGIOS_HOSTGROUPNAME}; # Nagios monitored host IP address my $o_hostaddress = $ENV{NAGIOS_HOSTADDRESS}; # Nagios service check output data my $o_serviceoutput = $ENV{NAGIOS_SERVICEOUTPUT}; # Nagios date when the event was recorded my $o_datetime = $ENV{NAGIOS_LONGDATETIME}; # The recipients defined in $CONTACTEMAIL$ my $o_to_recipients = $ENV{NAGIOS_CONTACTEMAIL}; # Modified by Robert Becht for using $CONTACTGROUPEMEMBERS$ in nagios.conf my $o_to_group = $ENV{NAGIOS_CONTACTGROUPMEMBERS}; # The next variables are provided through args my $o_cc_recipients = undef; # The recipients defined in $CONTACTADDRESS1$ my $o_bcc_recipients = undef; # The recipients defined in $CONTACTADDRESS2$ my $o_format = "text";# The e-mail output format (default: text) my $o_addurl = undef; # flag to add Nagios GUI URLs to HTML e-mails my $o_language = undef; # The e-mail output language my $o_lang_def = "en"; # The e-mail output language default my $o_customer = undef; # Company name and contract number for service providers my $o_help = undef; # We want help my $o_verb = undef; # verbose mode my $o_version = undef; # print version my $o_test = undef; # generate a test message # These variables are used in various subroutines my $text_msg = undef; # the plaintext notification my $html_msg = undef; # the HTML-formatted notification my $graphfile = undef; # if we generate graphs, the tmp file location my @rrd; my $logo_img = undef; # base64-encoded logo my $graph_img = undef; # base64-encoded graph my $boundary = undef; # unique string for multi-part emails my %mail; # ######################################################################## # subroutine defintions below # ######################################################################## # ######################################################################## # p_version returns the program version # ######################################################################## sub p_version { print "$0 nagios_send_service_mail.pl version : $Version\n"; } # ######################################################################## # print_usage returns the program usage # ######################################################################## sub print_usage { print "Usage: $0 [-v] [-V] [-h] [-t] [-H <SMTP host>] [-p <customername>] [-r <to_recipients> or -g <to_group>] [-c <cc_recipients>] [-b <bcc_recipients>] [-f <text|html|multi|graph>] [-u] [-l <en|jp|fr|de|(or other languages if added)]\n"; } # ######################################################################## # help returns the program help message # ######################################################################## sub help { print "\nNagios e-mail notification script for service events, version ",$Version,"\n"; print "GPL licence, (c)2010 Frank Migge\n\n"; print_usage(); print <<EOT; This script takes over the Nagios e-mail notifications by receiving the Nagios state information, formatting the e-mail and sending it out through an SMTP gateway. -v, --verbose print extra debugging information -V, --version prints version number -h, --help print this help message -t, --test generates a test message together with -r, --to-recipients -H, --smtphost=HOST name or IP address of SMTP gateway -p, --customer="customer name and contract #" optionally, add the customer name and contract for service providers -r, --to-recipients this option overrides the Nagios-provided \$CONTACTEMAIL\$ list of to: recipients -g, --to-group-recipients \$CONTACTGROUPMEMBERS\$ this option use the list of contactgroup and reconstitutes the mail address with the hard defined \$domain in this script. This is only possible when the contact name "abcd" works under the address "abcd\@domain". -c, --cc-recipients the Nagios-provided \$CONTACTADDRESS1\$ list of cc: recipients -b, --bcc-recipients the Nagios-provided \$CONTACTADDRESS2\$ list of bcc: recipients -f, --format='text|html|multi|graph' the email format to generate: either plain text,, HTML, multipart S/MIME and multipart adding the Nagiosgraph image -u, --addurl this adds URL's to the Nagios web GUI for check status, host and hostgroup views into the html mail, requires -f html or -f multi -l, --language='en|jp|fr|de|(or what you defined in this script)' the prefered e-mail language. The content-type header is currently is hard-coded to UTF-8. This might need to be changed if recipients require a different characterset encoding. Extra: For useful debug output, go to Nagios, select a service and choose "Send custom service notification". Entering text including the word "email-debug" in the comment field will trigger the creation of additional tables with a list of Nagios and script variables. EOT } # ######################################################################## # verb creates verbose output # ######################################################################## sub verb { my $t=shift; print $t,"\n" if defined($o_verb); } # ######################################################################## # unique content ID are needed for multipart messages with inline logos # ######################################################################## sub create_content_id { my $unique_string = rand(100); $unique_string = $unique_string . substr(md5_hex(time()),0,23); $unique_string =~ s/(.{5})/$1\./g; my $content_id = qq(part.${unique_string}\@) . "MAIL"; $unique_string = undef; return $content_id; } # ######################################################################## # create_boundary creates the S/MIME multipart boundary strings # ######################################################################## sub create_boundary { my $unique_string = substr(md5_hex(time()),0,24); $boundary = '======' . $unique_string ; $unique_string = undef; } sub unknown_arg { print_usage(); exit -1; } # ######################################################################## # create_address from the groupmembers list (Add by Robert Becht) # ######################################################################## sub create_address { chomp($o_to_group); my @mlist = split(",",$o_to_group); foreach (@mlist) { my $maddress = "$_"."$domain"; # Debugging #print "$maddress\n"; push(@listaddress,$maddress); } $o_to_group = join(",",@listaddress); #Debugging #print "$o_to_group\n"; return ($o_to_group); } # ######################################################################## # check_options checks and processes the commandline options given # ######################################################################## sub check_options { Getopt::Long::Configure ("bundling"); GetOptions( 'v' => \$o_verb, 'verbose' => \$o_verb, 'V' => \$o_version, 'version' => \$o_version, 'h' => \$o_help, 'help' => \$o_help, 't' => \$o_test, 'test' => \$o_test, 'H:s' => \$o_smtphost, 'smtphost:s' => \$o_smtphost, 'p:s' => \$o_customer, 'customer:s' => \$o_customer, 'r:s' => \$o_to_recipients, 'to-recipients:s' => \$o_to_recipients, 'g:s' => \$o_to_group, 'to-group-recipients' => \$o_to_group, 'c:s' => \$o_cc_recipients, 'cc-recipients:s' => \$o_cc_recipients, 'b:i' => \$o_bcc_recipients, 'bcc-recipients:s' => \$o_bcc_recipients, 'f:s' => \$o_format, 'format:s' => \$o_format, 'u' => \$o_addurl, 'addurl' => \$o_addurl, 'l:s' => \$o_language, 'language:s' => \$o_language ) or unknown_arg(); # Basic checks if (defined ($o_help)) { help(); exit 0}; if (defined($o_version)) { p_version(); exit 0}; if ((! defined($o_to_recipients)) && (! defined($o_to_group))) { # no recipients provided print "Error: no recipients have been provided\n"; print_usage(); exit -1} else { if (! defined($o_to_group)) { %mail = ( To => $o_to_recipients, From => $mail_sender, Sender => $mail_sender ); } else { &create_address; %mail = ( To => $o_to_group, From => $mail_sender, Sender => $mail_sender ); } } if ( $o_format ne "text" && $o_format ne "html" && $o_format ne "multi" && $o_format ne "graph") # wrong mail format { print "Error: wrong e-mail format.\n"; print_usage(); exit -1} if (defined($o_addurl) && $o_format eq "text") { print "Error: cannot add URL's to text.\n"; print_usage(); exit -1} if (defined($o_test)) { create_test_data(); }; # Modified by Robert Becht to support additional languages # if no language has been requested, try to determine default from OS if (! defined($o_language)) { # if environment $LANG is set, try to extract the first two country chars, i.e. "en|de|fr" if ($ENV{LANG} eq "C" || $ENV{LANG} eq "POSIX") { $land = "en"; } else { ($land, my $rem) = split('_',$ENV{LANG}, 2); } } else { $land = $o_language; } # Last resort: Set "English" if the requested language is not supported by our script if (! $language{$land}{'A'}) { $land = $o_lang_def; } } # ######################################################################## # if -t or --test, we need to create sample test data to send out # In order to successfully test a e-mail with performance graph generation # set a valid hostname and servicedesc to be able to pick up a RRD file. # ######################################################################## sub create_test_data { if (! defined($o_customer)){ $o_customer = "ACME Corporation";} if (! defined($o_notificationtype)){ $o_notificationtype = "TEST";} if (! defined($o_servicestate)){ $o_servicestate = "UNKNOWN";} if (! defined($o_hostname)){ $o_hostname = "susie114";} if (! defined($o_hostalias)){ $o_hostalias = "susie114.frank4dd.com (LINUX)";} if (! defined($o_hostaddress)){ $o_hostaddress = "127.0.0.1";} if (! defined($o_hostgroup)){ $o_hostgroup = "Linux Servers";} if (! defined($o_servicedesc)){ $o_servicedesc = "os_cpu_load";} if (! defined($o_servicegroup)){ $o_servicegroup = "performance checks";} if (! defined($o_datetime)){ $o_datetime = `date`;} # if (! defined($o_datetime)) {$o_datetime = localtime time;} if (! defined($o_serviceoutput)){ $o_serviceoutput = "Test output for this service";} if (! defined($o_notificationauth)){ $o_notificationauth = "John Doe";} # Setting the keyword "email-debug" in the notification comment below triggers the creation of debug tables if (! defined($o_notificationcmt)){ $o_notificationcmt = "Test message for the service with email-debug";} } # ######################################################################## # Create a plaintext message -> $text_msg # ######################################################################## sub create_message_text { $text_msg = $language{$land}{'N'}."\n" . "=====================================\n\n"; # if customer name was given for service providers, display it here if ( defined($o_customer)) { $text_msg = $text_msg . $language{$land}{'A'} . ": $o_customer\n"; } $text_msg = $text_msg . $language{$land}{'B'} . ": $o_notificationtype\n" . $language{$land}{'C'} . ": $o_servicedesc\n" . $language{$land}{'D'} . ": $o_servicestate\n" . $language{$land}{'E'} . ": $o_servicegroup\n" . $language{$land}{'F'} . ": $o_serviceoutput\n\n" . $language{$land}{'G'} . ": $o_hostname\n" . $language{$land}{'H'} . ": $o_hostalias\n" . $language{$land}{'I'} . ": $o_hostaddress\n" . $language{$land}{'J'} . ": $o_hostgroup\n" . $language{$land}{'K'} . ": $o_datetime\n\n"; # if author and comment data has been passed from nagios # and these variables have content, then we add two more columns if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) && ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) { $text_msg = $text_msg . $language{$land}{'L'} . ": $o_notificationauth\n" . $language{$land}{'M'} . ": $o_notificationcmt\n\n"; } $text_msg = $text_msg . "-------------------------------------\n" . $language{$land}{'O'} . ".\n" . "(". $authors . ")\n" ; } # ######################################################################## # Create a simple HTML message -> $html_msg # ######################################################################## sub create_message_html { # Start HTML message definition $html_msg = "<html><head><style type=\"text/css\">$html_style</style></head><body>\n" . "<table width=$table_size><tr>\n"; if ($o_format eq "multi" || $o_format eq "graph") { $logo_id = create_content_id(); $html_msg = $html_msg . "<td><img class=\"logo\" src=\"cid:$logo_id\"></td>" . "<td><span>$language{$land}{'N'}</span></td></tr><tr>\n"; } else { $html_msg = $html_msg . "<th colspan=2><span>$language{$land}{'N'}</span></th></tr><tr>\n"; } if ( defined($o_customer)) { $html_msg = $html_msg . "<th colspan=2 class=customer>$o_customer</th></tr><tr>\n"; } $html_msg = $html_msg . "<th width=$header_size class=even>$language{$land}{'B'}:</th>\n" . "<td bgcolor=$NOTIFICATIONCOLOR{$o_notificationtype}>\n" . "$o_notificationtype</td></tr>\n" . "<tr><th class=odd>$language{$land}{'C'}:</th><td>$o_servicedesc</td></tr>\n" . "<tr><th class=even>$language{$land}{'E'}:</th><td class=even>\n"; # The Servicegroup URL http://<nagios-web>/cgi-bin/status.cgi?servicegroup=$SERVICEGROUPNAME$&style=overview # This URL shows the service group table listing ofthe hosts that have this service if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?servicegroup=$o_servicegroup&style=overview\">$o_servicegroup</a>"; } else { $html_msg = $html_msg . $o_servicegroup; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'D'}:</th><td>$o_servicestate</td></tr>\n" . "<tr><th class=even>$language{$land}{'F'}:</th><td class=even>\n"; # The ServiceOutput URL http://<nagios-web>/cgi-bin/extinfo.cgi?type=2&host=$HOSTNAME$&service=$SERVICEDESC$ # This URL shows the full service details and commands for service management (ack, re-check, disable, etc) if (defined($o_addurl)) { if ( $nagios_pnpurl eq '') { $html_msg .= "<a href=\"$nagios_cgiurl/extinfo.cgi?type=2&host=$o_hostname&service=$o_servicedesc\">$o_serviceoutput</a>\n"; } else { # Modified by Robert Becht for link to PNP4Nagios graph $html_msg .= "<a href=\"$nagios_pnpurl/index.php/graph?host=$o_hostname&srv=$o_servicedesc\">$o_serviceoutput</a>\n"; } } else{ $html_msg .= $o_serviceoutput; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'G'}:</th><td>\n"; # The Hostname URL http://<nagios-web>/cgi-bin/status.cgi?host=$HOSTNAME$&style=detail # this URL shows the host and all services underneath it if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?host=$o_hostname&style=detail\">$o_hostname</a>"; } else { $html_msg = $html_msg . $o_hostname; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=even>$language{$land}{'H'}:</th><td class=even>$o_hostalias</td></tr>\n" . "<tr><th class=odd>$language{$land}{'I'}:</th><td>$o_hostaddress</td></tr>\n" . "<tr><th class=even>$language{$land}{'J'}:</th><td class=even>\n"; # The Hostgroup URL http://<nagios-web>/cgi-bin/status.cgi?hostgroup=$HOSTGROUPNAME$&style=overview # This URL shows the hostgroup table listing for all individual hosts that belong to it if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?hostgroup=$o_hostgroup&style=overview\">$o_hostgroup</a>"; } else { $html_msg = $html_msg . $o_hostgroup; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'K'}:</th><td>$o_datetime</td></tr>\n"; # If the author and comment data has been passed from nagios # and these variables have content, then we add two more columns if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) && ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) { $html_msg = $html_msg . "<tr><th class=even>$language{$land}{'L'}:</th>\n" . "<td class=even>$o_notificationauth</td></tr>\n" . "<tr><th class=odd>$language{$land}{'M'}:</th>\n" . "<td>$o_notificationcmt</td></tr>\n"; } $html_msg = $html_msg . "</table></br>\n"; # if we got the graph format and a image has been generated, we add it here if (defined($graph_img) && $o_format eq "graph") { $graph_id = create_content_id(); $html_msg = $html_msg . "<img src=\"cid:$graph_id\">\n"; } # add the Nagios footer tag line here $html_msg = $html_msg . "</br><hr>\n$language{$land}{'O'}\n .</br><em><font size=\"-1\" >(Authors:$authors)</font></em><hr>\n"; # add the extra debugtables if verbose output had been requested, # or if the notification command contains the keyword "email-debug" if (defined($o_notificationcmt) && ($o_notificationcmt =~ m/email-debug/i) || defined($o_verb)) { &create_debugtable; $html_msg = $html_msg . $debugtables; } # End HTML message definition $html_msg = $html_msg . "</body></html>\n"; } # ####################################################################### # urlencode() URL encode a string # ####################################################################### sub urlencode { $_[0] =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; return $_[0]; } # ####################################################################### # hashcolor() Choose a color for service # ####################################################################### sub hashcolor { my $c=0; map{$c=(51*$c+ord)%(216)}split//,"$_[0]x"; my $i = 0; my $n = 0; my $m = 0; my @h=(51*int $c/36,51*int $c/6%6,51*($c%6)); for$i(0..2){$m=$i if$h[$i]<$h[$m];$n=$i if$h[$i]>$h[$n]} $h[$m]=102if$h[$m]>102;$h[$n]=153if$h[$n]<153; $c=sprintf"%06X",$h[2]+$h[1]*256+$h[0]*16**4; return $c; } # ####################################################################### # dbfilelist() Get list of matching rrd files # ####################################################################### sub dbfilelist { my($host,$service, $rrddir) = @_; my $hs; # New style, files inside a <hostname> directory $rrddir .= "/" . $host; $hs = urlencode "$service" . "___"; verb("sub dbfilelist: Checking files inside directory: ".$rrddir); my @rrd; opendir DH, $rrddir or verb("sub dbfilelist: Cannot open: ".$rrddir); @rrd = grep s/^${hs}(.+)\.rrd$/$1/, readdir DH; closedir DH; verb("sub dbfilelist: We found number of RRD files: ".@rrd); return @rrd; } # ####################################################################### # graphinfo() Find graphs and values # ####################################################################### sub graphinfo { my($host,$service,$rrddir) = @_; my(@rrd,$ds,$f,$dsout,@values,$hs,%H,%R); $hs = $host . "/"; $hs .= urlencode "$service" . "___"; # Determine which files to read lines from @rrd = map {{ file=>$_ }} map { "${hs}${_}.rrd" } dbfilelist($host,$service, $rrddir); # we stop processing here if we could not find a file if (@rrd < 1) { verb("sub graphinfo: Could not find any graph file."); return undef; } else { verb("sub graphinfo: Listing $hs db files in $rrddir: " . join ', ', map { $_->{file} } @rrd); } $rrdfile = $rrd[0]->{file}; $ds = RRDs::info "$rrddir/$rrdfile"; verb("sub graphinfo: RRDs::info ERR " . RRDs::error) if RRDs::error; map { $rrd[0]->{line}{$_} = 1} grep {!$H{$_}++} map { /ds\[(.*)\]/; $1 } grep /ds\[(.*)\]/, keys %$ds; verb("sub graphinfo: Found datasources: " . %$ds); return \@rrd; } # ####################################################################### # rrdline() Generate the rrd parameters to produce a graph # ####################################################################### sub rrdline { my($host,$service,$geom,$G,$rrddir,$tmpfile) = @_; my($g,$f,$v,$c,@ds); my $directory = $rrddir; @ds = ($tmpfile, '-a', 'PNG', '-t', $service); push @ds, "--color=BACK$graph_bgcolor", "--color=SHADEA$graph_border", "--color=SHADEB$graph_border"; # Identify where to pull data from and what to call it for $g ( @$G ) { $f = $g->{file}; verb("sub rrdline: set filename: $f"); # Compute the longest label length my $longest = (sort map(length,keys(%{ $g->{line} })))[-1]; for $v ( sort keys %{ $g->{line} } ) { $c = hashcolor($v); verb("sub rrdline: file=$f line=$v color=$c"); my $sv = "$v"; my $label = sprintf("%-${longest}s", $sv); push @ds , "DEF:$sv=$directory/$f:$v:AVERAGE" , "LINE2:${sv}#$c:$label"; my $format = '%6.2lf%s'; # Graph labels push @ds, "GPRINT:$sv:MAX:Max\\: $format" , "GPRINT:$sv:AVERAGE:Avg\\: $format" , "GPRINT:$sv:MIN:Min\\: $format" , "GPRINT:$sv:LAST:Cur\\: ${format}\\n"; } } # Dimensions of graph if geom is specified if ( $geom ) { my($w,$h) = split 'x', $geom; push @ds, '-w', $w, '-h', $h; } return @ds; } # ######################################################################## # uuencode_image(filename) converts a existing binary source image file # into a base64-image string. # ######################################################################## sub uuencode_img { my($inputfile) = @_; open (IMG, $inputfile) or verb("uuencode_img: Cannot read source image file: $inputfile - $!"); binmode IMG; undef $/; my $uuencoded_img = encode_base64(<IMG>); close IMG; verb("uuencode_img: completed conversion of source image file: $inputfile - $!"); return $uuencoded_img; } # ####################################################################### # create_graph_img() tries to create a performance graph image file (PNG) # Input is the hostname and servicename, then we try to find a matching # RRD file according to NagiosGraph's filesystem layout. If there is one, # it queries the RRD information and graphs the last 24 hours similar to # Nagiosgraph. # ####################################################################### sub create_graph_img { my $fhandle = undef; my $graph_img = undef; # Figure out db files and line labels my $G = graphinfo($o_hostname,$o_servicedesc,$rrd_basedir); # if we could not find RRD data, we return $img as undef if(! defined($G)) { verb("sub create_graph_img: No graph data for $o_hostname,$o_servicedesc was found."); return $graph_img; } # generate temporary graph files for todays RRD data $fhandle = File::Temp->new() or verb("create_graph_img: Cannot create temporary image file."); my $tmpfile = $fhandle->filename; $ftemp = $tmpfile; my @ds = rrdline($o_hostname,$o_servicedesc,$graph_img_size,$G,$rrd_basedir,$tmpfile); verb("sub create_graph_img: RRDs::graph ". join ' ', @ds); RRDs::graph(@ds); verb("sub create_graph_img: RRDs::graph ERR " . RRDs::error) if RRDs::error; # because our mail system being Lotus Notes, which is not supporting PNG # images, we must convert them from PNG to JPG before we can continue. # comment out the next 3 lines if PNG images work with your mail clients # my $jpg_tmpfile = $tmpfile.".jpg"; # `pngtopnm $tmpfile | pnmtojpeg >$jpg_tmpfile`; # `mv $jpg_tmpfile $tmpfile`; # In e-mails, images need to be base64 encoded, we uuencode here $graph_img = uuencode_img($tmpfile); return $graph_img; } # ######################################################################## # Added by Robert Becht for request an PNP4Nagios graph # ######################################################################## sub import_pnp_graph { use LWP::Simple; $elapse = (1 * 3600); # This set 1 hour history $tstamp = time(); $tstart = ($tstamp - $tstamp); $img_get = "http://127.0.0.1/$pnp_uri/image?host=$o_hostname&srv=$o_servicedesc&source=0&start=$tstart&end=$tstamp"; # generate temporary graph files for todays RRD data my $fhandle = File::Temp->new( UNLINK =>1, SUFFIX => '.png') or verb("create_graph_img: Cannot create temporary image file."); my $tmpfile = $fhandle->filename; $ftemp = $tmpfile; # write the graphik file in $tmpfile print $fhandle get("$img_get"); # This is for graph size my $pnmfile = `pngtopnm $tmpfile`; (my $xysize = $graph_img_size) =~ s/x/ /; `pamscale -xysize $xysize $pnmfile | pnmtopng >$img_get`; # or use pnmtojpeg if png not supported ... $graph_img = uuencode_img($tmpfile); return $graph_img; } # ######################################################################## # language translated email subject: $lang{$land} # ######################################################################## sub set_subject { my $subject; my %lang = ('en' => "Nagios: $o_notificationtype service $o_servicedesc on $o_hostname ($o_hostgroup) is $o_servicestate", 'de' => "Nagios: $o_notificationtype $o_hostname($o_hostgroup) mit Dienst $o_servicedesc ist $o_servicestate", 'jp' => "Nagios: $o_notificationtype $o_hostname($o_hostgroup)のサービス $o_servicedesc $o_servicestate", 'fr' => "Nagios: $o_notificationtype : le service $o_servicedesc sur $o_hostname ($o_hostgroup) est $o_servicestate" ); if (!defined($lang{$land})) { $subject = $lang{'en'}; } else { $subject = $lang{$land}; } return $subject; } # ####################################################################### # main # ####################################################################### check_options(); $mail{Cc} = $o_cc_recipients if ($o_cc_recipients); $mail{Bcc} = $o_bcc_recipients if ($o_bcc_recipients); $mail{smtp} = $o_smtphost; $mail{subject} = set_subject(); # If the mail server requires authentication, try this line: # $mail{auth} = {user => "<username>", password => "<mailpw>", method="">"LOGIN PLAIN", required=>1}; if ($o_format eq "graph") { if ( ! defined $pnp_uri) { verb("main: trying to create the a graph image."); $graph_img = create_graph_img(); } else { $graph_img = import_pnp_graph();} } if ($o_format eq "multi" || $o_format eq "graph") { verb("main: Sending HTML email (language: $land) with inline logo."); # In e-mails, images need to be base64 encoded, we uuencode here my $logo_img = uuencode_img($logofile); create_boundary(); create_message_html(); $mail{'content-type'} = qq(multipart/related; boundary="$boundary"); $boundary = '--' . $boundary; # Here we define the mail content to be send my $mail_content = "This is a multi-part message in MIME format.\n" # create the first boundary start marker for the main message . "$boundary\n" . "Content-Type: text/html; charset=utf-8\n" . "Content-Transfer-Encoding: 8bit\n\n" . "$html_msg\n"; # create the second boundary marker for the logo $mail_content = $mail_content . "$boundary\n" . "Content-Type: image/gif; name=\"logo.gif\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-ID: <$logo_id>\n" . "Content-Disposition: inline; filename=\"logo.gif\"\n\n" . "$logo_img\n"; # if we got the graph format and a image has been generated, we add it here # create the third boundary marker for the graph if (defined($graph_img) && $o_format eq "graph") { $mail_content = $mail_content . "\n" . "$boundary\n" . "Content-Type: image/jpg; name=\"graph.jpg\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-ID: <$graph_id>\n" . "Content-Disposition: inline; filename=\"graph.jpg\"\n\n" . "$graph_img\n"; } # create the final end boundary marker $mail_content = $mail_content . $boundary . "--\n"; # put the completed message body into the mail $mail{body} = $mail_content ; } elsif ($o_format eq "html") { create_message_html(); $mail{'content-type'} = qq(text/html; charset="utf-8"); $mail{body} = $html_msg ; } else { create_message_text(); $mail{'content-type'} = qq(text/plain; charset="utf-8"); $mail{body} = $text_msg ; } sendmail(%mail) or die $Mail::Sendmail::error; verb("Sendmail Log says:\n$Mail::Sendmail::log\n"); exit 0; # ####################################################################### # Create a debugging table to check on Nagios and script variables # Added by Robert Becht to create a HTML table for debugging # ####################################################################### sub create_debugtable() { my $varcount = 0; my $oddcheck = "odd"; # Check if the following variables are defined my %param_vars = ( 'script' => { "title" => 'Script debug data', "o_verb" => \$o_verb, "o_version" => \$o_version, "o_help" => \$o_help, "o_smtphost" => \$o_smtphost, "o_customer" => \$o_customer, "o_to_recipients" => \$o_to_recipients, "o_to_group" => \$o_to_group, "o_cc_recipients" => \$o_cc_recipients, "o_bcc_recipients" => \$o_bcc_recipients, "o_format" => \$o_format, "o_addurl" => \$o_addurl, "o_language" => \$o_language, "o_test" => \$o_test, "o_smtphost" => \$o_smtphost, "domain" => \$domain, "land" => \$land, "logo file" => \$logofile, "temporary file" => \$ftemp, "boundary" => \$boundary }, 'nagios' => { "title" => 'Nagios debug data', "o_notificationtype" => \$o_notificationtype, "o_notificationauth" => \$o_notificationauth, "o_notificationcmt" => \$o_notificationcmt, "o_servicedesc" => \$o_servicedesc, "o_servicestate" => \$o_servicestate, "o_servicegroup" => \$o_servicegroup, "o_hostname" => \$o_hostname, "o_hostalias" => \$o_hostalias, "o_hostgroup" => \$o_hostgroup, "o_hostaddress" => \$o_hostaddress, "o_serviceoutput" => \$o_serviceoutput, "o_datetime" => \$o_datetime, "o_to_recipients" => \$o_to_recipients, "o_to_group" => \$o_to_group }, 'rrdbase' => { "title" => 'RRD debug data', "rrd_basedir" => \$rrd_basedir, "rrdfile" => \$rrdfile, "hs" => \$hs, "rrdfile" => \$rrdfile, "DS" => \$ds, "labels" => \$G }, 'pnp' => { "title" => 'PNP debug data', "PNP url" => \$nagios_pnpurl, "PNP uri" => \$pnp_uri, "img_get" => \$img_get, "interval(s)" => \$elapse, "time start" => \$tstamp } ); # display the script variables # Tables loop foreach $tbl (keys %param_vars) { $debugtables .= "</br>\n" . "<table width=$table_size>\n" . "<tr><th colspan=2 class=customer>$param_vars{$tbl}->{'title'}</th></tr>\n"; $varcount = 0; # Data loop foreach $var (keys %{$param_vars{$tbl}}) { if ($var ne 'title') { if ($varcount%2) {$oddcheck = "odd"; } else {$oddcheck = "even";} $debugtables .= "<tr><th class=$oddcheck>$var</th>"; if ((! defined(${$param_vars{$tbl}->{$var}})) || (${$param_vars{$tbl}->{$var}} eq '')) { $debugtables .= "<td class=$oddcheck>&nbsp;</td></tr>\n"; } else { $debugtables .= "<td class=$oddcheck>${$param_vars{$tbl}->{$var}}</td></tr>\n"; # # Debugging # print $var . "= " . ${$param_vars{$tbl}->{$var}} . "\n"; } $varcount++; } } $debugtables .= "</table>"; $debugtables .="</br>\n"; } } #!/usr/bin/perl -w # # First we explicitly switch off the Nagios embbeded Perl Interpreter # nagios: -epn # ######################### pnp4n_send_service_mail.pl ################ # # Date : Mar 18 2012 # # Purpose : Script to send out Nagios service e-mails.\n"; # # Author : Frank Migge (support at frank4dd dot com), Robert Becht # # Help : http://nagios.frank4dd.com/howto # # Licence : GPL - http://www.fsf.org/licenses/gpl.txt # # Written for and verified with Nagios version 3.2.3 # # Help : ./pnp4n_send_service_mail.pl -h # # # # Version : 1.0 initial release # # Version : 1.1 add multipart MIME and logo # # Version : 1.2 cleanup mail body generation code # # Version : 1.3 use environment variables for Nagios data handoff # # Version : 1.4 add the performance graph image if available # # this has been implemented for Nagiosgraph v0.9.1 # # Version : 1.5 add -g for using $CONTACTGROUPMEMBERS$ macro # # multi-language support for en|de|fr|jp, extendable # # enhanced debug, version by Robert Becht # # the script now reads logo's from file # # # # Depends : perl-Mail-Sendmail # # perl-MIME-tools # # rrdtool-devel # # libnetpbm (if image conversion from PNG to JPG is required) # # netpbm (if image conversion from PNG to JPG is required) # # ##################################################################### # use Getopt::Long; use Mail::Sendmail; use Digest::MD5 qw(md5_hex); use MIME::Base64; use RRDs; use File::Temp; use strict; use warnings; use vars qw( $o_verb $o_version $o_help $o_to_group $o_cc_recipients $o_bcc_recipients $o_addurl $inputfile $ftemp $logo_id $graph_id $rrdfile $tmpfile $land $debugtables $tbl $var %param_vars $hs $G $elapse $tstamp $tstart $img_get $ds ); # The version of this script my $Version ='1.6'; my $authors = 'Frank Migge, Robert Becht'; # the sender e-mail address to be seen by recipients my $mail_sender = "Nagios Monitoring <nagiosadmin\@yourdomain>"; # The nagios CGI URL my $nagios_cgiurl = "http://192.168.1.1/nagios/cgi-bin"; # Modified by Robert Becht that to use PNP4Nagios links # The PNP4Nagios URL : il not use, simply make to equal 'undef'. my $nagios_pnpurl = "http://192.168.1.1/pnp4nagios"; my ($ra, $rb, $rc, $pnp_uri) = split('/',$nagios_pnpurl); # Otherwise you can set $pnp_uri manualy # Here we define a simple HTML stylesheet to be used in the HTML header. my $html_style = "body {text-align: center; font-family: Verdana, sans-serif; font-size: 10pt;}\n" . "img.logo {float: left; margin: 10px 10px 10px; vertical-align: middle}\n" . "span {font-family: Verdana, sans-serif; font-size: 12pt;}\n" . "table {text-align:center; margin-left: auto; margin-right: auto;}\n" . "th {white-space: nowrap;}\n" . "th.even {background-color: #D9D9D9;}\n" . "td.even {background-color: #F2F2F2;}\n" . "th.odd {background-color: #F2F2F2;}\n" . "td.odd {background-color: #FFFFFF;}\n" . "th,td {font-family: Verdana, sans-serif; font-size: 10pt; text-align:left;}\n" . "th.customer {width: 600px; background-color: #004488; color: #ffffff;}"; my $table_size = "600px"; my $header_size = "180px"; my $data_size = "420px"; my $debugtables = "</br>\n"; # ######################################################################## # SMTP related data: If the commandline argument -H/--smtphost was not # given, we use the provided value in $o_smtphost below as the default. # ######################################################################## my $o_smtphost = "192.168.1.64"; my $domain = "\@yourdomain"; my @listaddress = (); # ######################################################################## # This is the logo image file, the path must point to a valid JPG, GIF or # PNG file, i.e. the nagios logo. Best size is rectangular up to 160x80px. # example: [nagioshome]/share/images/NagiosEnterprises-whitebg-112x46.png # ######################################################################## my $logofile = "/usr/lib64/nagios/local/logo_devsys.png"; # ######################################################################## # Here I define the HTML color values for each Nagios notification type. # There is one extra called TEST for sending a test e-mail from the cmdline # outside of Nagios. The color values are used for highlighting the # background of the notification type cell. # ######################################################################## my %NOTIFICATIONCOLOR=('PROBLEM'=>'#FF8080','RECOVERY'=>'#80FF80','ACKNOWLEDGEMENT'=>'FFFF80', 'DOWNTIMESTART'=>'80FFFF','DOWNTIMEEND'=>'80FF80','DOWNTIMECANCELLED'=>'FFFF80', 'FLAPPINGSTART'=>'#FF8080','FLAPPINGSTOP'=>'#80FF80',' FLAPPINGDISABLED'=>'FFFF80', 'TEST'=>'80FFFF'); # ######################################################################## # Here we set the information where to pick up the RRD data files for the # optional graph image generation, plus the graph size width x height px # ######################################################################## my $rrd_basedir = "/var/nagios/perfdata"; my $graph_img_size = "521x60"; my $graph_bgcolor = "#F2F2F2"; my $graph_border = "#999999"; # ######################################################################## # language translated message text: $language{$land}{'A'} (=Customer) # You can simply add here your translation... # ######################################################################## my %language = ('en' => { 'A' => 'Customer', 'B' => 'Notification Type', 'C' => 'Service Name', 'D' => 'Service Status', 'E' => 'Service Group', 'F' => 'Service Data', 'G' => 'Hostname', 'H' => 'Hostalias', 'I' => 'IP Address', 'J' => 'Hostgroup', 'K' => 'Event Time', 'L' => 'Author', 'M' => 'Comment', 'N' => 'Nagios Monitoring System Notification', 'O' => 'Generated by Nagios, the OpenSource monitoring solution' }, 'fr' => { 'A' => 'Utilisateur', 'B' => 'Type de notification', 'C' => 'Nom du service', 'D' => 'Statut du service', 'E' => 'Groupe du service', 'F' => 'Données', 'G' => 'Nom d\'hôte', 'H' => 'Alias d\'hôte', 'I' => 'Adresse IP', 'J' => 'Groupe d\'hôte', 'K' => 'Heure de la notification', 'L' => 'Auteur', 'M' => 'Commentaire', 'N' => 'Notification de la surveillance Nagios', 'O' => 'Généré par Nagios, le système de surveillance OpenSource' }, 'de' => { 'A' => 'Anwender', 'B' => 'Nachrichtentyp', 'C' => 'Dienstname', 'D' => 'Dienstzustand', 'E' => 'Dienstgruppe', 'F' => 'Dienstinformationen', 'G' => 'Systemname', 'H' => 'Systemalias', 'I' => 'System IP Adresse', 'J' => 'Systemgruppe', 'K' => 'Meldungsdatum', 'L' => 'Author', 'M' => 'Kommentar', 'N' => 'Nagios Überwachungssytem Meldung', 'O' => 'Erstellt mit Nagios, dem OpenSource Überwachungssytem' }, 'jp' => { 'A' => '顧客名', 'B' => '通知の種類', 'C' => 'サービス名', 'D' => 'サービスの状態', 'E' => 'サービスグループ', 'F' => 'サービスデータ出力', 'G' => 'ホスト名', 'H' => 'ホストの別名', 'I' => 'IPアドレス', 'J' => 'ホストグループ', 'K' => 'イベントの日付と時刻', 'L' => '投稿者', 'M' => 'コメント', 'N' => 'Nagios 監視システムの通知', 'O' => 'このメーセジはオープンソースの監視システムNagiosで生成されています。' }); ####### Global Variables - No changes necessary below this line ########## # Nagios notification type, i.e. PROBLEM my $o_notificationtype = $ENV{NAGIOS_NOTIFICATIONTYPE}; # Nagios notification author (if avail.) my $o_notificationauth = $ENV{NAGIOS_NOTIFICATIONAUTHOR}; # Nagios notification comment (if avail.) my $o_notificationcmt = $ENV{NAGIOS_NOTIFICATIONCOMMENT}; # Nagios service description my $o_servicedesc = $ENV{NAGIOS_SERVICEDESC}; # Nagios service state my $o_servicestate = $ENV{NAGIOS_SERVICESTATE}; # Nagios service group the service belongs to my $o_servicegroup = $ENV{NAGIOS_SERVICEGROUPNAME}; # Nagios monitored host name my $o_hostname = $ENV{NAGIOS_HOSTNAME}; # Nagios monitored host alias my $o_hostalias = $ENV{NAGIOS_HOSTALIAS}; # Nagios host group the host belongs to my $o_hostgroup = $ENV{NAGIOS_HOSTGROUPNAME}; # Nagios monitored host IP address my $o_hostaddress = $ENV{NAGIOS_HOSTADDRESS}; # Nagios service check output data my $o_serviceoutput = $ENV{NAGIOS_SERVICEOUTPUT}; # Nagios date when the event was recorded my $o_datetime = $ENV{NAGIOS_LONGDATETIME}; # The recipients defined in $CONTACTEMAIL$ my $o_to_recipients = $ENV{NAGIOS_CONTACTEMAIL}; # Modified by Robert Becht for using $CONTACTGROUPEMEMBERS$ in nagios.conf my $o_to_group = $ENV{NAGIOS_CONTACTGROUPMEMBERS}; # The next variables are provided through args my $o_cc_recipients = undef; # The recipients defined in $CONTACTADDRESS1$ my $o_bcc_recipients = undef; # The recipients defined in $CONTACTADDRESS2$ my $o_format = "text";# The e-mail output format (default: text) my $o_addurl = undef; # flag to add Nagios GUI URLs to HTML e-mails my $o_language = undef; # The e-mail output language my $o_lang_def = "en"; # The e-mail output language default my $o_customer = undef; # Company name and contract number for service providers my $o_help = undef; # We want help my $o_verb = undef; # verbose mode my $o_version = undef; # print version my $o_test = undef; # generate a test message # These variables are used in various subroutines my $text_msg = undef; # the plaintext notification my $html_msg = undef; # the HTML-formatted notification my $graphfile = undef; # if we generate graphs, the tmp file location my @rrd; my $logo_img = undef; # base64-encoded logo my $graph_img = undef; # base64-encoded graph my $boundary = undef; # unique string for multi-part emails my %mail; # ######################################################################## # subroutine defintions below # ######################################################################## # ######################################################################## # p_version returns the program version # ######################################################################## sub p_version { print "$0 nagios_send_service_mail.pl version : $Version\n"; } # ######################################################################## # print_usage returns the program usage # ######################################################################## sub print_usage { print "Usage: $0 [-v] [-V] [-h] [-t] [-H <SMTP host>] [-p <customername>] [-r <to_recipients> or -g <to_group>] [-c <cc_recipients>] [-b <bcc_recipients>] [-f <text|html|multi|graph>] [-u] [-l <en|jp|fr|de|(or other languages if added)]\n"; } # ######################################################################## # help returns the program help message # ######################################################################## sub help { print "\nNagios e-mail notification script for service events, version ",$Version,"\n"; print "GPL licence, (c)2010 Frank Migge\n\n"; print_usage(); print <<EOT; This script takes over the Nagios e-mail notifications by receiving the Nagios state information, formatting the e-mail and sending it out through an SMTP gateway. -v, --verbose print extra debugging information -V, --version prints version number -h, --help print this help message -t, --test generates a test message together with -r, --to-recipients -H, --smtphost=HOST name or IP address of SMTP gateway -p, --customer="customer name and contract #" optionally, add the customer name and contract for service providers -r, --to-recipients this option overrides the Nagios-provided \$CONTACTEMAIL\$ list of to: recipients -g, --to-group-recipients \$CONTACTGROUPMEMBERS\$ this option use the list of contactgroup and reconstitutes the mail address with the hard defined \$domain in this script. This is only possible when the contact name "abcd" works under the address "abcd\@domain". -c, --cc-recipients the Nagios-provided \$CONTACTADDRESS1\$ list of cc: recipients -b, --bcc-recipients the Nagios-provided \$CONTACTADDRESS2\$ list of bcc: recipients -f, --format='text|html|multi|graph' the email format to generate: either plain text,, HTML, multipart S/MIME and multipart adding the Nagiosgraph image -u, --addurl this adds URL's to the Nagios web GUI for check status, host and hostgroup views into the html mail, requires -f html or -f multi -l, --language='en|jp|fr|de|(or what you defined in this script)' the prefered e-mail language. The content-type header is currently is hard-coded to UTF-8. This might need to be changed if recipients require a different characterset encoding. Extra: For useful debug output, go to Nagios, select a service and choose "Send custom service notification". Entering text including the word "email-debug" in the comment field will trigger the creation of additional tables with a list of Nagios and script variables. EOT } # ######################################################################## # verb creates verbose output # ######################################################################## sub verb { my $t=shift; print $t,"\n" if defined($o_verb); } # ######################################################################## # unique content ID are needed for multipart messages with inline logos # ######################################################################## sub create_content_id { my $unique_string = rand(100); $unique_string = $unique_string . substr(md5_hex(time()),0,23); $unique_string =~ s/(.{5})/$1\./g; my $content_id = qq(part.${unique_string}\@) . "MAIL"; $unique_string = undef; return $content_id; } # ######################################################################## # create_boundary creates the S/MIME multipart boundary strings # ######################################################################## sub create_boundary { my $unique_string = substr(md5_hex(time()),0,24); $boundary = '======' . $unique_string ; $unique_string = undef; } sub unknown_arg { print_usage(); exit -1; } # ######################################################################## # create_address from the groupmembers list (Add by Robert Becht) # ######################################################################## sub create_address { chomp($o_to_group); my @mlist = split(",",$o_to_group); foreach (@mlist) { my $maddress = "$_"."$domain"; # Debugging #print "$maddress\n"; push(@listaddress,$maddress); } $o_to_group = join(",",@listaddress); #Debugging #print "$o_to_group\n"; return ($o_to_group); } # ######################################################################## # check_options checks and processes the commandline options given # ######################################################################## sub check_options { Getopt::Long::Configure ("bundling"); GetOptions( 'v' => \$o_verb, 'verbose' => \$o_verb, 'V' => \$o_version, 'version' => \$o_version, 'h' => \$o_help, 'help' => \$o_help, 't' => \$o_test, 'test' => \$o_test, 'H:s' => \$o_smtphost, 'smtphost:s' => \$o_smtphost, 'p:s' => \$o_customer, 'customer:s' => \$o_customer, 'r:s' => \$o_to_recipients, 'to-recipients:s' => \$o_to_recipients, 'g:s' => \$o_to_group, 'to-group-recipients' => \$o_to_group, 'c:s' => \$o_cc_recipients, 'cc-recipients:s' => \$o_cc_recipients, 'b:i' => \$o_bcc_recipients, 'bcc-recipients:s' => \$o_bcc_recipients, 'f:s' => \$o_format, 'format:s' => \$o_format, 'u' => \$o_addurl, 'addurl' => \$o_addurl, 'l:s' => \$o_language, 'language:s' => \$o_language ) or unknown_arg(); # Basic checks if (defined ($o_help)) { help(); exit 0}; if (defined($o_version)) { p_version(); exit 0}; if ((! defined($o_to_recipients)) && (! defined($o_to_group))) { # no recipients provided print "Error: no recipients have been provided\n"; print_usage(); exit -1} else { if (! defined($o_to_group)) { %mail = ( To => $o_to_recipients, From => $mail_sender, Sender => $mail_sender ); } else { &create_address; %mail = ( To => $o_to_group, From => $mail_sender, Sender => $mail_sender ); } } if ( $o_format ne "text" && $o_format ne "html" && $o_format ne "multi" && $o_format ne "graph") # wrong mail format { print "Error: wrong e-mail format.\n"; print_usage(); exit -1} if (defined($o_addurl) && $o_format eq "text") { print "Error: cannot add URL's to text.\n"; print_usage(); exit -1} if (defined($o_test)) { create_test_data(); }; # Modified by Robert Becht to support additional languages # if no language has been requested, try to determine default from OS if (! defined($o_language)) { # if environment $LANG is set, try to extract the first two country chars, i.e. "en|de|fr" if ($ENV{LANG} eq "C" || $ENV{LANG} eq "POSIX") { $land = "en"; } else { ($land, my $rem) = split('_',$ENV{LANG}, 2); } } else { $land = $o_language; } # Last resort: Set "English" if the requested language is not supported by our script if (! $language{$land}{'A'}) { $land = $o_lang_def; } } # ######################################################################## # if -t or --test, we need to create sample test data to send out # In order to successfully test a e-mail with performance graph generation # set a valid hostname and servicedesc to be able to pick up a RRD file. # ######################################################################## sub create_test_data { if (! defined($o_customer)){ $o_customer = "ACME Corporation";} if (! defined($o_notificationtype)){ $o_notificationtype = "TEST";} if (! defined($o_servicestate)){ $o_servicestate = "UNKNOWN";} if (! defined($o_hostname)){ $o_hostname = "susie114";} if (! defined($o_hostalias)){ $o_hostalias = "susie114.frank4dd.com (LINUX)";} if (! defined($o_hostaddress)){ $o_hostaddress = "127.0.0.1";} if (! defined($o_hostgroup)){ $o_hostgroup = "Linux Servers";} if (! defined($o_servicedesc)){ $o_servicedesc = "os_cpu_load";} if (! defined($o_servicegroup)){ $o_servicegroup = "performance checks";} if (! defined($o_datetime)){ $o_datetime = `date`;} # if (! defined($o_datetime)) {$o_datetime = localtime time;} if (! defined($o_serviceoutput)){ $o_serviceoutput = "Test output for this service";} if (! defined($o_notificationauth)){ $o_notificationauth = "John Doe";} # Setting the keyword "email-debug" in the notification comment below triggers the creation of debug tables if (! defined($o_notificationcmt)){ $o_notificationcmt = "Test message for the service with email-debug";} } # ######################################################################## # Create a plaintext message -> $text_msg # ######################################################################## sub create_message_text { $text_msg = $language{$land}{'N'}."\n" . "=====================================\n\n"; # if customer name was given for service providers, display it here if ( defined($o_customer)) { $text_msg = $text_msg . $language{$land}{'A'} . ": $o_customer\n"; } $text_msg = $text_msg . $language{$land}{'B'} . ": $o_notificationtype\n" . $language{$land}{'C'} . ": $o_servicedesc\n" . $language{$land}{'D'} . ": $o_servicestate\n" . $language{$land}{'E'} . ": $o_servicegroup\n" . $language{$land}{'F'} . ": $o_serviceoutput\n\n" . $language{$land}{'G'} . ": $o_hostname\n" . $language{$land}{'H'} . ": $o_hostalias\n" . $language{$land}{'I'} . ": $o_hostaddress\n" . $language{$land}{'J'} . ": $o_hostgroup\n" . $language{$land}{'K'} . ": $o_datetime\n\n"; # if author and comment data has been passed from nagios # and these variables have content, then we add two more columns if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) && ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) { $text_msg = $text_msg . $language{$land}{'L'} . ": $o_notificationauth\n" . $language{$land}{'M'} . ": $o_notificationcmt\n\n"; } $text_msg = $text_msg . "-------------------------------------\n" . $language{$land}{'O'} . ".\n" . "(". $authors . ")\n" ; } # ######################################################################## # Create a simple HTML message -> $html_msg # ######################################################################## sub create_message_html { # Start HTML message definition $html_msg = "<html><head><style type=\"text/css\">$html_style</style></head><body>\n" . "<table width=$table_size><tr>\n"; if ($o_format eq "multi" || $o_format eq "graph") { $logo_id = create_content_id(); $html_msg = $html_msg . "<td><img class=\"logo\" src=\"cid:$logo_id\"></td>" . "<td><span>$language{$land}{'N'}</span></td></tr><tr>\n"; } else { $html_msg = $html_msg . "<th colspan=2><span>$language{$land}{'N'}</span></th></tr><tr>\n"; } if ( defined($o_customer)) { $html_msg = $html_msg . "<th colspan=2 class=customer>$o_customer</th></tr><tr>\n"; } $html_msg = $html_msg . "<th width=$header_size class=even>$language{$land}{'B'}:</th>\n" . "<td bgcolor=$NOTIFICATIONCOLOR{$o_notificationtype}>\n" . "$o_notificationtype</td></tr>\n" . "<tr><th class=odd>$language{$land}{'C'}:</th><td>$o_servicedesc</td></tr>\n" . "<tr><th class=even>$language{$land}{'E'}:</th><td class=even>\n"; # The Servicegroup URL http://<nagios-web>/cgi-bin/status.cgi?servicegroup=$SERVICEGROUPNAME$&style=overview # This URL shows the service group table listing ofthe hosts that have this service if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?servicegroup=$o_servicegroup&style=overview\">$o_servicegroup</a>"; } else { $html_msg = $html_msg . $o_servicegroup; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'D'}:</th><td>$o_servicestate</td></tr>\n" . "<tr><th class=even>$language{$land}{'F'}:</th><td class=even>\n"; # The ServiceOutput URL http://<nagios-web>/cgi-bin/extinfo.cgi?type=2&host=$HOSTNAME$&service=$SERVICEDESC$ # This URL shows the full service details and commands for service management (ack, re-check, disable, etc) if (defined($o_addurl)) { if ( $nagios_pnpurl eq '') { $html_msg .= "<a href=\"$nagios_cgiurl/extinfo.cgi?type=2&host=$o_hostname&service=$o_servicedesc\">$o_serviceoutput</a>\n"; } else { # Modified by Robert Becht for link to PNP4Nagios graph $html_msg .= "<a href=\"$nagios_pnpurl/index.php/graph?host=$o_hostname&srv=$o_servicedesc\">$o_serviceoutput</a>\n"; } } else{ $html_msg .= $o_serviceoutput; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'G'}:</th><td>\n"; # The Hostname URL http://<nagios-web>/cgi-bin/status.cgi?host=$HOSTNAME$&style=detail # this URL shows the host and all services underneath it if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?host=$o_hostname&style=detail\">$o_hostname</a>"; } else { $html_msg = $html_msg . $o_hostname; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=even>$language{$land}{'H'}:</th><td class=even>$o_hostalias</td></tr>\n" . "<tr><th class=odd>$language{$land}{'I'}:</th><td>$o_hostaddress</td></tr>\n" . "<tr><th class=even>$language{$land}{'J'}:</th><td class=even>\n"; # The Hostgroup URL http://<nagios-web>/cgi-bin/status.cgi?hostgroup=$HOSTGROUPNAME$&style=overview # This URL shows the hostgroup table listing for all individual hosts that belong to it if (defined($o_addurl)) { $html_msg = $html_msg . "<a href=\"$nagios_cgiurl/status.cgi?hostgroup=$o_hostgroup&style=overview\">$o_hostgroup</a>"; } else { $html_msg = $html_msg . $o_hostgroup; } $html_msg = $html_msg . "</td></tr>\n" . "<tr><th class=odd>$language{$land}{'K'}:</th><td>$o_datetime</td></tr>\n"; # If the author and comment data has been passed from nagios # and these variables have content, then we add two more columns if ( ( defined($o_notificationauth) && defined($o_notificationcmt) ) && ( ($o_notificationauth ne "") && ($o_notificationcmt ne "") ) ) { $html_msg = $html_msg . "<tr><th class=even>$language{$land}{'L'}:</th>\n" . "<td class=even>$o_notificationauth</td></tr>\n" . "<tr><th class=odd>$language{$land}{'M'}:</th>\n" . "<td>$o_notificationcmt</td></tr>\n"; } $html_msg = $html_msg . "</table></br>\n"; # if we got the graph format and a image has been generated, we add it here if (defined($graph_img) && $o_format eq "graph") { $graph_id = create_content_id(); $html_msg = $html_msg . "<img src=\"cid:$graph_id\">\n"; } # add the Nagios footer tag line here $html_msg = $html_msg . "</br><hr>\n$language{$land}{'O'}\n .</br><em><font size=\"-1\" >(Authors:$authors)</font></em><hr>\n"; # add the extra debugtables if verbose output had been requested, # or if the notification command contains the keyword "email-debug" if (defined($o_notificationcmt) && ($o_notificationcmt =~ m/email-debug/i) || defined($o_verb)) { &create_debugtable; $html_msg = $html_msg . $debugtables; } # End HTML message definition $html_msg = $html_msg . "</body></html>\n"; } # ####################################################################### # urlencode() URL encode a string # ####################################################################### sub urlencode { $_[0] =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; return $_[0]; } # ####################################################################### # hashcolor() Choose a color for service # ####################################################################### sub hashcolor { my $c=0; map{$c=(51*$c+ord)%(216)}split//,"$_[0]x"; my $i = 0; my $n = 0; my $m = 0; my @h=(51*int $c/36,51*int $c/6%6,51*($c%6)); for$i(0..2){$m=$i if$h[$i]<$h[$m];$n=$i if$h[$i]>$h[$n]} $h[$m]=102if$h[$m]>102;$h[$n]=153if$h[$n]<153; $c=sprintf"%06X",$h[2]+$h[1]*256+$h[0]*16**4; return $c; } # ####################################################################### # dbfilelist() Get list of matching rrd files # ####################################################################### sub dbfilelist { my($host,$service, $rrddir) = @_; my $hs; # New style, files inside a <hostname> directory $rrddir .= "/" . $host; $hs = urlencode "$service" . "___"; verb("sub dbfilelist: Checking files inside directory: ".$rrddir); my @rrd; opendir DH, $rrddir or verb("sub dbfilelist: Cannot open: ".$rrddir); @rrd = grep s/^${hs}(.+)\.rrd$/$1/, readdir DH; closedir DH; verb("sub dbfilelist: We found number of RRD files: ".@rrd); return @rrd; } # ####################################################################### # graphinfo() Find graphs and values # ####################################################################### sub graphinfo { my($host,$service,$rrddir) = @_; my(@rrd,$ds,$f,$dsout,@values,$hs,%H,%R); $hs = $host . "/"; $hs .= urlencode "$service" . "___"; # Determine which files to read lines from @rrd = map {{ file=>$_ }} map { "${hs}${_}.rrd" } dbfilelist($host,$service, $rrddir); # we stop processing here if we could not find a file if (@rrd < 1) { verb("sub graphinfo: Could not find any graph file."); return undef; } else { verb("sub graphinfo: Listing $hs db files in $rrddir: " . join ', ', map { $_->{file} } @rrd); } $rrdfile = $rrd[0]->{file}; $ds = RRDs::info "$rrddir/$rrdfile"; verb("sub graphinfo: RRDs::info ERR " . RRDs::error) if RRDs::error; map { $rrd[0]->{line}{$_} = 1} grep {!$H{$_}++} map { /ds\[(.*)\]/; $1 } grep /ds\[(.*)\]/, keys %$ds; verb("sub graphinfo: Found datasources: " . %$ds); return \@rrd; } # ####################################################################### # rrdline() Generate the rrd parameters to produce a graph # ####################################################################### sub rrdline { my($host,$service,$geom,$G,$rrddir,$tmpfile) = @_; my($g,$f,$v,$c,@ds); my $directory = $rrddir; @ds = ($tmpfile, '-a', 'PNG', '-t', $service); push @ds, "--color=BACK$graph_bgcolor", "--color=SHADEA$graph_border", "--color=SHADEB$graph_border"; # Identify where to pull data from and what to call it for $g ( @$G ) { $f = $g->{file}; verb("sub rrdline: set filename: $f"); # Compute the longest label length my $longest = (sort map(length,keys(%{ $g->{line} })))[-1]; for $v ( sort keys %{ $g->{line} } ) { $c = hashcolor($v); verb("sub rrdline: file=$f line=$v color=$c"); my $sv = "$v"; my $label = sprintf("%-${longest}s", $sv); push @ds , "DEF:$sv=$directory/$f:$v:AVERAGE" , "LINE2:${sv}#$c:$label"; my $format = '%6.2lf%s'; # Graph labels push @ds, "GPRINT:$sv:MAX:Max\\: $format" , "GPRINT:$sv:AVERAGE:Avg\\: $format" , "GPRINT:$sv:MIN:Min\\: $format" , "GPRINT:$sv:LAST:Cur\\: ${format}\\n"; } } # Dimensions of graph if geom is specified if ( $geom ) { my($w,$h) = split 'x', $geom; push @ds, '-w', $w, '-h', $h; } return @ds; } # ######################################################################## # uuencode_image(filename) converts a existing binary source image file # into a base64-image string. # ######################################################################## sub uuencode_img { my($inputfile) = @_; open (IMG, $inputfile) or verb("uuencode_img: Cannot read source image file: $inputfile - $!"); binmode IMG; undef $/; my $uuencoded_img = encode_base64(<IMG>); close IMG; verb("uuencode_img: completed conversion of source image file: $inputfile - $!"); return $uuencoded_img; } # ####################################################################### # create_graph_img() tries to create a performance graph image file (PNG) # Input is the hostname and servicename, then we try to find a matching # RRD file according to NagiosGraph's filesystem layout. If there is one, # it queries the RRD information and graphs the last 24 hours similar to # Nagiosgraph. # ####################################################################### sub create_graph_img { my $fhandle = undef; my $graph_img = undef; # Figure out db files and line labels my $G = graphinfo($o_hostname,$o_servicedesc,$rrd_basedir); # if we could not find RRD data, we return $img as undef if(! defined($G)) { verb("sub create_graph_img: No graph data for $o_hostname,$o_servicedesc was found."); return $graph_img; } # generate temporary graph files for todays RRD data $fhandle = File::Temp->new() or verb("create_graph_img: Cannot create temporary image file."); my $tmpfile = $fhandle->filename; $ftemp = $tmpfile; my @ds = rrdline($o_hostname,$o_servicedesc,$graph_img_size,$G,$rrd_basedir,$tmpfile); verb("sub create_graph_img: RRDs::graph ". join ' ', @ds); RRDs::graph(@ds); verb("sub create_graph_img: RRDs::graph ERR " . RRDs::error) if RRDs::error; # because our mail system being Lotus Notes, which is not supporting PNG # images, we must convert them from PNG to JPG before we can continue. # comment out the next 3 lines if PNG images work with your mail clients # my $jpg_tmpfile = $tmpfile.".jpg"; # `pngtopnm $tmpfile | pnmtojpeg >$jpg_tmpfile`; # `mv $jpg_tmpfile $tmpfile`; # In e-mails, images need to be base64 encoded, we uuencode here $graph_img = uuencode_img($tmpfile); return $graph_img; } # ######################################################################## # Added by Robert Becht for request an PNP4Nagios graph # ######################################################################## sub import_pnp_graph { use LWP::Simple; $elapse = (1 * 3600); # This set 1 hour history $tstamp = time(); $tstart = ($tstamp - $tstamp); $img_get = "http://127.0.0.1/$pnp_uri/image?host=$o_hostname&srv=$o_servicedesc&source=0&start=$tstart&end=$tstamp"; # generate temporary graph files for todays RRD data my $fhandle = File::Temp->new( UNLINK =>1, SUFFIX => '.png') or verb("create_graph_img: Cannot create temporary image file."); my $tmpfile = $fhandle->filename; $ftemp = $tmpfile; # write the graphik file in $tmpfile print $fhandle get("$img_get"); # This is for graph size my $pnmfile = `pngtopnm $tmpfile`; (my $xysize = $graph_img_size) =~ s/x/ /; `pamscale -xysize $xysize $pnmfile | pnmtopng >$img_get`; # or use pnmtojpeg if png not supported ... $graph_img = uuencode_img($tmpfile); return $graph_img; } # ######################################################################## # language translated email subject: $lang{$land} # ######################################################################## sub set_subject { my $subject; my %lang = ('en' => "Nagios: $o_notificationtype service $o_servicedesc on $o_hostname ($o_hostgroup) is $o_servicestate", 'de' => "Nagios: $o_notificationtype $o_hostname($o_hostgroup) mit Dienst $o_servicedesc ist $o_servicestate", 'jp' => "Nagios: $o_notificationtype $o_hostname($o_hostgroup)のサービス $o_servicedesc $o_servicestate", 'fr' => "Nagios: $o_notificationtype : le service $o_servicedesc sur $o_hostname ($o_hostgroup) est $o_servicestate" ); if (!defined($lang{$land})) { $subject = $lang{'en'}; } else { $subject = $lang{$land}; } return $subject; } # ####################################################################### # main # ####################################################################### check_options(); $mail{Cc} = $o_cc_recipients if ($o_cc_recipients); $mail{Bcc} = $o_bcc_recipients if ($o_bcc_recipients); $mail{smtp} = $o_smtphost; $mail{subject} = set_subject(); # If the mail server requires authentication, try this line: # $mail{auth} = {user => "<username>", password => "<mailpw>", method="">"LOGIN PLAIN", required=>1}; if ($o_format eq "graph") { if ( ! defined $pnp_uri) { verb("main: trying to create the a graph image."); $graph_img = create_graph_img(); } else { $graph_img = import_pnp_graph();} } if ($o_format eq "multi" || $o_format eq "graph") { verb("main: Sending HTML email (language: $land) with inline logo."); # In e-mails, images need to be base64 encoded, we uuencode here my $logo_img = uuencode_img($logofile); create_boundary(); create_message_html(); $mail{'content-type'} = qq(multipart/related; boundary="$boundary"); $boundary = '--' . $boundary; # Here we define the mail content to be send my $mail_content = "This is a multi-part message in MIME format.\n" # create the first boundary start marker for the main message . "$boundary\n" . "Content-Type: text/html; charset=utf-8\n" . "Content-Transfer-Encoding: 8bit\n\n" . "$html_msg\n"; # create the second boundary marker for the logo $mail_content = $mail_content . "$boundary\n" . "Content-Type: image/gif; name=\"logo.gif\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-ID: <$logo_id>\n" . "Content-Disposition: inline; filename=\"logo.gif\"\n\n" . "$logo_img\n"; # if we got the graph format and a image has been generated, we add it here # create the third boundary marker for the graph if (defined($graph_img) && $o_format eq "graph") { $mail_content = $mail_content . "\n" . "$boundary\n" . "Content-Type: image/jpg; name=\"graph.jpg\"\n" . "Content-Transfer-Encoding: base64\n" . "Content-ID: <$graph_id>\n" . "Content-Disposition: inline; filename=\"graph.jpg\"\n\n" . "$graph_img\n"; } # create the final end boundary marker $mail_content = $mail_content . $boundary . "--\n"; # put the completed message body into the mail $mail{body} = $mail_content ; } elsif ($o_format eq "html") { create_message_html(); $mail{'content-type'} = qq(text/html; charset="utf-8"); $mail{body} = $html_msg ; } else { create_message_text(); $mail{'content-type'} = qq(text/plain; charset="utf-8"); $mail{body} = $text_msg ; } sendmail(%mail) or die $Mail::Sendmail::error; verb("Sendmail Log says:\n$Mail::Sendmail::log\n"); exit 0; # ####################################################################### # Create a debugging table to check on Nagios and script variables # Added by Robert Becht to create a HTML table for debugging # ####################################################################### sub create_debugtable() { my $varcount = 0; my $oddcheck = "odd"; # Check if the following variables are defined my %param_vars = ( 'script' => { "title" => 'Script debug data', "o_verb" => \$o_verb, "o_version" => \$o_version, "o_help" => \$o_help, "o_smtphost" => \$o_smtphost, "o_customer" => \$o_customer, "o_to_recipients" => \$o_to_recipients, "o_to_group" => \$o_to_group, "o_cc_recipients" => \$o_cc_recipients, "o_bcc_recipients" => \$o_bcc_recipients, "o_format" => \$o_format, "o_addurl" => \$o_addurl, "o_language" => \$o_language, "o_test" => \$o_test, "o_smtphost" => \$o_smtphost, "domain" => \$domain, "land" => \$land, "logo file" => \$logofile, "temporary file" => \$ftemp, "boundary" => \$boundary }, 'nagios' => { "title" => 'Nagios debug data', "o_notificationtype" => \$o_notificationtype, "o_notificationauth" => \$o_notificationauth, "o_notificationcmt" => \$o_notificationcmt, "o_servicedesc" => \$o_servicedesc, "o_servicestate" => \$o_servicestate, "o_servicegroup" => \$o_servicegroup, "o_hostname" => \$o_hostname, "o_hostalias" => \$o_hostalias, "o_hostgroup" => \$o_hostgroup, "o_hostaddress" => \$o_hostaddress, "o_serviceoutput" => \$o_serviceoutput, "o_datetime" => \$o_datetime, "o_to_recipients" => \$o_to_recipients, "o_to_group" => \$o_to_group }, 'rrdbase' => { "title" => 'RRD debug data', "rrd_basedir" => \$rrd_basedir, "rrdfile" => \$rrdfile, "hs" => \$hs, "rrdfile" => \$rrdfile, "DS" => \$ds, "labels" => \$G }, 'pnp' => { "title" => 'PNP debug data', "PNP url" => \$nagios_pnpurl, "PNP uri" => \$pnp_uri, "img_get" => \$img_get, "interval(s)" => \$elapse, "time start" => \$tstamp } ); # display the script variables # Tables loop foreach $tbl (keys %param_vars) { $debugtables .= "</br>\n" . "<table width=$table_size>\n" . "<tr><th colspan=2 class=customer>$param_vars{$tbl}->{'title'}</th></tr>\n"; $varcount = 0; # Data loop foreach $var (keys %{$param_vars{$tbl}}) { if ($var ne 'title') { if ($varcount%2) {$oddcheck = "odd"; } else {$oddcheck = "even";} $debugtables .= "<tr><th class=$oddcheck>$var</th>"; if ((! defined(${$param_vars{$tbl}->{$var}})) || (${$param_vars{$tbl}->{$var}} eq '')) { $debugtables .= "<td class=$oddcheck>&nbsp;</td></tr>\n"; } else { $debugtables .= "<td class=$oddcheck>${$param_vars{$tbl}->{$var}}</td></tr>\n"; # # Debugging # print $var . "= " . ${$param_vars{$tbl}->{$var}} . "\n"; } $varcount++; } } $debugtables .= "</table>"; $debugtables .="</br>\n"; } } A parte do script que é responsável por montar os endereços de email é essa: # Basic checks if (defined ($o_help)) { help(); exit 0}; if (defined($o_version)) { p_version(); exit 0}; if ((! defined($o_to_recipients)) && (! defined($o_to_group))) { # no recipients provided print "Error: no recipients have been provided\n"; print_usage(); exit -1} else { if (! defined($o_to_group)) { %mail = ( To => $o_to_recipients, From => $mail_sender, Sender => $mail_sender ); } else { &create_address; %mail = ( To => $o_to_group, From => $mail_sender, Sender => $mail_sender ); } } Porém ela é a mesma nos dois scripts, porém funciona apenas em um.
×
×
  • Create New...