├── .npmignore ├── .gitignore ├── screenshots ├── host-recovery.png ├── service-critical.png └── service-recovery-thread.png ├── Makefile ├── package.json ├── templates ├── host.html.ejs └── service.html.ejs ├── nagios-html-email.js ├── test ├── host.env └── service.env └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | screenshots 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.html 3 | -------------------------------------------------------------------------------- /screenshots/host-recovery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Voxer/nagios-html-email/HEAD/screenshots/host-recovery.png -------------------------------------------------------------------------------- /screenshots/service-critical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Voxer/nagios-html-email/HEAD/screenshots/service-critical.png -------------------------------------------------------------------------------- /screenshots/service-recovery-thread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Voxer/nagios-html-email/HEAD/screenshots/service-recovery-thread.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: html 2 | 3 | html: 4 | . test/service.env && ./nagios-html-email.js service | awk 'NR > 5' > service.html 5 | . test/host.env && ./nagios-html-email.js host | awk 'NR > 5' > host.html 6 | 7 | clean: 8 | rm -f *.html 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nagios-html-email", 3 | "version": "0.0.1", 4 | "description": "Generate HTML emails for Nagios service and host alerts", 5 | "author": "Dave Eddy (http://www.daveeddy.com)", 6 | "repository": "git://github.com/Voxer/nagios-html-email.git", 7 | "license": "MIT", 8 | "preferGlobal": true, 9 | "bin": { 10 | "nagios-html-email": "./nagios-html-email.js" 11 | }, 12 | "dependencies": { 13 | "posix-getopt": "~1.0.0", 14 | "ejs": "~3.1.10", 15 | "latest": "~0.1.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /templates/host.html.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | // nagios base URI, ex http://nagios.example.com 3 | var baseuri = args[0]; 4 | // colors to use for the email 5 | var colors = { 6 | host: { 7 | UP: '#88d066', 8 | DOWN: '#f88888', 9 | }, 10 | table: { 11 | 0: '#f4f4f4', 12 | 1: '#e7e7e7' 13 | } 14 | }; 15 | // keys to put in the table if they are present 16 | var keys = [ 17 | 'NOTIFICATIONTYPE', 18 | 'HOSTALIAS', 19 | 'HOSTADDRESS', 20 | 'LONGDATETIME', 21 | 'HOSTSTATE' 22 | ]; 23 | -%> 24 | 25 | 26 | 27 |
28 | <%= nagios.HOSTSTATE %> - 29 | <%= nagios.HOSTALIAS.split('.')[0] %> 30 |
31 |
32 | <% if (nagios.NOTIFICATIONAUTHOR && nagios.NOTIFICATIONCOMMENT) { -%> 33 | [<%= nagios.NOTIFICATIONTYPE === 'ACKNOWLEDGEMENT' ? 'acknowledgement' : 'comment' %>] 34 | <%= nagios.NOTIFICATIONAUTHOR %>: <%= nagios.NOTIFICATIONCOMMENT %> 35 |
36 |
37 | <% } -%> 38 | 39 | <% 40 | var i = 0; 41 | keys.forEach(function(key) { 42 | if (!nagios[key]) 43 | return; 44 | -%> 45 | 46 | 47 | 48 | 49 | <% }); -%> 50 |
<%= key.toLowerCase() %><%= nagios[key] %>
51 |
52 | 53 |
54 | <% if (baseuri) { -%> 55 | 59 | <% } -%> 60 | 61 | <%= nagios.LONGDATETIME %> 62 |
63 | 64 | 65 | -------------------------------------------------------------------------------- /templates/service.html.ejs: -------------------------------------------------------------------------------- 1 | <% 2 | // nagios base URI, ex http://nagios.example.com 3 | var baseuri = args[0]; 4 | // colors to use for the email 5 | var colors = { 6 | service: { 7 | OK: '#88d066', 8 | WARNING: '#ffff00', 9 | CRITICAL: '#f88888', 10 | UNKNOWN: '#ffbb55' 11 | }, 12 | table: { 13 | 0: '#f4f4f4', 14 | 1: '#e7e7e7' 15 | } 16 | }; 17 | // keys to put in the table if they are present 18 | var keys = [ 19 | 'NOTIFICATIONTYPE', 20 | 'SERVICEDESC', 21 | 'HOSTALIAS', 22 | 'HOSTADDRESS', 23 | 'SERVICESTATE', 24 | 'SERVICEDURATION', 25 | 'SERVICEOUTPUT', 26 | 'LONGDATETIME' 27 | ]; 28 | -%> 29 | 30 | 31 | 32 |
33 | <%= nagios.SERVICESTATE %> - 34 | <%= nagios.HOSTALIAS.split('.')[0] %> <%= nagios.SERVICEDESC %> 35 |
36 |
37 |
<%= nagios.SERVICEOUTPUT %>
38 |
39 | <% if (nagios.NOTIFICATIONAUTHOR && nagios.NOTIFICATIONCOMMENT) { -%> 40 | [<%= nagios.NOTIFICATIONTYPE === 'ACKNOWLEDGEMENT' ? 'acknowledgement' : 'comment' %>] 41 | <%= nagios.NOTIFICATIONAUTHOR %>: <%= nagios.NOTIFICATIONCOMMENT %> 42 |
43 |
44 | <% } else if (nagios._SERVICEALLEVIATE && nagios.SERVICESTATE !== 'OK') { -%> 45 | the following steps may possibly alleviate the issue 46 |
47 |
<%= nagios._SERVICEALLEVIATE %>
48 |
49 | <% } -%> 50 | 51 | <% 52 | var i = 0; 53 | keys.forEach(function(key) { 54 | if (!nagios[key]) 55 | return; 56 | -%> 57 | 58 | 59 | 60 | 61 | <% }); -%> 62 |
<%= key.toLowerCase() %><%= nagios[key] %>
63 |
64 | 65 |
66 | <% if (baseuri) { -%> 67 | 72 | <% } -%> 73 | 74 | <%= nagios.LONGDATETIME %> 75 |
76 | 77 | 78 | -------------------------------------------------------------------------------- /nagios-html-email.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * Generate notifications for host or services via nagios 4 | * and output raw email data suitable for passing to 5 | * something like `mailx -t` 6 | * 7 | * Author: Dave Eddy 8 | * Date: 2/3/2014 9 | * Licens: MIT 10 | */ 11 | 12 | var fs = require('fs'); 13 | var path = require('path'); 14 | var util = require('util'); 15 | 16 | var ejs = require('ejs'); 17 | var getopt = require('posix-getopt'); 18 | 19 | var package = require('./package'); 20 | 21 | function usage() { 22 | return [ 23 | 'Usage: nagios-html-email [options] [arg1] [arg2] ...', 24 | '', 25 | 'This command is meant to be run from nagios when a service or host', 26 | 'experiences problems. The output will be suitable for passing to', 27 | 'a mail program that takes raw email data like `mailx -t`', 28 | '', 29 | 'Options', 30 | ' -a, --address the email address to send mail to, defaults to env NAGIOS_CONTACTEMAIL', 31 | ' -h, --help print this message and exit', 32 | ' -s, --subject the email subject to use, defaults to _subject for the host/service, or default nagios subject', 33 | ' -t, --template-dir dir to find ejs template files, defaults to builtin templates', 34 | ' -u, --updates check for available updates on npm', 35 | ' -v, --version print the version number and exit', 36 | ].join('\n'); 37 | } 38 | 39 | // command line arguments 40 | var options = [ 41 | 'a:(address)', 42 | 'h(help)', 43 | 's:(subject)', 44 | 't:(template-dir)', 45 | 'u(updates)', 46 | 'v(version)' 47 | ].join(''); 48 | var parser = new getopt.BasicParser(options, process.argv); 49 | 50 | var opts = { 51 | subject: null, 52 | templatedir: path.join(__dirname, 'templates'), 53 | to: process.env.NAGIOS_CONTACTEMAIL 54 | }; 55 | var option; 56 | while ((option = parser.getopt()) !== undefined) { 57 | switch (option.option) { 58 | case 'a': opts.to = option.optarg; break; 59 | case 'h': console.log(usage()); process.exit(0); 60 | case 's': opts.subject = option.optarg; break; 61 | case 't': opts.templatedir = option.optarg; break; 62 | case 'u': // check for updates 63 | require('latest').checkupdate(package, function(ret, msg) { 64 | console.log(msg); 65 | process.exit(ret); 66 | }); 67 | return; 68 | case 'v': console.log(package.version); process.exit(0); 69 | default: console.error(usage()); process.exit(1); 70 | } 71 | } 72 | var args = process.argv.slice(parser.optind()); 73 | 74 | // the notification type, typically 'host' or 'subject' 75 | var type = args.shift(); 76 | if (!type) { 77 | console.error('a type must be specified as the first argument!'); 78 | console.error(); 79 | console.error(usage()); 80 | process.exit(1); 81 | } 82 | 83 | // the email address to whom the notification should be sent 84 | if (!opts.to) { 85 | console.error('env NAGIOS_CONTACTEMAIL or `-a
` must be supplied!'); 86 | console.error(); 87 | console.error(usage()); 88 | process.exit(1); 89 | } 90 | 91 | // extract nagios environmental variables 92 | var nagios = {}; 93 | Object.keys(process.env).forEach(function(key) { 94 | if (key.indexOf('NAGIOS_') === 0) 95 | nagios[key.replace(/^NAGIOS_/, '')] = process.env[key]; 96 | }); 97 | var data = { 98 | args: args, 99 | nagios: nagios, 100 | package: package 101 | }; 102 | 103 | // create the subject if `-s` is not supplied 104 | if (!opts.subject) { 105 | // look for _subject on the host or service and prefer that if it exists 106 | var key = util.format('_%sSUBJECT', type.toUpperCase()); 107 | opts.subject = data.nagios[key]; 108 | if (!opts.subject) { 109 | switch (type) { 110 | case 'host': 111 | opts.subject = util.format('%s is %s', 112 | data.nagios.HOSTALIAS, 113 | data.nagios.HOSTSTATE); 114 | break; 115 | case 'service': 116 | opts.subject = util.format('%s - %s %s', 117 | data.nagios.SERVICESTATE, 118 | data.nagios.HOSTALIAS, 119 | data.nagios.SERVICEDESC); 120 | break; 121 | default: 122 | opts.subject = util.format('unknown type - %s', 123 | type); 124 | break; 125 | } 126 | } 127 | } 128 | 129 | // email headers 130 | console.log('To: %s', opts.to); 131 | console.log('Reply-To: %s', opts.to); 132 | console.log('Subject: %s', opts.subject); 133 | console.log('Content-Type: text/html'); 134 | console.log(); 135 | 136 | var message; 137 | // the message to be sent if something goes wrong 138 | // or if a template cannot be found. 139 | // it is just the JSON provided by the nagios daemon 140 | var templ = '
<%= d %>
'; 141 | data.d = JSON.stringify(data, null, 2); 142 | try { 143 | message = ejs.render(templ, data); 144 | } catch (e) { 145 | message = util.format('error rendering default template!: %s', e.message); 146 | console.error(message); 147 | } 148 | 149 | // try to find a template, /.html.ejs 150 | // and render it 151 | var templfile = path.join(opts.templatedir, type + '.html.ejs'); 152 | try { 153 | var templ = fs.readFileSync(templfile, 'utf-8'); 154 | message = ejs.render(templ, data); 155 | } catch (e) { 156 | // if we are here, message will still be set from the above line 157 | // so don't overwrite it 158 | console.error('template %s error: %s', templfile, e.message); 159 | } 160 | 161 | // dump the message to stdout 162 | console.log(message); 163 | -------------------------------------------------------------------------------- /test/host.env: -------------------------------------------------------------------------------- 1 | export NAGIOS_ADMINEMAIL="admin@example.com" 2 | export NAGIOS_ADMINPAGER="admin@example.com" 3 | export NAGIOS_ARG1="" 4 | export NAGIOS_ARG10="" 5 | export NAGIOS_ARG11="" 6 | export NAGIOS_ARG12="" 7 | export NAGIOS_ARG13="" 8 | export NAGIOS_ARG14="" 9 | export NAGIOS_ARG15="" 10 | export NAGIOS_ARG16="" 11 | export NAGIOS_ARG17="" 12 | export NAGIOS_ARG18="" 13 | export NAGIOS_ARG19="" 14 | export NAGIOS_ARG2="" 15 | export NAGIOS_ARG20="" 16 | export NAGIOS_ARG21="" 17 | export NAGIOS_ARG22="" 18 | export NAGIOS_ARG23="" 19 | export NAGIOS_ARG24="" 20 | export NAGIOS_ARG25="" 21 | export NAGIOS_ARG26="" 22 | export NAGIOS_ARG27="" 23 | export NAGIOS_ARG28="" 24 | export NAGIOS_ARG29="" 25 | export NAGIOS_ARG3="" 26 | export NAGIOS_ARG30="" 27 | export NAGIOS_ARG31="" 28 | export NAGIOS_ARG32="" 29 | export NAGIOS_ARG4="" 30 | export NAGIOS_ARG5="" 31 | export NAGIOS_ARG6="" 32 | export NAGIOS_ARG7="" 33 | export NAGIOS_ARG8="" 34 | export NAGIOS_ARG9="" 35 | export NAGIOS_COMMANDFILE="/tmp/nagios/rw/nagios.cmd" 36 | export NAGIOS_CONTACTADDRESS0="" 37 | export NAGIOS_CONTACTADDRESS1="" 38 | export NAGIOS_CONTACTADDRESS2="" 39 | export NAGIOS_CONTACTADDRESS3="" 40 | export NAGIOS_CONTACTADDRESS4="" 41 | export NAGIOS_CONTACTADDRESS5="" 42 | export NAGIOS_CONTACTALIAS="Nagios" 43 | export NAGIOS_CONTACTEMAIL="nagios@example.com" 44 | export NAGIOS_CONTACTGROUPALIAS="Nagios Admins" 45 | export NAGIOS_CONTACTGROUPMEMBERS="nagios" 46 | export NAGIOS_CONTACTGROUPNAME="admins" 47 | export NAGIOS_CONTACTGROUPNAMES="admins" 48 | export NAGIOS_CONTACTNAME="nagios" 49 | export NAGIOS_CONTACTPAGER="" 50 | export NAGIOS_DATE="02-20-2014" 51 | export NAGIOS_EVENTSTARTTIME="1392850569" 52 | export NAGIOS_HOSTACKAUTHOR="" 53 | export NAGIOS_HOSTACKAUTHORALIAS="" 54 | export NAGIOS_HOSTACKAUTHORNAME="" 55 | export NAGIOS_HOSTACKCOMMENT="" 56 | export NAGIOS_HOSTACTIONURL="" 57 | export NAGIOS_HOSTADDRESS="192.168.1.2" 58 | export NAGIOS_HOSTALIAS="prod-box-1.voxer.com" 59 | export NAGIOS_HOSTATTEMPT="1" 60 | export NAGIOS_HOSTCHECKCOMMAND="check-host-alive" 61 | export NAGIOS_HOSTCHECKTYPE="ACTIVE" 62 | export NAGIOS_HOSTDISPLAYNAME="prod-box-1.voxer.com" 63 | export NAGIOS_HOSTDOWNTIME="0" 64 | export NAGIOS_HOSTDURATION="0d 0h 0m 0s" 65 | export NAGIOS_HOSTDURATIONSEC="0" 66 | export NAGIOS_HOSTEVENTID="16470" 67 | export NAGIOS_HOSTEXECUTIONTIME="0.033" 68 | export NAGIOS_HOSTGROUPACTIONURL="" 69 | export NAGIOS_HOSTGROUPALIAS="All Servers" 70 | export NAGIOS_HOSTGROUPMEMBERS="prod-box-1.voxer.com,prod-box-2.voxer.com" 71 | export NAGIOS_HOSTGROUPNAME="server" 72 | export NAGIOS_HOSTGROUPNAMES="server,prod-redis,prod,base" 73 | export NAGIOS_HOSTGROUPNOTES="" 74 | export NAGIOS_HOSTGROUPNOTESURL="" 75 | export NAGIOS_HOSTLATENCY="0.000" 76 | export NAGIOS_HOSTNAME="prod-box-1.voxer.com" 77 | export NAGIOS_HOSTNOTES="" 78 | export NAGIOS_HOSTNOTESURL="" 79 | export NAGIOS_HOSTNOTIFICATIONID="2159" 80 | export NAGIOS_HOSTNOTIFICATIONNUMBER="2" 81 | export NAGIOS_HOSTOUTPUT="PING OK - Packet loss = 0%, RTA = 0.12 ms" 82 | export NAGIOS_HOSTPERCENTCHANGE="16.25" 83 | export NAGIOS_HOSTPERFDATA="rta=0.125000ms;3000.000000;5000.000000;0.000000 pl=0%;80;100;0" 84 | export NAGIOS_HOSTPERFDATAFILE="" 85 | export NAGIOS_HOSTPROBLEMID="0" 86 | export NAGIOS_HOSTSTATE="UP" 87 | export NAGIOS_HOSTSTATEID="0" 88 | export NAGIOS_HOSTSTATETYPE="HARD" 89 | export NAGIOS_ISVALIDTIME="" 90 | export NAGIOS_LASTHOSTCHECK="1392913969" 91 | export NAGIOS_LASTHOSTDOWN="1392913819" 92 | export NAGIOS_LASTHOSTEVENTID="16460" 93 | export NAGIOS_LASTHOSTPROBLEMID="8211" 94 | export NAGIOS_LASTHOSTSTATE="DOWN" 95 | export NAGIOS_LASTHOSTSTATECHANGE="1392913979" 96 | export NAGIOS_LASTHOSTSTATEID="1" 97 | export NAGIOS_LASTHOSTUNREACHABLE="0" 98 | export NAGIOS_LASTHOSTUP="1392913979" 99 | export NAGIOS_LASTSERVICECHECK="" 100 | export NAGIOS_LASTSERVICECRITICAL="" 101 | export NAGIOS_LASTSERVICEEVENTID="" 102 | export NAGIOS_LASTSERVICEOK="" 103 | export NAGIOS_LASTSERVICEPROBLEMID="" 104 | export NAGIOS_LASTSERVICESTATE="" 105 | export NAGIOS_LASTSERVICESTATECHANGE="" 106 | export NAGIOS_LASTSERVICESTATEID="" 107 | export NAGIOS_LASTSERVICEUNKNOWN="" 108 | export NAGIOS_LASTSERVICEWARNING="" 109 | export NAGIOS_LOGFILE="/tmp/nagios/nagios.log" 110 | export NAGIOS_LONGDATETIME="Thu Feb 20 16:32:59 UTC 2014" 111 | export NAGIOS_LONGHOSTOUTPUT="" 112 | export NAGIOS_LONGSERVICEOUTPUT="" 113 | export NAGIOS_MAINCONFIGFILE="/opt/local/etc/nagios/nagios.cfg" 114 | export NAGIOS_MAXHOSTATTEMPTS="3" 115 | export NAGIOS_MAXSERVICEATTEMPTS="" 116 | export NAGIOS_NEXTVALIDTIME="" 117 | export NAGIOS_NOTIFICATIONAUTHOR="" 118 | export NAGIOS_NOTIFICATIONAUTHORALIAS="" 119 | export NAGIOS_NOTIFICATIONAUTHORNAME="" 120 | export NAGIOS_NOTIFICATIONCOMMENT="" 121 | export NAGIOS_NOTIFICATIONISESCALATED="0" 122 | export NAGIOS_NOTIFICATIONNUMBER="2" 123 | export NAGIOS_NOTIFICATIONRECIPIENTS="nagios" 124 | export NAGIOS_NOTIFICATIONTYPE="RECOVERY" 125 | export NAGIOS_OBJECTCACHEFILE="/tmp/nagios/objects.cache" 126 | export NAGIOS_PROCESSSTARTTIME="1392850560" 127 | export NAGIOS_RESOURCEFILE="/opt/local/etc/nagios/resource.cfg" 128 | export NAGIOS_RETENTIONDATAFILE="/tmp/nagios/retention.dat" 129 | export NAGIOS_SERVICEACKAUTHOR="" 130 | export NAGIOS_SERVICEACKAUTHORALIAS="" 131 | export NAGIOS_SERVICEACKAUTHORNAME="" 132 | export NAGIOS_SERVICEACKCOMMENT="" 133 | export NAGIOS_SERVICEACTIONURL="" 134 | export NAGIOS_SERVICEATTEMPT="" 135 | export NAGIOS_SERVICECHECKCOMMAND="" 136 | export NAGIOS_SERVICECHECKTYPE="" 137 | export NAGIOS_SERVICEDESC="" 138 | export NAGIOS_SERVICEDISPLAYNAME="" 139 | export NAGIOS_SERVICEDOWNTIME="" 140 | export NAGIOS_SERVICEDURATION="" 141 | export NAGIOS_SERVICEDURATIONSEC="" 142 | export NAGIOS_SERVICEEVENTID="" 143 | export NAGIOS_SERVICEEXECUTIONTIME="" 144 | export NAGIOS_SERVICEGROUPACTIONURL="" 145 | export NAGIOS_SERVICEGROUPALIAS="" 146 | export NAGIOS_SERVICEGROUPMEMBERS="" 147 | export NAGIOS_SERVICEGROUPNAME="" 148 | export NAGIOS_SERVICEGROUPNAMES="" 149 | export NAGIOS_SERVICEGROUPNOTES="" 150 | export NAGIOS_SERVICEGROUPNOTESURL="" 151 | export NAGIOS_SERVICEISVOLATILE="" 152 | export NAGIOS_SERVICELATENCY="" 153 | export NAGIOS_SERVICENOTES="" 154 | export NAGIOS_SERVICENOTESURL="" 155 | export NAGIOS_SERVICENOTIFICATIONID="" 156 | export NAGIOS_SERVICENOTIFICATIONNUMBER="" 157 | export NAGIOS_SERVICEOUTPUT="" 158 | export NAGIOS_SERVICEPERCENTCHANGE="" 159 | export NAGIOS_SERVICEPERFDATA="" 160 | export NAGIOS_SERVICEPERFDATAFILE="" 161 | export NAGIOS_SERVICEPROBLEMID="" 162 | export NAGIOS_SERVICESTATE="" 163 | export NAGIOS_SERVICESTATEID="" 164 | export NAGIOS_SERVICESTATETYPE="" 165 | export NAGIOS_SHORTDATETIME="02-20-2014 16:32:59" 166 | export NAGIOS_STATUSDATAFILE="/tmp/nagios/status.dat" 167 | export NAGIOS_TEMPFILE="/tmp/nagios.tmp" 168 | export NAGIOS_TEMPPATH="/tmp" 169 | export NAGIOS_TIME="16:32:59" 170 | export NAGIOS_TIMET="1392913979" 171 | export NAGIOS_TOTALHOSTPROBLEMS="" 172 | export NAGIOS_TOTALHOSTPROBLEMSUNHANDLED="" 173 | export NAGIOS_TOTALHOSTSDOWN="" 174 | export NAGIOS_TOTALHOSTSDOWNUNHANDLED="" 175 | export NAGIOS_TOTALHOSTSERVICES="245" 176 | export NAGIOS_TOTALHOSTSERVICESCRITICAL="55" 177 | export NAGIOS_TOTALHOSTSERVICESOK="134" 178 | export NAGIOS_TOTALHOSTSERVICESUNKNOWN="56" 179 | export NAGIOS_TOTALHOSTSERVICESWARNING="0" 180 | export NAGIOS_TOTALHOSTSUNREACHABLE="" 181 | export NAGIOS_TOTALHOSTSUNREACHABLEUNHANDLED="" 182 | export NAGIOS_TOTALHOSTSUP="" 183 | export NAGIOS_TOTALSERVICEPROBLEMS="" 184 | export NAGIOS_TOTALSERVICEPROBLEMSUNHANDLED="" 185 | export NAGIOS_TOTALSERVICESCRITICAL="" 186 | export NAGIOS_TOTALSERVICESCRITICALUNHANDLED="" 187 | export NAGIOS_TOTALSERVICESOK="" 188 | export NAGIOS_TOTALSERVICESUNKNOWN="" 189 | export NAGIOS_TOTALSERVICESUNKNOWNUNHANDLED="" 190 | export NAGIOS_TOTALSERVICESWARNING="" 191 | export NAGIOS_TOTALSERVICESWARNINGUNHANDLED="" 192 | -------------------------------------------------------------------------------- /test/service.env: -------------------------------------------------------------------------------- 1 | export NAGIOS_ADMINEMAIL="admin@example.com" 2 | export NAGIOS_ADMINPAGER="admin@example.com" 3 | export NAGIOS_ARG1="" 4 | export NAGIOS_ARG10="" 5 | export NAGIOS_ARG11="" 6 | export NAGIOS_ARG12="" 7 | export NAGIOS_ARG13="" 8 | export NAGIOS_ARG14="" 9 | export NAGIOS_ARG15="" 10 | export NAGIOS_ARG16="" 11 | export NAGIOS_ARG17="" 12 | export NAGIOS_ARG18="" 13 | export NAGIOS_ARG19="" 14 | export NAGIOS_ARG2="" 15 | export NAGIOS_ARG20="" 16 | export NAGIOS_ARG21="" 17 | export NAGIOS_ARG22="" 18 | export NAGIOS_ARG23="" 19 | export NAGIOS_ARG24="" 20 | export NAGIOS_ARG25="" 21 | export NAGIOS_ARG26="" 22 | export NAGIOS_ARG27="" 23 | export NAGIOS_ARG28="" 24 | export NAGIOS_ARG29="" 25 | export NAGIOS_ARG3="" 26 | export NAGIOS_ARG30="" 27 | export NAGIOS_ARG31="" 28 | export NAGIOS_ARG32="" 29 | export NAGIOS_ARG4="" 30 | export NAGIOS_ARG5="" 31 | export NAGIOS_ARG6="" 32 | export NAGIOS_ARG7="" 33 | export NAGIOS_ARG8="" 34 | export NAGIOS_ARG9="" 35 | export NAGIOS_COMMANDFILE="/tmp/nagios/rw/nagios.cmd" 36 | export NAGIOS_CONTACTADDRESS0="" 37 | export NAGIOS_CONTACTADDRESS1="" 38 | export NAGIOS_CONTACTADDRESS2="" 39 | export NAGIOS_CONTACTADDRESS3="" 40 | export NAGIOS_CONTACTADDRESS4="" 41 | export NAGIOS_CONTACTADDRESS5="" 42 | export NAGIOS_CONTACTALIAS="Nagios" 43 | export NAGIOS_CONTACTEMAIL="nagios@example.com" 44 | export NAGIOS_CONTACTGROUPALIAS="Nagios Admins" 45 | export NAGIOS_CONTACTGROUPMEMBERS="nagios" 46 | export NAGIOS_CONTACTGROUPNAME="admins" 47 | export NAGIOS_CONTACTGROUPNAMES="admins" 48 | export NAGIOS_CONTACTNAME="nagios" 49 | export NAGIOS_CONTACTPAGER="" 50 | export NAGIOS_DATE="02-20-2014" 51 | export NAGIOS_EVENTSTARTTIME="1392850569" 52 | export NAGIOS_HOSTACKAUTHOR="" 53 | export NAGIOS_HOSTACKAUTHORALIAS="" 54 | export NAGIOS_HOSTACKAUTHORNAME="" 55 | export NAGIOS_HOSTACKCOMMENT="" 56 | export NAGIOS_HOSTACTIONURL="" 57 | export NAGIOS_HOSTADDRESS="192.168.1.3" 58 | export NAGIOS_HOSTALIAS="prod-box-2.voxer.com" 59 | export NAGIOS_HOSTATTEMPT="1" 60 | export NAGIOS_HOSTCHECKCOMMAND="check-host-alive" 61 | export NAGIOS_HOSTCHECKTYPE="ACTIVE" 62 | export NAGIOS_HOSTDISPLAYNAME="prod-box-2.voxer.com" 63 | export NAGIOS_HOSTDOWNTIME="0" 64 | export NAGIOS_HOSTDURATION="10d 5h 31m 43s" 65 | export NAGIOS_HOSTDURATIONSEC="883903" 66 | export NAGIOS_HOSTEVENTID="7121" 67 | export NAGIOS_HOSTEXECUTIONTIME="0.032" 68 | export NAGIOS_HOSTGROUPACTIONURL="" 69 | export NAGIOS_HOSTGROUPALIAS="All Servers" 70 | export NAGIOS_HOSTGROUPMEMBERS="prod-box-1.voxer.com,prod-box-2.voxer.com" 71 | export NAGIOS_HOSTGROUPNAME="server" 72 | export NAGIOS_HOSTGROUPNAMES="server,riak-media,riak,prod,base" 73 | export NAGIOS_HOSTGROUPNOTES="" 74 | export NAGIOS_HOSTGROUPNOTESURL="" 75 | export NAGIOS_HOSTLATENCY="0.566" 76 | export NAGIOS_HOSTNAME="prod-box-2.voxer.com" 77 | export NAGIOS_HOSTNOTES="" 78 | export NAGIOS_HOSTNOTESURL="" 79 | export NAGIOS_HOSTNOTIFICATIONID="1903" 80 | export NAGIOS_HOSTNOTIFICATIONNUMBER="0" 81 | export NAGIOS_HOSTOUTPUT="PING OK - Packet loss = 0%, RTA = 0.23 ms" 82 | export NAGIOS_HOSTPERCENTCHANGE="0.00" 83 | export NAGIOS_HOSTPERFDATA="rta=0.228000ms;3000.000000;5000.000000;0.000000 pl=0%;80;100;0" 84 | export NAGIOS_HOSTPERFDATAFILE="" 85 | export NAGIOS_HOSTPROBLEMID="0" 86 | export NAGIOS_HOSTSTATE="UP" 87 | export NAGIOS_HOSTSTATEID="0" 88 | export NAGIOS_HOSTSTATETYPE="HARD" 89 | export NAGIOS_ISVALIDTIME="" 90 | export NAGIOS_LASTHOSTCHECK="1392926249" 91 | export NAGIOS_LASTHOSTDOWN="1392042236" 92 | export NAGIOS_LASTHOSTEVENTID="7119" 93 | export NAGIOS_LASTHOSTPROBLEMID="3548" 94 | export NAGIOS_LASTHOSTSTATE="UP" 95 | export NAGIOS_LASTHOSTSTATECHANGE="1392042546" 96 | export NAGIOS_LASTHOSTSTATEID="0" 97 | export NAGIOS_LASTHOSTUNREACHABLE="0" 98 | export NAGIOS_LASTHOSTUP="1392926259" 99 | export NAGIOS_LASTSERVICECHECK="1392926443" 100 | export NAGIOS_LASTSERVICECRITICAL="1392926143" 101 | export NAGIOS_LASTSERVICEEVENTID="11822" 102 | export NAGIOS_LASTSERVICEOK="1392926443" 103 | export NAGIOS_LASTSERVICEPROBLEMID="6003" 104 | export NAGIOS_LASTSERVICESTATE="CRITICAL" 105 | export NAGIOS_LASTSERVICESTATECHANGE="1392926443" 106 | export NAGIOS_LASTSERVICESTATEID="2" 107 | export NAGIOS_LASTSERVICEUNKNOWN="0" 108 | export NAGIOS_LASTSERVICEWARNING="0" 109 | export NAGIOS_LOGFILE="/tmp/nagios/nagios.log" 110 | export NAGIOS_LONGDATETIME="Thu Feb 20 20:00:49 UTC 2014" 111 | export NAGIOS_LONGHOSTOUTPUT="" 112 | export NAGIOS_LONGSERVICEOUTPUT="" 113 | export NAGIOS_MAINCONFIGFILE="/opt/local/etc/nagios/nagios.cfg" 114 | export NAGIOS_MAXHOSTATTEMPTS="3" 115 | export NAGIOS_MAXSERVICEATTEMPTS="2" 116 | export NAGIOS_NEXTVALIDTIME="" 117 | export NAGIOS_NOTIFICATIONAUTHOR="" 118 | export NAGIOS_NOTIFICATIONAUTHORALIAS="" 119 | export NAGIOS_NOTIFICATIONAUTHORNAME="" 120 | export NAGIOS_NOTIFICATIONCOMMENT="" 121 | export NAGIOS_NOTIFICATIONISESCALATED="0" 122 | export NAGIOS_NOTIFICATIONNUMBER="2" 123 | export NAGIOS_NOTIFICATIONRECIPIENTS="nagios" 124 | export NAGIOS_NOTIFICATIONTYPE="RECOVERY" 125 | export NAGIOS_OBJECTCACHEFILE="/tmp/nagios/objects.cache" 126 | export NAGIOS_PROCESSSTARTTIME="1392850560" 127 | export NAGIOS_RESOURCEFILE="/opt/local/etc/nagios/resource.cfg" 128 | export NAGIOS_RETENTIONDATAFILE="/tmp/nagios/retention.dat" 129 | export NAGIOS_SERVICEACKAUTHOR="" 130 | export NAGIOS_SERVICEACKAUTHORALIAS="" 131 | export NAGIOS_SERVICEACKAUTHORNAME="" 132 | export NAGIOS_SERVICEACKCOMMENT="" 133 | export NAGIOS_SERVICEACTIONURL="" 134 | export NAGIOS_SERVICEATTEMPT="2" 135 | export NAGIOS_SERVICECHECKCOMMAND="check_http!-I \$HOSTADDRESS\$ -p 8098 -u /ping -s OK" 136 | export NAGIOS_SERVICECHECKTYPE="ACTIVE" 137 | export NAGIOS_SERVICEDESC="Riak HTTP GET /ping" 138 | export NAGIOS_SERVICEDISPLAYNAME="Riak HTTP GET /ping" 139 | export NAGIOS_SERVICEDOWNTIME="0" 140 | export NAGIOS_SERVICEDURATION="0d 0h 0m 6s" 141 | export NAGIOS_SERVICEDURATIONSEC="6" 142 | export NAGIOS_SERVICEEVENTID="16753" 143 | export NAGIOS_SERVICEEXECUTIONTIME="0.032" 144 | export NAGIOS_SERVICEGROUPACTIONURL="" 145 | export NAGIOS_SERVICEGROUPALIAS="Riak Services" 146 | export NAGIOS_SERVICEGROUPMEMBERS="prod-box-1.voxer.com,Riak Compaction Errors,prod-box-1.voxer.com,Riak HTTP GET /ping,prod-box-1.voxer.com,Riak Singleton" 147 | export NAGIOS_SERVICEGROUPNAME="riak" 148 | export NAGIOS_SERVICEGROUPNAMES="riak" 149 | export NAGIOS_SERVICEGROUPNOTES="" 150 | export NAGIOS_SERVICEGROUPNOTESURL="" 151 | export NAGIOS_SERVICEISVOLATILE="0" 152 | export NAGIOS_SERVICELATENCY="0.267" 153 | export NAGIOS_SERVICENOTES="" 154 | export NAGIOS_SERVICENOTESURL="" 155 | export NAGIOS_SERVICENOTIFICATIONID="2211" 156 | export NAGIOS_SERVICENOTIFICATIONNUMBER="2" 157 | export NAGIOS_SERVICEOUTPUT="HTTP OK: HTTP/1.0 200 OK - 171 bytes in 0.002 second response time" 158 | export NAGIOS_SERVICEPERCENTCHANGE="6.25" 159 | export NAGIOS_SERVICEPERFDATA="time=0.001979s;;;0.000000 size=171B;;;0" 160 | export NAGIOS_SERVICEPERFDATAFILE="" 161 | export NAGIOS_SERVICEPROBLEMID="0" 162 | export NAGIOS_SERVICESTATE="OK" 163 | export NAGIOS_SERVICESTATEID="0" 164 | export NAGIOS_SERVICESTATETYPE="HARD" 165 | export NAGIOS_SHORTDATETIME="02-20-2014 20:00:49" 166 | export NAGIOS_STATUSDATAFILE="/tmp/nagios/status.dat" 167 | export NAGIOS_TEMPFILE="/tmp/nagios.tmp" 168 | export NAGIOS_TEMPPATH="/tmp" 169 | export NAGIOS_TIME="20:00:49" 170 | export NAGIOS_TIMET="1392926449" 171 | export NAGIOS_TOTALHOSTPROBLEMS="" 172 | export NAGIOS_TOTALHOSTPROBLEMSUNHANDLED="" 173 | export NAGIOS_TOTALHOSTSDOWN="" 174 | export NAGIOS_TOTALHOSTSDOWNUNHANDLED="" 175 | export NAGIOS_TOTALHOSTSERVICES="16" 176 | export NAGIOS_TOTALHOSTSERVICESCRITICAL="0" 177 | export NAGIOS_TOTALHOSTSERVICESOK="14" 178 | export NAGIOS_TOTALHOSTSERVICESUNKNOWN="2" 179 | export NAGIOS_TOTALHOSTSERVICESWARNING="0" 180 | export NAGIOS_TOTALHOSTSUNREACHABLE="" 181 | export NAGIOS_TOTALHOSTSUNREACHABLEUNHANDLED="" 182 | export NAGIOS_TOTALHOSTSUP="" 183 | export NAGIOS_TOTALSERVICEPROBLEMS="" 184 | export NAGIOS_TOTALSERVICEPROBLEMSUNHANDLED="" 185 | export NAGIOS_TOTALSERVICESCRITICAL="" 186 | export NAGIOS_TOTALSERVICESCRITICALUNHANDLED="" 187 | export NAGIOS_TOTALSERVICESOK="" 188 | export NAGIOS_TOTALSERVICESUNKNOWN="" 189 | export NAGIOS_TOTALSERVICESUNKNOWNUNHANDLED="" 190 | export NAGIOS_TOTALSERVICESWARNING="" 191 | export NAGIOS_TOTALSERVICESWARNINGUNHANDLED="" 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Nagios HTML Email Template 2 | -------------------------- 3 | 4 | Generate HTML emails for Nagios service and host alerts 5 | 6 | - [Quick Start Guide](#quick-start-guide) 7 | - [Screenshots](#screenshots) 8 | - [Advanced Usage](#advanced-usage) 9 | - [Custom Subject](#custom-subject) 10 | - [Alleviation Steps](#alleviation-steps) 11 | - [Custom Templates](#custom-templates) 12 | - [Rendering](#rendering) 13 | - [Testing](#testing) 14 | - [Common Problems](#common-problems) 15 | - [License](#license) 16 | 17 | Quick Start Guide 18 | ----------------- 19 | 20 | Install this package on your nagios server 21 | 22 | [sudo] npm install -g nagios-html-email 23 | 24 | And modify `commands.cfg` (or similar) to use this program 25 | 26 | ``` bash 27 | define command { 28 | command_name notify-service-by-email 29 | command_line nagios-html-email service http://nagios.example.com | mailx -t 30 | } 31 | define command { 32 | command_name notify-host-by-email 33 | command_line nagios-html-email host http://nagios.example.com | mailx -t 34 | } 35 | ``` 36 | 37 | The second argument of `http://nagios.example.com` is optional, and if supplied, should be 38 | the base URI of your Nagios instance. If present, it will result 39 | in extra links in the email generated like like "acknowledge alert", "view all 40 | alerts", etc. 41 | 42 | Restart Nagios, and you should get fancy HTML email alerts. If something 43 | doesn't work, check the [Common Problems](#common-problems) section below for 44 | possible solutions. The most common problem is `nagios-html-email` isn't in the 45 | PATH of the Nagios server. 46 | 47 | Screenshots 48 | ----------- 49 | 50 | A critical service 51 | 52 |

Critical Service

53 | 54 | The service recovery, threaded because the subject is the same 55 | 56 |

Service Recovery Threaded

57 | 58 | Host recovery 59 | 60 |

Host Recovery

61 | 62 | Advanced Usage 63 | -------------- 64 | 65 | Note that these tips are only useful if you use the builtin templates supplied 66 | by this program, or use the variables that the builtin templates use. 67 | 68 | ### Custom Subject 69 | 70 | A custom subject can be set by setting a `_subject` attribute on the host 71 | or service that is generating the alert, for example: 72 | 73 | ``` bash 74 | define service { 75 | use generic-service 76 | hostgroup_name server 77 | service_description SSH 78 | check_command check_ssh 79 | _subject ssh 80 | } 81 | ``` 82 | 83 | Now, whenever the `check_ssh` service generates an alert, it will be sent with 84 | the subject of simply `ssh`, regardless of notification type or service state. 85 | This is convenient for threaded email clients (like gmail), as all emails 86 | about the `check_ssh` service will be grouped in the same thread. 87 | 88 | ``` bash 89 | define host { 90 | host_name prod-box-1.voxer.com 91 | use generic-host 92 | hostgroups server 93 | _subject prod box 1 94 | } 95 | ``` 96 | 97 | Same as above, except for a host notification for `prod-box-1.voxer.com`. 98 | Whenever this host generates a notification, it will be sent with the simple 99 | subject of `prod box 1`. 100 | 101 | At Voxer, we use the `_subject` attribute of services and not hosts. 102 | 103 | ### Alleviation Steps 104 | 105 | At Voxer, we use Chef to manage our Nagios instance, and as such, programatically 106 | generate Nagios services for each production service we have. All of our production 107 | services are uniquely named like fooservice1, fooservice2, fooservice3, etc. regardless of 108 | the host that runs the service, so a separate Nagios service must be created for each 109 | production service. 110 | 111 | One of the things we check is memory usage on a per process basis. Every node process 112 | running in production is set to warn us when it passes a certain threshold of RSS on the box, 113 | and under typical circumstances we just get a core dump of the process, and restart it. 114 | 115 | After we have a couple core dumps, it becomes unecassary to waste time dumping core, 116 | so we just restart the troubled programs before they become a issue. 117 | 118 | Since the "alleviation" steps are pretty much the same for each service, but we don't 119 | want this to happen automatically (imagine if every service restarted at the same time... 120 | that would be bad), we just add an `_alleviate` attribute to each service, that the 121 | builtin template knows how to render. For example: 122 | 123 | ``` bash 124 | define service { 125 | use generic-service 126 | host_name prod-box-1 127 | service_description fooservice1 RSS 128 | check_command check_voxer_rss!fooservice1 129 | _subject fooservice 130 | _alleviate ssh prod-box-1 sudo svcadm -v restart fooservice1 131 | } 132 | ``` 133 | 134 | Now, whenever an email is generated for the service when it is not `OK`, extra 135 | lines will be added that look like: 136 | 137 | ``` 138 | the following steps may possibly alleviate the issue 139 | 140 | ssh prod-box-1 sudo svcadm -v restart fooservice1 141 | ``` 142 | 143 | However, it is still up to the recipient of this alert to determine if this is the 144 | best course of action. 145 | 146 | Custom Templates 147 | ---------------- 148 | 149 | By default, this program will use builtin templates for host and service 150 | alerts. You can use your own templates by supplying `-t ` to point to a 151 | directory with your templates. 152 | 153 | See [templates/](templates) to see the builtin templates. 154 | 155 | ### Rendering 156 | 157 | Templates are rendered using [EJS](https://github.com/visionmedia/ejs), and 158 | have these variables available for you to use. 159 | 160 | - `nagios`: this object contains all of the Nagios variables found as 161 | environmental variables. For example, `nagios.CONTACTEMAIL`, 162 | `nagios.HOSTSTATE`, etc. Any variable you could access as a macro like 163 | `$MACRONAME$` will be avaliable as `nagios.MACRONAME`. 164 | - `args`: this array contains all of the command line arguments after the type 165 | argument. For instance, if the program is invoked as `nagios-html-email -t 166 | /etc/templates -s subject service foo bar baz` the array will be set to 167 | `['foo', 'bar', 'baz']`. 168 | - `package`: `package.json` from this module as an object; this can be used 169 | to get information like `package.version`, etc. 170 | 171 | A custom template dir, if you supply one, should contain at least a 172 | `host.html.ejs` and `service.html.ejs` file for host and service alerts 173 | respectively. 174 | 175 | ### Testing 176 | 177 | To test out custom templates, it's easiest to clone this repo and use the 178 | the example environmental variables for a fake Nagios alert. 179 | 180 | First 181 | 182 | git clone git://github.com/Voxer/nagios-html-email.git 183 | cd nagios-html-email 184 | npm install 185 | 186 | Next, edit the templates 187 | 188 | $ vim templates/*.html.ejs 189 | ... edit edit edit ... 190 | :wq 191 | 192 | Then, run `make` to generate test templates 193 | 194 | $ make 195 | . test/service.env && ./nagios-html-email.js service | awk 'NR > 5' > service.html 196 | . test/host.env && ./nagios-html-email.js host | awk 'NR > 5' > host.html 197 | $ ls *.html 198 | host.html service.html 199 | 200 | Now you can open both HTML files to see what the templates looks like when they are rendered 201 | 202 | open *.html 203 | 204 | Or, if you prefer, you can do this manually with the following 205 | 206 | . test/service.env 207 | ./nagios-html-email.js service > service.html 208 | open service.html || xdg-open service.html 209 | 210 | Repeat the edit and testing steps until your templates look good, and then you can 211 | call the globally installed `nagios-html-email` program with `-t /path/to/your/templates` 212 | to use your newly created templates. 213 | 214 | Common Problems 215 | --------------- 216 | 217 | ### No emails are being generated 218 | 219 | Most likely, the path with `nagios-html-email` in it is not in the `PATH` 220 | variable for the Nagios server. Ensure the path given by `which 221 | nagios-html-email` is in the PATH of the Nagios server. 222 | 223 | ### I'm getting emailed, but it is a JSON stringified version of the Nagios variables 224 | 225 | This means that a template failed to render. Instead of failing 226 | to send an email, this program will do everything it can to make sure you 227 | get an email, even if it isn't pretty. 228 | 229 | ### I'm trying to do numerical analysis on values but it isn't working 230 | 231 | Since variables are passed as either command line arguments or 232 | environmental variables, all variables are of type `String`. You 233 | must expliticly cast any values you know to be numbers, booleans, 234 | dates, etc. to their correct data type. 235 | 236 | ### I've disabled environmental variables for performance reasons 237 | 238 | You can still use this program, just pass the variables you would like to 239 | use as command line arguments, and access them in your template as 240 | `args[0]`, `args[1]`, etc. For example: 241 | 242 | 243 | ``` bash 244 | define command { 245 | command_name notify-service-by-email 246 | command_line nagios-html-email -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" -a $CONTACTEMAIL$ service | mailx -t 247 | } 248 | ``` 249 | 250 | However, from experience, passing environmental variables won't cause too much 251 | of a performance penality. I'd recommend turning it on for a bit to see how it 252 | affects your latency before turning off such an amazing feature. 253 | 254 | License 255 | ------- 256 | 257 | MIT 258 | --------------------------------------------------------------------------------