@cryptotaxi247 / netdata-1 / commits / 73752d984

pass additional arguments to alarm URLs; optimizations in alarm-notify.sh

Costa Tsaousis (ktsaou) committed Sep 11, 2016 at 14:42 UTC 73752d98410a5bc35238e1cb392e47182fa61b16
3 files changed +92 -40
plugins.d/alarm-notify.sh
+55 -31
@@ -5,11 +5,22 @@
5
6 me="${0}"
7
8 +if [ $(( ${BASH_VERSINFO[0]} )) -lt 4 ]
9 +then
10 + echo >&2
11 + echo >&2 "$me: ERROR"
12 + echo >&2 "BASH version 4 or later is required."
13 + echo >&2 "You are running version: ${BASH_VERSION}"
14 + echo >&2 "Please upgrade."
15 + echo >&2
16 + exit 1
17 +fi
18 +
19 # -----------------------------------------------------------------------------
20 # parse command line parameters
21
22 recipient="${1}" # the recepient of the email
12 -hostname="${2}" # the hostname this event refers to
23 +host="${2}" # the host this event refers to
24 unique_id="${3}" # the unique id of this event
25 alarm_id="${4}" # the unique id of the alarm that generated this event
26 event_id="${5}" # the incremental id of the event, for this alarm
@@ -17,8 +28,8 @@ when="${6}" # the timestamp this event occured
28 name="${7}" # the name of the alarm, as given in netdata health.d entries
29 chart="${8}" # the name of the chart (type.id)
30 family="${9}" # the family of the chart
20 -status="${10}" # the current status : UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
21 -old_status="${11}" # the previous status: UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
31 +status="${10}" # the current status : REMOVED, UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
32 +old_status="${11}" # the previous status: REMOVED, UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
33 value="${12}" # the current value
34 old_value="${13}" # the previous value
35 src="${14}" # the line number and file the alarm has been configured
@@ -79,7 +90,7 @@ if [ -f "${NETDATA_CONFIG_DIR}/health_alarm_notify.conf" ]
90 fi
91
92 # -----------------------------------------------------------------------------
82 -# find the exact recipient per method
93 +# find the recipient's addresses per method
94
95 declare -A arr_slack=()
96 declare -A arr_pushover=()
@@ -87,7 +98,7 @@ declare -A arr_email=()
98
99 # netdata may call us with multiple recipients
100 # so, here we find the unique ones
90 -for x in ${recipient}
101 +for x in ${recipient//,/ }
102 do
103 # email
104 a="${role_recipients_email[${recipient}]}"
@@ -158,9 +169,9 @@ fi
169 # -----------------------------------------------------------------------------
170 # get the system hostname
171
161 -[ -z "${hostname}" ] && hostname="${NETDATA_HOSTNAME}"
162 -[ -z "${hostname}" ] && hostname="${NETDATA_REGISTRY_HOSTNAME}"
163 -[ -z "${hostname}" ] && hostname="$(hostname 2>/dev/null)"
172 +[ -z "${host}" ] && host="${NETDATA_HOSTNAME}"
173 +[ -z "${host}" ] && host="${NETDATA_REGISTRY_HOSTNAME}"
174 +[ -z "${host}" ] && host="$(hostname 2>/dev/null)"
175
176 # -----------------------------------------------------------------------------
177 # get the date the alarm happened
@@ -189,7 +200,9 @@ urlencode() {
200 esac
201 encoded+="${o}"
202 done
192 - echo "${encoded}"
203 +
204 + REPLY="${encoded}"
205 + echo "${REPLY}"
206 }
207
208 # -----------------------------------------------------------------------------
@@ -197,7 +210,7 @@ urlencode() {
210 # using DAYS, MINUTES, SECONDS
211
212 duration4human() {
200 - local s="${1}" d=0 h=0 m=0 ds="day" hs="hour" ms="minute" ss="second"
213 + local s="${1}" d=0 h=0 m=0 ds="day" hs="hour" ms="minute" ss="second" ret
214 d=$(( s / 86400 ))
215 s=$(( s - (d * 86400) ))
216 h=$(( s / 3600 ))
@@ -212,9 +225,9 @@ duration4human() {
225 [ ${h} -gt 1 ] && hs="hours"
226 if [ ${h} -gt 0 ]
227 then
215 - echo "${d} ${ds} and ${h} ${hs}"
228 + ret="${d} ${ds} and ${h} ${hs}"
229 else
217 - echo "${d} ${ds}"
230 + ret="${d} ${ds}"
231 fi
232 elif [ ${h} -gt 0 ]
233 then
@@ -223,9 +236,9 @@ duration4human() {
236 [ ${m} -gt 1 ] && ms="minutes"
237 if [ ${m} -gt 0 ]
238 then
226 - echo "${h} ${hs} and ${m} ${ms}"
239 + ret="${h} ${hs} and ${m} ${ms}"
240 else
228 - echo "${h} ${hs}"
241 + ret="${h} ${hs}"
242 fi
243 elif [ ${m} -gt 0 ]
244 then
@@ -233,31 +246,36 @@ duration4human() {
246 [ ${s} -gt 1 ] && ss="seconds"
247 if [ ${s} -gt 0 ]
248 then
236 - echo "${m} ${ms} and ${s} ${ss}"
249 + ret="${m} ${ms} and ${s} ${ss}"
250 else
238 - echo "${m} ${ms}"
251 + ret="${m} ${ms}"
252 fi
253 else
254 [ ${s} -gt 1 ] && ss="seconds"
242 - echo "${s} ${ss}"
255 + ret="${s} ${ss}"
256 fi
257 +
258 + REPLY="${ret}"
259 + echo "${REPLY}"
260 }
261
262 # -----------------------------------------------------------------------------
263 # email sender
264
265 send_email() {
266 + local ret=
267 if [ "${SEND_EMAIL}" = "YES" ]
268 then
269
270 "${sendmail}" -t
271 + ret=$?
272
255 - if [ $? -eq 0 ]
273 + if [ $ret -eq 0 ]
274 then
257 - echo >&2 "${me}: Sent notification email for ${status} on '${chart}.${name}' to '${to_email}'"
275 + echo >&2 "${me}: Sent email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}'"
276 return 0
277 else
260 - echo >&2 "${me}: FAILED to send notification email for ${status} on '${chart}.${name}' to '${to_email}'"
278 + echo >&2 "${me}: Failed to send email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}' with error code ${ret}."
279 return 1
280 fi
281 fi
@@ -325,7 +343,7 @@ send_slack() {
343 for channel in ${channels}
344 do
345 httpcode=$(${curl} --write-out %{http_code} --silent --output /dev/null -X POST --data-urlencode \
328 - "payload={\"channel\": \"#${channel}\", \"username\": \"${username}\", \"text\": \"${hostname} ${status_message} - ${author} ${raised_for} - click <${goto_url}|here> to view the netdata dashboard.\", \"icon_url\": \"${image}\", \"attachments\": [{\"fallback\": \"${alarm} - ${info}\", \"color\": \"${color}\", \"title\": \"${alarm}\", \"title_link\": \"${goto_url}\", \"text\": \"${info}\", \"footer\": \"netdata\", \"footer_icon\": \"${NETDATA_REGISTRY_URL}/images/seo-performance-128.png\", \"ts\": ${when}}]}" \
346 + "payload={\"channel\": \"#${channel}\", \"username\": \"${username}\", \"text\": \"${host} ${status_message} - ${author} ${raised_for} - click <${goto_url}|here> to view the netdata dashboard.\", \"icon_url\": \"${image}\", \"attachments\": [{\"fallback\": \"${alarm} - ${info}\", \"color\": \"${color}\", \"title\": \"${alarm}\", \"title_link\": \"${goto_url}\", \"text\": \"${info}\", \"footer\": \"netdata\", \"footer_icon\": \"${NETDATA_REGISTRY_URL}/images/seo-performance-128.png\", \"ts\": ${when}}]}" \
347 "${webhook}")
348
349 if [ "${httpcode}" == "200" ]
@@ -348,13 +366,19 @@ send_slack() {
366 # prepare the content of the notification
367
368 # the url to send the user on click
351 -goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?host=$(urlencode "${NETDATA_REGISTRY_HOSTNAME}")&chart=${chart}&family=${family}"
369 +urlencode "${NETDATA_REGISTRY_HOSTNAME}" >/dev/null; url_host="${REPLY}"
370 +urlencode "${chart}" >/dev/null; url_chart="${REPLY}"
371 +urlencode "${family}" >/dev/null; url_family="${REPLY}"
372 +urlencode "${name}" >/dev/null; url_name="${REPLY}"
373 +goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?host=${url_host}&chart=${url_chart}&family=${url_family}&alarm=${url_name}&alarm_unique_id=${unique_id}&alarm_id=${alarm_id}&alarm_event_id=${event_id}"
374
375 # the severity of the alarm
376 severity="${status}"
377
378 # the time the alarm was raised
357 -raised_for="(was ${old_status,,} for $(duration4human ${duration}))"
379 +duration4human ${duration} >/dev/null; duration_txt="${REPLY}"
380 +duration4human ${non_clear_duration} >/dev/null; non_clear_duration_txt="${REPLY}"
381 +raised_for="(was ${old_status,,} for ${duration_txt}"
382
383 # the key status message
384 status_message="status unknown"
@@ -398,7 +422,7 @@ then
422 severity="Recovered from ${old_status}"
423 if [ $non_clear_duration -gt $duration ]
424 then
401 - raised_for="(had issues for $(duration4human ${non_clear_duration}))"
425 + raised_for="(alarm was raised for ${non_clear_duration_txt})"
426 fi
427
428 elif [ "${old_status}" = "WARNING" -a "${status}" = "CRITICAL" ]
@@ -406,7 +430,7 @@ then
430 severity="Escalated to ${status}"
431 if [ $non_clear_duration -gt $duration ]
432 then
409 - raised_for="(has issues for $(duration4human ${non_clear_duration}))"
433 + raised_for="(alarm is raised for ${non_clear_duration_txt})"
434 fi
435
436 elif [ "${old_status}" = "CRITICAL" -a "${status}" = "WARNING" ]
@@ -414,7 +438,7 @@ then
438 severity="Demoted to ${status}"
439 if [ $non_clear_duration -gt $duration ]
440 then
417 - raised_for="(has issues for $(duration4human ${non_clear_duration}))"
441 + raised_for="(alarm is raised for ${non_clear_duration_txt})"
442 fi
443
444 else
@@ -432,15 +456,15 @@ raised_for_html=
456 # send the slack notification
457
458 # slack aggregates posts from the same username
435 -# so we use "${hostname} ${status}" as the bot username, to make them diff
459 +# so we use "${host} ${status}" as the bot username, to make them diff
460
437 -send_slack "${SLACK_WEBHOOK_URL}" "${to_slack}" "${when}" "${hostname} ${status}" "${image}" "${chart} (${family})"
461 +send_slack "${SLACK_WEBHOOK_URL}" "${to_slack}" "${when}" "${host} ${status}" "${image}" "${chart} (${family})"
462 SENT_SLACK=$?
463
464 # -----------------------------------------------------------------------------
465 # send the pushover notification
466
443 -send_pushover "${PUSHOVER_APP_TOKEN}" "${to_pushover}" "${when}" "${goto_url}" "${status}" "${hostname} ${status_message} - ${name//_/ } - ${chart}" "
467 +send_pushover "${PUSHOVER_APP_TOKEN}" "${to_pushover}" "${when}" "${goto_url}" "${status}" "${host} ${status_message} - ${name//_/ } - ${chart}" "
468 <font color=\"${color}\"><b>${alarm}</b></font>${info_html}<br/>&nbsp;
469 <small><b>${chart}</b><br/>Chart<br/>&nbsp;</small>
470 <small><b>${family}</b><br/>Family<br/>&nbsp;</small>
@@ -457,7 +481,7 @@ SENT_PUSHOVER=$?
481
482 send_email <<EOF
483 To: ${to_email}
460 -Subject: ${hostname} ${status_message} - ${name//_/ } - ${chart}
484 +Subject: ${host} ${status_message} - ${name//_/ } - ${chart}
485 Content-Type: text/html
486
487 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -478,7 +502,7 @@ Content-Type: text/html
502 </tr>
503 <tr>
504 <td bgcolor="${color}" style="font-size: 16px; vertical-align: top; font-weight: 400; text-align: center; margin: 0; padding: 10px; color: #ffffff; background: ${color} !important; border: 1px solid ${color}; border-top-color: ${color};" align="center" valign="top">
481 - <h1 style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0;">${hostname} ${status_message}</h1>
505 + <h1 style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0;">${host} ${status_message}</h1>
506 </td>
507 </tr>
508 <tr>
web/goto-host-from-alarm.html
+14 -1
@@ -23,6 +23,10 @@
23 host: null,
24 chart: null,
25 family: null,
26 + alarm: null,
27 + alarm_unique_id: 0,
28 + alarm_id: 0,
29 + alarm_event_id: 0,
30 hasProperty: function(property) {
31 return typeof this[property] !== 'undefined';
32 }
@@ -40,7 +44,16 @@
44 }
45
46 function netdataURL(url) {
43 - return url + '#top;show_alarms=true;chart=' + urlOptions.chart + ';family=' + urlOptions.family;
47 + return url + '#top'
48 + + ';nowelcome=1'
49 + + ';show_alarms=1'
50 + + ';chart=' + urlOptions.chart.toString()
51 + + ';family=' + urlOptions.family.toString()
52 + + ';alarm=' + urlOptions.alarm.toString()
53 + + ';alarm_unique_id=' + urlOptions.alarm_unique_id.toString()
54 + + ';alarm_id=' + urlOptions.alarm_id.toString()
55 + + ';alarm_event_id=' + urlOptions.alarm_event_id.toString()
56 + ;
57 }
58
59 var gotoServerValidateRemaining = 0;
web/index.html
+23 -8
@@ -408,10 +408,14 @@
408 pan_and_zoom: false,
409 after: 0,
410 before: 0,
411 - nowelcome: 0,
412 - show_alarms: 0,
411 + nowelcome: false,
412 + show_alarms: false,
413 chart: null,
414 family: null,
415 + alarm: null,
416 + alarm_unique_id: 0,
417 + alarm_id: 0,
418 + alarm_event_id: 0,
419 hasProperty: function(property) {
420 // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
421 return typeof this[property] !== 'undefined';
@@ -461,8 +465,21 @@
465 }
466 }
467
464 - if(urlOptions.before > 0 && urlOptions.after > 0)
468 + var booleans = [ 'nowelcome', 'show_alarms', 'pan_and_zoom' ];
469 + len = booleans.length;
470 + while(len--) {
471 + if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1)
472 + urlOptions[booleans[len]] = true;
473 + else
474 + urlOptions[booleans[len]] = false;
475 + }
476 +
477 + if(urlOptions.before > 0 && urlOptions.after > 0) {
478 urlOptions.pan_and_zoom = true;
479 + urlOptions.nowelcome = true;
480 + }
481 + else
482 + urlOptions.pan_and_zoom = false;
483
484 // console.log(urlOptions);
485 }
@@ -3030,10 +3047,8 @@ function finalizePage() {
3047 // the Dom elements are initially zero-sized
3048 NETDATA.parseDom();
3049
3033 - if(urlOptions.pan_and_zoom === true) {
3034 - urlOptions.nowelcome = true;
3050 + if(urlOptions.pan_and_zoom === true)
3051 NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
3036 - }
3052
3053 // ------------------------------------------------------------------------
3054 // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
@@ -3299,7 +3314,7 @@ function finalizePage() {
3314 });
3315
3316 if(isdemo()) {
3302 - if(!urlOptions.nowelcome) {
3317 + if(urlOptions.nowelcome !== true) {
3318 setTimeout(function() {
3319 $('#welcomeModal').modal();
3320 }, 1000);
@@ -3319,7 +3334,7 @@ function finalizePage() {
3334 }
3335 else notifyForUpdate();
3336
3322 - if(urlOptions.show_alarms === 'true')
3337 + if(urlOptions.show_alarms === true)
3338 setTimeout(function() { $('#alarmsModal').modal('show'); }, 1000);
3339 }
3340