@cryptotaxi247 / netdata-1 / commits / fda93c778

Page duty V2 (#10189)

Add Pagerduty V2 to Netdata.

thiagoftsm committed Nov 6, 2020 at 11:12 UTC fda93c7783f7c5280090ba1bcefa40df328615ae
3 files changed +1298 -1243
health/notifications/alarm-notify.sh.in
+1291 -1243
@@ -43,35 +43,35 @@
43 # testing notifications
44
45 if { [ "${1}" = "test" ] || [ "${2}" = "test" ]; } && [ "${#}" -le 2 ]; then
46 - if [ "${2}" = "test" ]; then
47 - recipient="${1}"
48 - else
49 - recipient="${2}"
50 - fi
51 -
52 - [ -z "${recipient}" ] && recipient="sysadmin"
53 -
54 - id=1
55 - last="CLEAR"
56 - test_res=0
57 - for x in "WARNING" "CRITICAL" "CLEAR"; do
58 - echo >&2
59 - echo >&2 "# SENDING TEST ${x} ALARM TO ROLE: ${recipient}"
60 -
61 - "${0}" "${recipient}" "$(hostname)" 1 1 "${id}" "$(date +%s)" "test_alarm" "test.chart" "test.family" "${x}" "${last}" 100 90 "${0}" 1 $((0 + id)) "units" "this is a test alarm to verify notifications work" "new value" "old value" "evaluated expression" "expression variable values" 0 0
62 - #shellcheck disable=SC2181
63 - if [ $? -ne 0 ]; then
64 - echo >&2 "# FAILED"
65 - test_res=1
66 - else
67 - echo >&2 "# OK"
68 - fi
69 -
70 - last="${x}"
71 - id=$((id + 1))
72 - done
73 -
74 - exit $test_res
46 + if [ "${2}" = "test" ]; then
47 + recipient="${1}"
48 + else
49 + recipient="${2}"
50 + fi
51 +
52 + [ -z "${recipient}" ] && recipient="sysadmin"
53 +
54 + id=1
55 + last="CLEAR"
56 + test_res=0
57 + for x in "WARNING" "CRITICAL" "CLEAR"; do
58 + echo >&2
59 + echo >&2 "# SENDING TEST ${x} ALARM TO ROLE: ${recipient}"
60 +
61 + "${0}" "${recipient}" "$(hostname)" 1 1 "${id}" "$(date +%s)" "test_alarm" "test.chart" "test.family" "${x}" "${last}" 100 90 "${0}" 1 $((0 + id)) "units" "this is a test alarm to verify notifications work" "new value" "old value" "evaluated expression" "expression variable values" 0 0
62 + #shellcheck disable=SC2181
63 + if [ $? -ne 0 ]; then
64 + echo >&2 "# FAILED"
65 + test_res=1
66 + else
67 + echo >&2 "# OK"
68 + fi
69 +
70 + last="${x}"
71 + id=$((id + 1))
72 + done
73 +
74 + exit $test_res
75 fi
76
77 export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
@@ -82,67 +82,67 @@ export LC_ALL=C
82 PROGRAM_NAME="$(basename "${0}")"
83
84 logdate() {
85 - date "+%Y-%m-%d %H:%M:%S"
85 + date "+%Y-%m-%d %H:%M:%S"
86 }
87
88 log() {
89 - local status="${1}"
90 - shift
89 + local status="${1}"
90 + shift
91
92 - echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}"
92 + echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}"
93
94 }
95
96 warning() {
97 - log WARNING "${@}"
97 + log WARNING "${@}"
98 }
99
100 error() {
101 - log ERROR "${@}"
101 + log ERROR "${@}"
102 }
103
104 info() {
105 - log INFO "${@}"
105 + log INFO "${@}"
106 }
107
108 fatal() {
109 - log FATAL "${@}"
110 - exit 1
109 + log FATAL "${@}"
110 + exit 1
111 }
112
113 debug=${NETDATA_ALARM_NOTIFY_DEBUG-0}
114 debug() {
115 - [ "${debug}" = "1" ] && log DEBUG "${@}"
115 + [ "${debug}" = "1" ] && log DEBUG "${@}"
116 }
117
118 docurl() {
119 - if [ -z "${curl}" ]; then
120 - error "${curl} is unset."
121 - return 1
122 - fi
123 -
124 - if [ "${debug}" = "1" ]; then
125 - echo >&2 "--- BEGIN curl command ---"
126 - printf >&2 "%q " ${curl} "${@}"
127 - echo >&2
128 - echo >&2 "--- END curl command ---"
129 -
130 - local out code ret
131 - out=$(mktemp /tmp/netdata-health-alarm-notify-XXXXXXXX)
132 - code=$(${curl} ${curl_options} --write-out "%{http_code}" --output "${out}" --silent --show-error "${@}")
133 - ret=$?
134 - echo >&2 "--- BEGIN received response ---"
135 - cat >&2 "${out}"
136 - echo >&2
137 - echo >&2 "--- END received response ---"
138 - echo >&2 "RECEIVED HTTP RESPONSE CODE: ${code}"
139 - rm "${out}"
140 - echo "${code}"
141 - return ${ret}
142 - fi
143 -
144 - ${curl} ${curl_options} --write-out "%{http_code}" --output /dev/null --silent --show-error "${@}"
145 - return $?
119 + if [ -z "${curl}" ]; then
120 + error "${curl} is unset."
121 + return 1
122 + fi
123 +
124 + if [ "${debug}" = "1" ]; then
125 + echo >&2 "--- BEGIN curl command ---"
126 + printf >&2 "%q " ${curl} "${@}"
127 + echo >&2
128 + echo >&2 "--- END curl command ---"
129 +
130 + local out code ret
131 + out=$(mktemp /tmp/netdata-health-alarm-notify-XXXXXXXX)
132 + code=$(${curl} ${curl_options} --write-out "%{http_code}" --output "${out}" --silent --show-error "${@}")
133 + ret=$?
134 + echo >&2 "--- BEGIN received response ---"
135 + cat >&2 "${out}"
136 + echo >&2
137 + echo >&2 "--- END received response ---"
138 + echo >&2 "RECEIVED HTTP RESPONSE CODE: ${code}"
139 + rm "${out}"
140 + echo "${code}"
141 + return ${ret}
142 + fi
143 +
144 + ${curl} ${curl_options} --write-out "%{http_code}" --output /dev/null --silent --show-error "${@}"
145 + return $?
146 }
147
148 # -----------------------------------------------------------------------------
@@ -181,14 +181,14 @@ matrix
181 # this is to be overwritten by the config file
182
183 custom_sender() {
184 - info "not sending custom notification for ${status} of '${host}.${chart}.${name}'"
184 + info "not sending custom notification for ${status} of '${host}.${chart}.${name}'"
185 }
186
187 # -----------------------------------------------------------------------------
188
189 # check for BASH v4+ (required for associative arrays)
190 if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
191 - fatal "BASH version 4 or later is required (this is ${BASH_VERSION})."
191 + fatal "BASH version 4 or later is required (this is ${BASH_VERSION})."
192 fi
193
194 # -----------------------------------------------------------------------------
@@ -204,49 +204,49 @@ fi
204 # parse command line parameters
205
206 if [[ ${1} = "unittest" ]]; then
207 - unittest=1 # enable unit testing mode
208 - roles="${2}" # the role that should be used for unit testing
209 - cfgfile="${3}" # the location of the config file to use for unit testing
210 - status="${4}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
211 - old_status="${5}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
207 + unittest=1 # enable unit testing mode
208 + roles="${2}" # the role that should be used for unit testing
209 + cfgfile="${3}" # the location of the config file to use for unit testing
210 + status="${4}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
211 + old_status="${5}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
212 else
213 - roles="${1}" # the roles that should be notified for this event
214 - args_host="${2}" # the host generated this event
215 - unique_id="${3}" # the unique id of this event
216 - alarm_id="${4}" # the unique id of the alarm that generated this event
217 - event_id="${5}" # the incremental id of the event, for this alarm id
218 - when="${6}" # the timestamp this event occurred
219 - name="${7}" # the name of the alarm, as given in netdata health.d entries
220 - chart="${8}" # the name of the chart (type.id)
221 - family="${9}" # the family of the chart
222 - status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
223 - old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
224 - value="${12}" # the current value of the alarm
225 - old_value="${13}" # the previous value of the alarm
226 - src="${14}" # the line number and file the alarm has been configured
227 - duration="${15}" # the duration in seconds of the previous alarm state
228 - non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
229 - units="${17}" # the units of the value
230 - info="${18}" # a short description of the alarm
231 - value_string="${19}" # friendly value (with units)
232 - # shellcheck disable=SC2034
233 - # variable is unused, but https://github.com/netdata/netdata/pull/5164#discussion_r255572947
234 - old_value_string="${20}" # friendly old value (with units), previously named "old_value_string"
235 - calc_expression="${21}" # contains the expression that was evaluated to trigger the alarm
236 - calc_param_values="${22}" # the values of the parameters in the expression, at the time of the evaluation
237 - total_warnings="${23}" # Total number of alarms in WARNING state
238 - total_critical="${24}" # Total number of alarms in CRITICAL state
213 + roles="${1}" # the roles that should be notified for this event
214 + args_host="${2}" # the host generated this event
215 + unique_id="${3}" # the unique id of this event
216 + alarm_id="${4}" # the unique id of the alarm that generated this event
217 + event_id="${5}" # the incremental id of the event, for this alarm id
218 + when="${6}" # the timestamp this event occurred
219 + name="${7}" # the name of the alarm, as given in netdata health.d entries
220 + chart="${8}" # the name of the chart (type.id)
221 + family="${9}" # the family of the chart
222 + status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
223 + old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
224 + value="${12}" # the current value of the alarm
225 + old_value="${13}" # the previous value of the alarm
226 + src="${14}" # the line number and file the alarm has been configured
227 + duration="${15}" # the duration in seconds of the previous alarm state
228 + non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
229 + units="${17}" # the units of the value
230 + info="${18}" # a short description of the alarm
231 + value_string="${19}" # friendly value (with units)
232 + # shellcheck disable=SC2034
233 + # variable is unused, but https://github.com/netdata/netdata/pull/5164#discussion_r255572947
234 + old_value_string="${20}" # friendly old value (with units), previously named "old_value_string"
235 + calc_expression="${21}" # contains the expression that was evaluated to trigger the alarm
236 + calc_param_values="${22}" # the values of the parameters in the expression, at the time of the evaluation
237 + total_warnings="${23}" # Total number of alarms in WARNING state
238 + total_critical="${24}" # Total number of alarms in CRITICAL state
239 fi
240
241 # -----------------------------------------------------------------------------
242 # find a suitable hostname to use, if netdata did not supply a hostname
243
244 if [ -z ${args_host} ]; then
245 - this_host=$(hostname -s 2>/dev/null)
246 - host="${this_host}"
247 - args_host="${this_host}"
245 + this_host=$(hostname -s 2>/dev/null)
246 + host="${this_host}"
247 + args_host="${this_host}"
248 else
249 - host="${args_host}"
249 + host="${args_host}"
250 fi
251
252 # -----------------------------------------------------------------------------
@@ -254,14 +254,14 @@ fi
254
255 # don't do anything if this is not WARNING, CRITICAL or CLEAR
256 if [ "${status}" != "WARNING" ] && [ "${status}" != "CRITICAL" ] && [ "${status}" != "CLEAR" ]; then
257 - info "not sending notification for ${status} of '${host}.${chart}.${name}'"
258 - exit 1
257 + info "not sending notification for ${status} of '${host}.${chart}.${name}'"
258 + exit 1
259 fi
260
261 # don't do anything if this is CLEAR, but it was not WARNING or CRITICAL
262 if [ "${clear_alarm_always}" != "YES" ] && [ "${old_status}" != "WARNING" ] && [ "${old_status}" != "CRITICAL" ] && [ "${status}" = "CLEAR" ]; then
263 - info "not sending notification for ${status} of '${host}.${chart}.${name}' (last status was ${old_status})"
264 - exit 1
263 + info "not sending notification for ${status} of '${host}.${chart}.${name}' (last status was ${old_status})"
264 + exit 1
265 fi
266
267 # -----------------------------------------------------------------------------
@@ -286,12 +286,12 @@ sendmail=
286
287 # enable / disable features
288 for method_name in ${method_names^^}; do
289 - declare SEND_${method_name}="YES"
290 - declare DEFAULT_RECIPIENT_${method_name}
289 + declare SEND_${method_name}="YES"
290 + declare DEFAULT_RECIPIENT_${method_name}
291 done
292
293 for method_name in ${method_names}; do
294 - declare -A role_recipients_${method_name}
294 + declare -A role_recipients_${method_name}
295 done
296
297 # slack configs
@@ -347,6 +347,7 @@ KAFKA_SENDER_IP=
347
348 # pagerduty.com configs
349 PD_SERVICE_KEY=
350 +USE_PD_VERSION=
351
352 # fleep.io configs
353 FLEEP_SENDER="${host}"
@@ -395,87 +396,87 @@ OPSGENIE_API_KEY=
396 # these will overwrite the variables above
397
398 if [ ${unittest} ]; then
398 - if source "${cfgfile}"; then
399 - error "Failed to load requested config file."
400 - exit 1
401 - fi
399 + if source "${cfgfile}"; then
400 + error "Failed to load requested config file."
401 + exit 1
402 + fi
403 else
403 - for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/health_alarm_notify.conf" "${NETDATA_USER_CONFIG_DIR}/health_alarm_notify.conf"; do
404 - if [ -f "${CONFIG}" ]; then
405 - debug "Loading config file '${CONFIG}'..."
406 - source "${CONFIG}" || error "Failed to load config file '${CONFIG}'."
407 - else
408 - warning "Cannot find file '${CONFIG}'."
409 - fi
410 - done
404 + for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/health_alarm_notify.conf" "${NETDATA_USER_CONFIG_DIR}/health_alarm_notify.conf"; do
405 + if [ -f "${CONFIG}" ]; then
406 + debug "Loading config file '${CONFIG}'..."
407 + source "${CONFIG}" || error "Failed to load config file '${CONFIG}'."
408 + else
409 + warning "Cannot find file '${CONFIG}'."
410 + fi
411 + done
412 fi
413
414 # If we didn't autodetect the character set for e-mail and it wasn't
415 # set by the user, we need to set it to a reasonable default. UTF-8
416 # should be correct for almost all modern UNIX systems.
417 if [ -z ${EMAIL_CHARSET} ]; then
417 - EMAIL_CHARSET="UTF-8"
418 + EMAIL_CHARSET="UTF-8"
419 fi
420
421 # If we've been asked to use FQDN's for the URL's in the alarm, do so,
422 # unless we're sending an alarm for a child system which we can't get the
423 # FQDN of easily.
424 if [ "${use_fqdn}" = "YES" ] && [ "${host}" = "$(hostname -s 2>/dev/null)" ]; then
424 - host="$(hostname -f 2>/dev/null)"
425 + host="$(hostname -f 2>/dev/null)"
426 fi
427
428 # -----------------------------------------------------------------------------
429 # filter a recipient based on alarm event severity
430
431 filter_recipient_by_criticality() {
431 - local method="${1}" x="${2}" r s
432 - shift
433 -
434 - r="${x/|*/}" # the recipient
435 - s="${x/*|/}" # the severity required for notifying this recipient
436 -
437 - # no severity filtering for this person
438 - [ "${r}" = "${s}" ] && return 0
439 -
440 - # the severity is invalid
441 - s="${s^^}"
442 - if [ "${s}" != "CRITICAL" ]; then
443 - error "SEVERITY FILTERING for ${x} VIA ${method}: invalid severity '${s,,}', only 'critical' is supported."
444 - return 0
445 - fi
446 -
447 - # create the status tracking directory for this user
448 - [ ! -d "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}" ] &&
449 - mkdir -p "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}"
450 -
451 - case "${status}" in
452 - CRITICAL)
453 - # make sure he will get future notifications for this alarm too
454 - touch "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
455 - debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: the alarm is CRITICAL (will now receive next status change)"
456 - return 0
457 - ;;
458 -
459 - WARNING)
460 - if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]; then
461 - # we do not remove the file, so that he will get future notifications of this alarm
462 - debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm in the past (will still receive next status change)"
463 - return 0
464 - fi
465 - ;;
466 -
467 - *)
468 - if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]; then
469 - # remove the file, so that he will only receive notifications for CRITICAL states for this alarm
470 - rm "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
471 - debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm (will only receive CRITICAL notifications from now on)"
472 - return 0
473 - fi
474 - ;;
475 - esac
476 -
477 - debug "SEVERITY FILTERING for ${x} VIA ${method}: BLOCK: recipient should not receive this notification"
478 - return 1
432 + local method="${1}" x="${2}" r s
433 + shift
434 +
435 + r="${x/|*/}" # the recipient
436 + s="${x/*|/}" # the severity required for notifying this recipient
437 +
438 + # no severity filtering for this person
439 + [ "${r}" = "${s}" ] && return 0
440 +
441 + # the severity is invalid
442 + s="${s^^}"
443 + if [ "${s}" != "CRITICAL" ]; then
444 + error "SEVERITY FILTERING for ${x} VIA ${method}: invalid severity '${s,,}', only 'critical' is supported."
445 + return 0
446 + fi
447 +
448 + # create the status tracking directory for this user
449 + [ ! -d "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}" ] &&
450 + mkdir -p "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}"
451 +
452 + case "${status}" in
453 + CRITICAL)
454 + # make sure he will get future notifications for this alarm too
455 + touch "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
456 + debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: the alarm is CRITICAL (will now receive next status change)"
457 + return 0
458 + ;;
459 +
460 + WARNING)
461 + if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]; then
462 + # we do not remove the file, so that he will get future notifications of this alarm
463 + debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm in the past (will still receive next status change)"
464 + return 0
465 + fi
466 + ;;
467 +
468 + *)
469 + if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]; then
470 + # remove the file, so that he will only receive notifications for CRITICAL states for this alarm
471 + rm "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
472 + debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm (will only receive CRITICAL notifications from now on)"
473 + return 0
474 + fi
475 + ;;
476 + esac
477 +
478 + debug "SEVERITY FILTERING for ${x} VIA ${method}: BLOCK: recipient should not receive this notification"
479 + return 1
480 }
481
482 # -----------------------------------------------------------------------------
@@ -547,93 +548,93 @@ filter_recipient_by_criticality() {
548 [ -z "${STACKPULSE_WEBHOOK}" ] && SEND_STACKPULSE="NO"
549
550 if [ "${SEND_PUSHOVER}" = "YES" ] ||
550 - [ "${SEND_SLACK}" = "YES" ] ||
551 - [ "${SEND_ROCKETCHAT}" = "YES" ] ||
552 - [ "${SEND_ALERTA}" = "YES" ] ||
553 - [ "${SEND_PD}" = "YES" ] ||
554 - [ "${SEND_FLOCK}" = "YES" ] ||
555 - [ "${SEND_DISCORD}" = "YES" ] ||
556 - [ "${SEND_HIPCHAT}" = "YES" ] ||
557 - [ "${SEND_TWILIO}" = "YES" ] ||
558 - [ "${SEND_MESSAGEBIRD}" = "YES" ] ||
559 - [ "${SEND_KAVENEGAR}" = "YES" ] ||
560 - [ "${SEND_TELEGRAM}" = "YES" ] ||
561 - [ "${SEND_PUSHBULLET}" = "YES" ] ||
562 - [ "${SEND_KAFKA}" = "YES" ] ||
563 - [ "${SEND_FLEEP}" = "YES" ] ||
564 - [ "${SEND_PROWL}" = "YES" ] ||
565 - [ "${SEND_HANGOUTS}" = "YES" ] ||
566 - [ "${SEND_MATRIX}" = "YES" ] ||
567 - [ "${SEND_CUSTOM}" = "YES" ] ||
568 - [ "${SEND_MSTEAM}" = "YES" ] ||
569 - [ "${SEND_DYNATRACE}" = "YES" ] ||
570 - [ "${SEND_STACKPULSE}" = "YES" ] ||
571 - [ "${SEND_OPSGENIE}" = "YES" ]; then
572 - # if we need curl, check for the curl command
573 - if [ -z "${curl}" ]; then
574 - curl="$(command -v curl 2>/dev/null)"
575 - fi
576 - if [ -z "${curl}" ]; then
577 - error "Cannot find curl command in the system path. Disabling all curl based notifications."
578 - SEND_PUSHOVER="NO"
579 - SEND_PUSHBULLET="NO"
580 - SEND_TELEGRAM="NO"
581 - SEND_SLACK="NO"
582 - SEND_MSTEAM="NO"
583 - SEND_ROCKETCHAT="NO"
584 - SEND_ALERTA="NO"
585 - SEND_PD="NO"
586 - SEND_FLOCK="NO"
587 - SEND_DISCORD="NO"
588 - SEND_TWILIO="NO"
589 - SEND_HIPCHAT="NO"
590 - SEND_MESSAGEBIRD="NO"
591 - SEND_KAVENEGAR="NO"
592 - SEND_KAFKA="NO"
593 - SEND_FLEEP="NO"
594 - SEND_PROWL="NO"
595 - SEND_HANGOUTS="NO"
596 - SEND_MATRIX="NO"
597 - SEND_CUSTOM="NO"
598 - SEND_DYNATRACE="NO"
599 - SEND_STACKPULSE="NO"
600 - SEND_OPSGENIE="NO"
601 - fi
551 + [ "${SEND_SLACK}" = "YES" ] ||
552 + [ "${SEND_ROCKETCHAT}" = "YES" ] ||
553 + [ "${SEND_ALERTA}" = "YES" ] ||
554 + [ "${SEND_PD}" = "YES" ] ||
555 + [ "${SEND_FLOCK}" = "YES" ] ||
556 + [ "${SEND_DISCORD}" = "YES" ] ||
557 + [ "${SEND_HIPCHAT}" = "YES" ] ||
558 + [ "${SEND_TWILIO}" = "YES" ] ||
559 + [ "${SEND_MESSAGEBIRD}" = "YES" ] ||
560 + [ "${SEND_KAVENEGAR}" = "YES" ] ||
561 + [ "${SEND_TELEGRAM}" = "YES" ] ||
562 + [ "${SEND_PUSHBULLET}" = "YES" ] ||
563 + [ "${SEND_KAFKA}" = "YES" ] ||
564 + [ "${SEND_FLEEP}" = "YES" ] ||
565 + [ "${SEND_PROWL}" = "YES" ] ||
566 + [ "${SEND_HANGOUTS}" = "YES" ] ||
567 + [ "${SEND_MATRIX}" = "YES" ] ||
568 + [ "${SEND_CUSTOM}" = "YES" ] ||
569 + [ "${SEND_MSTEAM}" = "YES" ] ||
570 + [ "${SEND_DYNATRACE}" = "YES" ] ||
571 + [ "${SEND_STACKPULSE}" = "YES" ] ||
572 + [ "${SEND_OPSGENIE}" = "YES" ]; then
573 + # if we need curl, check for the curl command
574 + if [ -z "${curl}" ]; then
575 + curl="$(command -v curl 2>/dev/null)"
576 + fi
577 + if [ -z "${curl}" ]; then
578 + error "Cannot find curl command in the system path. Disabling all curl based notifications."
579 + SEND_PUSHOVER="NO"
580 + SEND_PUSHBULLET="NO"
581 + SEND_TELEGRAM="NO"
582 + SEND_SLACK="NO"
583 + SEND_MSTEAM="NO"
584 + SEND_ROCKETCHAT="NO"
585 + SEND_ALERTA="NO"
586 + SEND_PD="NO"
587 + SEND_FLOCK="NO"
588 + SEND_DISCORD="NO"
589 + SEND_TWILIO="NO"
590 + SEND_HIPCHAT="NO"
591 + SEND_MESSAGEBIRD="NO"
592 + SEND_KAVENEGAR="NO"
593 + SEND_KAFKA="NO"
594 + SEND_FLEEP="NO"
595 + SEND_PROWL="NO"
596 + SEND_HANGOUTS="NO"
597 + SEND_MATRIX="NO"
598 + SEND_CUSTOM="NO"
599 + SEND_DYNATRACE="NO"
600 + SEND_STACKPULSE="NO"
601 + SEND_OPSGENIE="NO"
602 + fi
603 fi
604
605 if [ "${SEND_SMS}" = "YES" ]; then
605 - if [ -z "${sendsms}" ]; then
606 - sendsms="$(command -v sendsms 2>/dev/null)"
607 - fi
608 - if [ -z "${sendsms}" ]; then
609 - SEND_SMS="NO"
610 - fi
606 + if [ -z "${sendsms}" ]; then
607 + sendsms="$(command -v sendsms 2>/dev/null)"
608 + fi
609 + if [ -z "${sendsms}" ]; then
610 + SEND_SMS="NO"
611 + fi
612 fi
613 # if we need sendmail, check for the sendmail command
614 if [ "${SEND_EMAIL}" = "YES" ] && [ -z "${sendmail}" ]; then
614 - sendmail="$(command -v sendmail 2>/dev/null)"
615 - if [ -z "${sendmail}" ]; then
616 - debug "Cannot find sendmail command in the system path. Disabling email notifications."
617 - SEND_EMAIL="NO"
618 - fi
615 + sendmail="$(command -v sendmail 2>/dev/null)"
616 + if [ -z "${sendmail}" ]; then
617 + debug "Cannot find sendmail command in the system path. Disabling email notifications."
618 + SEND_EMAIL="NO"
619 + fi
620 fi
621
622 # if we need logger, check for the logger command
623 if [ "${SEND_SYSLOG}" = "YES" ] && [ -z "${logger}" ]; then
623 - logger="$(command -v logger 2>/dev/null)"
624 - if [ -z "${logger}" ]; then
625 - debug "Cannot find logger command in the system path. Disabling syslog notifications."
626 - SEND_SYSLOG="NO"
627 - fi
624 + logger="$(command -v logger 2>/dev/null)"
625 + if [ -z "${logger}" ]; then
626 + debug "Cannot find logger command in the system path. Disabling syslog notifications."
627 + SEND_SYSLOG="NO"
628 + fi
629 fi
630
631 # if we need aws, check for the aws command
632 if [ "${SEND_AWSSNS}" = "YES" ] && [ -z "${aws}" ]; then
632 - aws="$(command -v aws 2>/dev/null)"
633 - if [ -z "${aws}" ]; then
634 - debug "Cannot find aws command in the system path. Disabling Amazon SNS notifications."
635 - SEND_AWSSNS="NO"
636 - fi
633 + aws="$(command -v aws 2>/dev/null)"
634 + if [ -z "${aws}" ]; then
635 + debug "Cannot find aws command in the system path. Disabling Amazon SNS notifications."
636 + SEND_AWSSNS="NO"
637 + fi
638 fi
639
640 # -----------------------------------------------------------------------------
@@ -642,47 +643,47 @@ fi
643 # netdata may call us with multiple roles, and roles may have multiple but
644 # overlapping recipients - so, here we find the unique recipients.
645 for method_name in ${method_names}; do
645 - send_var="SEND_${method_name^^}"
646 - if [ "${!send_var}" = "NO" ]; then
647 - continue
648 - fi
649 -
650 - declare -A arr_var=()
651 -
652 - for x in ${roles//,/ }; do
653 - # the roles 'silent' and 'disabled' mean:
654 - # don't send a notification for this role
655 - if [ "${x}" = "silent" ] || [ "${x}" = "disabled" ]; then
656 - continue
657 - fi
658 -
659 - role_recipients="role_recipients_${method_name}[$x]"
660 - default_recipient_var="DEFAULT_RECIPIENT_${method_name^^}"
661 -
662 - a="${!role_recipients}"
663 - [ -z "${a}" ] && a="${!default_recipient_var}"
664 - for r in ${a//,/ }; do
665 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality ${method_name} "${r}" && arr_var[${r/|*/}]="1"
666 - done
667 - done
668 -
669 - # build the list of recipients
670 - to_var="to_${method_name}"
671 - declare to_${method_name}="${!arr_var[*]}"
672 -
673 - [ -z "${!to_var}" ] && declare ${send_var}="NO"
646 + send_var="SEND_${method_name^^}"
647 + if [ "${!send_var}" = "NO" ]; then
648 + continue
649 + fi
650 +
651 + declare -A arr_var=()
652 +
653 + for x in ${roles//,/ }; do
654 + # the roles 'silent' and 'disabled' mean:
655 + # don't send a notification for this role
656 + if [ "${x}" = "silent" ] || [ "${x}" = "disabled" ]; then
657 + continue
658 + fi
659 +
660 + role_recipients="role_recipients_${method_name}[$x]"
661 + default_recipient_var="DEFAULT_RECIPIENT_${method_name^^}"
662 +
663 + a="${!role_recipients}"
664 + [ -z "${a}" ] && a="${!default_recipient_var}"
665 + for r in ${a//,/ }; do
666 + [ "${r}" != "disabled" ] && filter_recipient_by_criticality ${method_name} "${r}" && arr_var[${r/|*/}]="1"
667 + done
668 + done
669 +
670 + # build the list of recipients
671 + to_var="to_${method_name}"
672 + declare to_${method_name}="${!arr_var[*]}"
673 +
674 + [ -z "${!to_var}" ] && declare ${send_var}="NO"
675 done
676
677 # -----------------------------------------------------------------------------
678 # handle fixup of the email recipient list.
679
680 fix_to_email() {
680 - to_email=
681 - while [ -n "${1}" ]; do
682 - [ -n "${to_email}" ] && to_email="${to_email}, "
683 - to_email="${to_email}${1}"
684 - shift 1
685 - done
681 + to_email=
682 + while [ -n "${1}" ]; do
683 + [ -n "${to_email}" ] && to_email="${to_email}, "
684 + to_email="${to_email}${1}"
685 + shift 1
686 + done
687 }
688
689 # ${to_email} without quotes here
@@ -691,52 +692,52 @@ fix_to_email ${to_email}
692 # -----------------------------------------------------------------------------
693 # handle output if we're running in unit test mode
694 if [ ${unittest} ]; then
694 - for method_name in ${method_names}; do
695 - to_var="to_${method_name}"
696 - echo "results: ${method_name}: ${!to_var}"
697 - done
698 - exit 0
695 + for method_name in ${method_names}; do
696 + to_var="to_${method_name}"
697 + echo "results: ${method_name}: ${!to_var}"
698 + done
699 + exit 0
700 fi
701
702 # -----------------------------------------------------------------------------
703 # check that we have at least a method enabled
704 proceed=0
705 for method in "${SEND_EMAIL}" \
705 - "${SEND_PUSHOVER}" \
706 - "${SEND_TELEGRAM}" \
707 - "${SEND_SLACK}" \
708 - "${SEND_ROCKETCHAT}" \
709 - "${SEND_ALERTA}" \
710 - "${SEND_FLOCK}" \
711 - "${SEND_DISCORD}" \
712 - "${SEND_TWILIO}" \
713 - "${SEND_HIPCHAT}" \
714 - "${SEND_MESSAGEBIRD}" \
715 - "${SEND_KAVENEGAR}" \
716 - "${SEND_PUSHBULLET}" \
717 - "${SEND_KAFKA}" \
718 - "${SEND_PD}" \
719 - "${SEND_FLEEP}" \
720 - "${SEND_PROWL}" \
721 - "${SEND_MATRIX}" \
722 - "${SEND_CUSTOM}" \
723 - "${SEND_IRC}" \
724 - "${SEND_HANGOUTS}" \
725 - "${SEND_AWSSNS}" \
726 - "${SEND_SYSLOG}" \
727 - "${SEND_SMS}" \
728 - "${SEND_MSTEAM}" \
729 - "${SEND_DYNATRACE}" \
730 - "${SEND_STACKPULSE}" \
731 - "${SEND_OPSGENIE}" ; do
732 -
733 - if [ "${method}" == "YES" ]; then
734 - proceed=1
735 - break
736 - fi
706 + "${SEND_PUSHOVER}" \
707 + "${SEND_TELEGRAM}" \
708 + "${SEND_SLACK}" \
709 + "${SEND_ROCKETCHAT}" \
710 + "${SEND_ALERTA}" \
711 + "${SEND_FLOCK}" \
712 + "${SEND_DISCORD}" \
713 + "${SEND_TWILIO}" \
714 + "${SEND_HIPCHAT}" \
715 + "${SEND_MESSAGEBIRD}" \
716 + "${SEND_KAVENEGAR}" \
717 + "${SEND_PUSHBULLET}" \
718 + "${SEND_KAFKA}" \
719 + "${SEND_PD}" \
720 + "${SEND_FLEEP}" \
721 + "${SEND_PROWL}" \
722 + "${SEND_MATRIX}" \
723 + "${SEND_CUSTOM}" \
724 + "${SEND_IRC}" \
725 + "${SEND_HANGOUTS}" \
726 + "${SEND_AWSSNS}" \
727 + "${SEND_SYSLOG}" \
728 + "${SEND_SMS}" \
729 + "${SEND_MSTEAM}" \
730 + "${SEND_DYNATRACE}" \
731 + "${SEND_STACKPULSE}" \
732 + "${SEND_OPSGENIE}" ; do
733 +
734 + if [ "${method}" == "YES" ]; then
735 + proceed=1
736 + break
737 + fi
738 done
739 if [ "$proceed" -eq 0 ]; then
739 - fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'."
740 + fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'."
741 fi
742
743 # -----------------------------------------------------------------------------
@@ -750,34 +751,34 @@ date=$(date --date=@${when} "${date_format}" 2>/dev/null)
751 # ----------------------------------------------------------------------------
752 # prepare some extra headers if we've been asked to thread e-mails
753 if [ "${SEND_EMAIL}" == "YES" ] && [ "${EMAIL_THREADING}" != "NO" ]; then
753 - email_thread_headers="In-Reply-To: <${chart}-${name}@${host}>\\r\\nReferences: <${chart}-${name}@${host}>"
754 + email_thread_headers="In-Reply-To: <${chart}-${name}@${host}>\\r\\nReferences: <${chart}-${name}@${host}>"
755 else
755 - email_thread_headers=
756 + email_thread_headers=
757 fi
758
759 # -----------------------------------------------------------------------------
760 # function to URL encode a string
761
762 urlencode() {
762 - local string="${1}" strlen encoded pos c o
763 -
764 - strlen=${#string}
765 - for ((pos = 0; pos < strlen; pos++)); do
766 - c=${string:pos:1}
767 - case "${c}" in
768 - [-_.~a-zA-Z0-9])
769 - o="${c}"
770 - ;;
771 -
772 - *)
773 - printf -v o '%%%02x' "'${c}"
774 - ;;
775 - esac
776 - encoded+="${o}"
777 - done
778 -
779 - REPLY="${encoded}"
780 - echo "${REPLY}"
763 + local string="${1}" strlen encoded pos c o
764 +
765 + strlen=${#string}
766 + for ((pos = 0; pos < strlen; pos++)); do
767 + c=${string:pos:1}
768 + case "${c}" in
769 + [-_.~a-zA-Z0-9])
770 + o="${c}"
771 + ;;
772 +
773 + *)
774 + printf -v o '%%%02x' "'${c}"
775 + ;;
776 + esac
777 + encoded+="${o}"
778 + done
779 +
780 + REPLY="${encoded}"
781 + echo "${REPLY}"
782 }
783
784 # -----------------------------------------------------------------------------
@@ -785,154 +786,154 @@ urlencode() {
786 # using DAYS, MINUTES, SECONDS
787
788 duration4human() {
788 - local s="${1}" d=0 h=0 m=0 ds="day" hs="hour" ms="minute" ss="second" ret
789 - d=$((s / 86400))
790 - s=$((s - (d * 86400)))
791 - h=$((s / 3600))
792 - s=$((s - (h * 3600)))
793 - m=$((s / 60))
794 - s=$((s - (m * 60)))
795 -
796 - if [ ${d} -gt 0 ]; then
797 - [ ${m} -ge 30 ] && h=$((h + 1))
798 - [ ${d} -gt 1 ] && ds="days"
799 - [ ${h} -gt 1 ] && hs="hours"
800 - if [ ${h} -gt 0 ]; then
801 - ret="${d} ${ds} and ${h} ${hs}"
802 - else
803 - ret="${d} ${ds}"
804 - fi
805 - elif [ ${h} -gt 0 ]; then
806 - [ ${s} -ge 30 ] && m=$((m + 1))
807 - [ ${h} -gt 1 ] && hs="hours"
808 - [ ${m} -gt 1 ] && ms="minutes"
809 - if [ ${m} -gt 0 ]; then
810 - ret="${h} ${hs} and ${m} ${ms}"
811 - else
812 - ret="${h} ${hs}"
813 - fi
814 - elif [ ${m} -gt 0 ]; then
815 - [ ${m} -gt 1 ] && ms="minutes"
816 - [ ${s} -gt 1 ] && ss="seconds"
817 - if [ ${s} -gt 0 ]; then
818 - ret="${m} ${ms} and ${s} ${ss}"
819 - else
820 - ret="${m} ${ms}"
821 - fi
822 - else
823 - [ ${s} -gt 1 ] && ss="seconds"
824 - ret="${s} ${ss}"
825 - fi
826 -
827 - REPLY="${ret}"
828 - echo "${REPLY}"
789 + local s="${1}" d=0 h=0 m=0 ds="day" hs="hour" ms="minute" ss="second" ret
790 + d=$((s / 86400))
791 + s=$((s - (d * 86400)))
792 + h=$((s / 3600))
793 + s=$((s - (h * 3600)))
794 + m=$((s / 60))
795 + s=$((s - (m * 60)))
796 +
797 + if [ ${d} -gt 0 ]; then
798 + [ ${m} -ge 30 ] && h=$((h + 1))
799 + [ ${d} -gt 1 ] && ds="days"
800 + [ ${h} -gt 1 ] && hs="hours"
801 + if [ ${h} -gt 0 ]; then
802 + ret="${d} ${ds} and ${h} ${hs}"
803 + else
804 + ret="${d} ${ds}"
805 + fi
806 + elif [ ${h} -gt 0 ]; then
807 + [ ${s} -ge 30 ] && m=$((m + 1))
808 + [ ${h} -gt 1 ] && hs="hours"
809 + [ ${m} -gt 1 ] && ms="minutes"
810 + if [ ${m} -gt 0 ]; then
811 + ret="${h} ${hs} and ${m} ${ms}"
812 + else
813 + ret="${h} ${hs}"
814 + fi
815 + elif [ ${m} -gt 0 ]; then
816 + [ ${m} -gt 1 ] && ms="minutes"
817 + [ ${s} -gt 1 ] && ss="seconds"
818 + if [ ${s} -gt 0 ]; then
819 + ret="${m} ${ms} and ${s} ${ss}"
820 + else
821 + ret="${m} ${ms}"
822 + fi
823 + else
824 + [ ${s} -gt 1 ] && ss="seconds"
825 + ret="${s} ${ss}"
826 + fi
827 +
828 + REPLY="${ret}"
829 + echo "${REPLY}"
830 }
831
832 # -----------------------------------------------------------------------------
833 # email sender
834
835 send_email() {
835 - local ret opts=() sender_email="${EMAIL_SENDER}" sender_name=
836 - if [ "${SEND_EMAIL}" = "YES" ]; then
837 -
838 - if [ -n "${EMAIL_SENDER}" ]; then
839 - if [[ ${EMAIL_SENDER} =~ ^\".*\"\ \<.*\>$ ]]; then
840 - # the name includes double quotes
841 - sender_email="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1)"
842 - sender_name="$(echo "${EMAIL_SENDER}" | cut -d '"' -f 2)"
843 - elif [[ ${EMAIL_SENDER} =~ ^\'.*\'\ \<.*\>$ ]]; then
844 - # the name includes single quotes
845 - sender_email="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1)"
846 - sender_name="$(echo "${EMAIL_SENDER}" | cut -d "'" -f 2)"
847 - elif [[ ${EMAIL_SENDER} =~ ^.*\ \<.*\>$ ]]; then
848 - # the name does not have any quotes
849 - sender_email="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1)"
850 - sender_name="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)"
851 - fi
852 - fi
853 -
854 - [ -n "${sender_email}" ] && opts+=(-f "${sender_email}")
855 - [ -n "${sender_name}" ] && opts+=(-F "${sender_name}")
856 -
857 - if [ "${debug}" = "1" ]; then
858 - echo >&2 "--- BEGIN sendmail command ---"
859 - printf >&2 "%q " "${sendmail}" -t "${opts[@]}"
860 - echo >&2
861 - echo >&2 "--- END sendmail command ---"
862 - fi
863 -
864 - "${sendmail}" -t "${opts[@]}"
865 - ret=$?
866 -
867 - if [ ${ret} -eq 0 ]; then
868 - info "sent email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}'"
869 - return 0
870 - else
871 - error "failed to send email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}' with error code ${ret}."
872 - return 1
873 - fi
874 - fi
875 -
876 - return 1
836 + local ret opts=() sender_email="${EMAIL_SENDER}" sender_name=
837 + if [ "${SEND_EMAIL}" = "YES" ]; then
838 +
839 + if [ -n "${EMAIL_SENDER}" ]; then
840 + if [[ ${EMAIL_SENDER} =~ ^\".*\"\ \<.*\>$ ]]; then
841 + # the name includes double quotes
842 + sender_email="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1)"
843 + sender_name="$(echo "${EMAIL_SENDER}" | cut -d '"' -f 2)"
844 + elif [[ ${EMAIL_SENDER} =~ ^\'.*\'\ \<.*\>$ ]]; then
845 + # the name includes single quotes
846 + sender_email="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1)"
847 + sender_name="$(echo "${EMAIL_SENDER}" | cut -d "'" -f 2)"
848 + elif [[ ${EMAIL_SENDER} =~ ^.*\ \<.*\>$ ]]; then
849 + # the name does not have any quotes
850 + sender_email="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1)"
851 + sender_name="$(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)"
852 + fi
853 + fi
854 +
855 + [ -n "${sender_email}" ] && opts+=(-f "${sender_email}")
856 + [ -n "${sender_name}" ] && opts+=(-F "${sender_name}")
857 +
858 + if [ "${debug}" = "1" ]; then
859 + echo >&2 "--- BEGIN sendmail command ---"
860 + printf >&2 "%q " "${sendmail}" -t "${opts[@]}"
861 + echo >&2
862 + echo >&2 "--- END sendmail command ---"
863 + fi
864 +
865 + "${sendmail}" -t "${opts[@]}"
866 + ret=$?
867 +
868 + if [ ${ret} -eq 0 ]; then
869 + info "sent email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}'"
870 + return 0
871 + else
872 + error "failed to send email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}' with error code ${ret}."
873 + return 1
874 + fi
875 + fi
876 +
877 + return 1
878 }
879
880 # -----------------------------------------------------------------------------
881 # pushover sender
882
883 send_pushover() {
883 - local apptoken="${1}" usertokens="${2}" when="${3}" url="${4}" status="${5}" title="${6}" message="${7}" httpcode sent=0 user priority
884 -
885 - if [ "${SEND_PUSHOVER}" = "YES" ] && [ -n "${apptoken}" ] && [ -n "${usertokens}" ] && [ -n "${title}" ] && [ -n "${message}" ]; then
886 -
887 - # https://pushover.net/api
888 - priority=-2
889 - case "${status}" in
890 - CLEAR) priority=-1 ;; # low priority: no sound or vibration
891 - WARNING) priority=0 ;; # normal priority: respect quiet hours
892 - CRITICAL) priority=1 ;; # high priority: bypass quiet hours
893 - *) priority=-2 ;; # lowest priority: no notification at all
894 - esac
895 -
896 - for user in ${usertokens}; do
897 - httpcode=$(docurl \
898 - --form-string "token=${apptoken}" \
899 - --form-string "user=${user}" \
900 - --form-string "html=1" \
901 - --form-string "title=${title}" \
902 - --form-string "message=${message}" \
903 - --form-string "timestamp=${when}" \
904 - --form-string "url=${url}" \
905 - --form-string "url_title=Open netdata dashboard to view the alarm" \
906 - --form-string "priority=${priority}" \
907 - https://api.pushover.net/1/messages.json)
908 -
909 - if [ "${httpcode}" = "200" ]; then
910 - info "sent pushover notification for: ${host} ${chart}.${name} is ${status} to '${user}'"
911 - sent=$((sent + 1))
912 - else
913 - error "failed to send pushover notification for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
914 - fi
915 - done
916 -
917 - [ ${sent} -gt 0 ] && return 0
918 - fi
919 -
920 - return 1
884 + local apptoken="${1}" usertokens="${2}" when="${3}" url="${4}" status="${5}" title="${6}" message="${7}" httpcode sent=0 user priority
885 +
886 + if [ "${SEND_PUSHOVER}" = "YES" ] && [ -n "${apptoken}" ] && [ -n "${usertokens}" ] && [ -n "${title}" ] && [ -n "${message}" ]; then
887 +
888 + # https://pushover.net/api
889 + priority=-2
890 + case "${status}" in
891 + CLEAR) priority=-1 ;; # low priority: no sound or vibration
892 + WARNING) priority=0 ;; # normal priority: respect quiet hours
893 + CRITICAL) priority=1 ;; # high priority: bypass quiet hours
894 + *) priority=-2 ;; # lowest priority: no notification at all
895 + esac
896 +
897 + for user in ${usertokens}; do
898 + httpcode=$(docurl \
899 + --form-string "token=${apptoken}" \
900 + --form-string "user=${user}" \
901 + --form-string "html=1" \
902 + --form-string "title=${title}" \
903 + --form-string "message=${message}" \
904 + --form-string "timestamp=${when}" \
905 + --form-string "url=${url}" \
906 + --form-string "url_title=Open netdata dashboard to view the alarm" \
907 + --form-string "priority=${priority}" \
908 + https://api.pushover.net/1/messages.json)
909 +
910 + if [ "${httpcode}" = "200" ]; then
911 + info "sent pushover notification for: ${host} ${chart}.${name} is ${status} to '${user}'"
912 + sent=$((sent + 1))
913 + else
914 + error "failed to send pushover notification for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
915 + fi
916 + done
917 +
918 + [ ${sent} -gt 0 ] && return 0
919 + fi
920 +
921 + return 1
922 }
923
924 # -----------------------------------------------------------------------------
925 # pushbullet sender
926
927 send_pushbullet() {
927 - local userapikey="${1}" source_device="${2}" recipients="${3}" url="${4}" title="${5}" message="${6}" httpcode sent=0 user
928 - if [ "${SEND_PUSHBULLET}" = "YES" ] && [ -n "${userapikey}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
929 - #https://docs.pushbullet.com/#create-push
930 - for user in ${recipients}; do
931 - httpcode=$(docurl \
932 - --header 'Access-Token: '${userapikey}'' \
933 - --header 'Content-Type: application/json' \
934 - --data-binary @<(
935 - cat <<EOF
928 + local userapikey="${1}" source_device="${2}" recipients="${3}" url="${4}" title="${5}" message="${6}" httpcode sent=0 user
929 + if [ "${SEND_PUSHBULLET}" = "YES" ] && [ -n "${userapikey}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
930 + #https://docs.pushbullet.com/#create-push
931 + for user in ${recipients}; do
932 + httpcode=$(docurl \
933 + --header 'Access-Token: '${userapikey}'' \
934 + --header 'Content-Type: application/json' \
935 + --data-binary @<(
936 + cat <<EOF
937 {"title": "${title}",
938 "type": "link",
939 "email": "${user}",
@@ -940,62 +941,106 @@ send_pushbullet() {
941 "url": "${url}",
942 "source_device_iden": "${source_device}"}
943 EOF
943 - ) "https://api.pushbullet.com/v2/pushes" -X POST)
944 + ) "https://api.pushbullet.com/v2/pushes" -X POST)
945
945 - if [ "${httpcode}" = "200" ]; then
946 - info "sent pushbullet notification for: ${host} ${chart}.${name} is ${status} to '${user}'"
947 - sent=$((sent + 1))
948 - else
949 - error "failed to send pushbullet notification for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
950 - fi
951 - done
946 + if [ "${httpcode}" = "200" ]; then
947 + info "sent pushbullet notification for: ${host} ${chart}.${name} is ${status} to '${user}'"
948 + sent=$((sent + 1))
949 + else
950 + error "failed to send pushbullet notification for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
951 + fi
952 + done
953
953 - [ ${sent} -gt 0 ] && return 0
954 - fi
954 + [ ${sent} -gt 0 ] && return 0
955 + fi
956
956 - return 1
957 + return 1
958 }
959
960 # -----------------------------------------------------------------------------
961 # kafka sender
962
963 send_kafka() {
963 - local httpcode sent=0
964 - if [ "${SEND_KAFKA}" = "YES" ]; then
965 - httpcode=$(docurl -X POST \
966 - --data "{host_ip:\"${KAFKA_SENDER_IP}\",when:${when},name:\"${name}\",chart:\"${chart}\",family:\"${family}\",status:\"${status}\",old_status:\"${old_status}\",value:${value},old_value:${old_value},duration:${duration},non_clear_duration:${non_clear_duration},units:\"${units}\",info:\"${info}\"}" \
967 - "${KAFKA_URL}")
968 -
969 - if [ "${httpcode}" = "204" ]; then
970 - info "sent kafka data for: ${host} ${chart}.${name} is ${status} and ip '${KAFKA_SENDER_IP}'"
971 - sent=$((sent + 1))
972 - else
973 - error "failed to send kafka data for: ${host} ${chart}.${name} is ${status} and ip '${KAFKA_SENDER_IP}' with HTTP response status code ${httpcode}."
974 - fi
975 -
976 - [ ${sent} -gt 0 ] && return 0
977 - fi
978 -
979 - return 1
964 + local httpcode sent=0
965 + if [ "${SEND_KAFKA}" = "YES" ]; then
966 + httpcode=$(docurl -X POST \
967 + --data "{host_ip:\"${KAFKA_SENDER_IP}\",when:${when},name:\"${name}\",chart:\"${chart}\",family:\"${family}\",status:\"${status}\",old_status:\"${old_status}\",value:${value},old_value:${old_value},duration:${duration},non_clear_duration:${non_clear_duration},units:\"${units}\",info:\"${info}\"}" \
968 + "${KAFKA_URL}")
969 +
970 + if [ "${httpcode}" = "204" ]; then
971 + info "sent kafka data for: ${host} ${chart}.${name} is ${status} and ip '${KAFKA_SENDER_IP}'"
972 + sent=$((sent + 1))
973 + else
974 + error "failed to send kafka data for: ${host} ${chart}.${name} is ${status} and ip '${KAFKA_SENDER_IP}' with HTTP response status code ${httpcode}."
975 + fi
976 +
977 + [ ${sent} -gt 0 ] && return 0
978 + fi
979 +
980 + return 1
981 }
982
983 # -----------------------------------------------------------------------------
984 # pagerduty.com sender
985
986 send_pd() {
986 - local recipients="${1}" sent=0
987 - unset t
988 - case ${status} in
989 - CLEAR) t='resolve' ;;
990 - WARNING) t='trigger' ;;
991 - CRITICAL) t='trigger' ;;
992 - esac
993 -
994 - if [ ${SEND_PD} = "YES" ] && [ -n "${t}" ]; then
995 - for PD_SERVICE_KEY in ${recipients}; do
996 - d="${status} ${name} = ${value_string} - ${host}, ${family}"
997 - payload="$(
998 - cat <<EOF
987 + local recipients="${1}" sent=0 severity current_time payload url response_code
988 + unset t
989 + case ${status} in
990 + CLEAR) t='resolve' ; severity='info' ;;
991 + WARNING) t='trigger' ; severity='warning' ;;
992 + CRITICAL) t='trigger' ; severity='critical' ;;
993 + esac
994 +
995 + if [ ${SEND_PD} = "YES" ] && [ -n "${t}" ]; then
996 + if [ "$(uname)" == "Linux" ]; then
997 + current_time=$(date -d @${when} +'%Y-%m-%dT%H:%M:%S.000')
998 + else
999 + current_time=$(date -r ${when} +'%Y-%m-%dT%H:%M:%S.000')
1000 + fi
1001 + for PD_SERVICE_KEY in ${recipients}; do
1002 + d="${status} ${name} = ${value_string} - ${host}, ${family}"
1003 + if [ ${USE_PD_VERSION} = "2" ]; then
1004 + payload="$(
1005 + cat <<EOF
1006 + {
1007 + "payload" : {
1008 + "summary": "${info:0:1024}",
1009 + "source" : "${args_host}",
1010 + "severity" : "${severity}",
1011 + "timestamp" : "${current_time}",
1012 + "group" : "${family}",
1013 + "class" : "${chart}",
1014 + "custom_details": {
1015 + "value_w_units": "${value_string}",
1016 + "when": "${when}",
1017 + "duration" : "${duration}",
1018 + "roles": "${roles}",
1019 + "alarm_id" : "${alarm_id}",
1020 + "name" : "${name}",
1021 + "chart" : "${chart}",
1022 + "family" : "${family}",
1023 + "status" : "${status}",
1024 + "old_status" : "${old_status}",
1025 + "value" : "${value}",
1026 + "old_value" : "${old_value}",
1027 + "src" : "${src}",
1028 + "non_clear_duration" : "${non_clear_duration}",
1029 + "units" : "${units}",
1030 + "info" : "${info}"
1031 + }
1032 + },
1033 + "routing_key": "${PD_SERVICE_KEY}",
1034 + "event_action": "${t}",
1035 + "dedup_key": "${unique_id}"
1036 + }
1037 +EOF
1038 + )"
1039 + url="https://events.pagerduty.com/v2/enqueue"
1040 + response_code="202"
1041 + else
1042 + payload="$(
1043 + cat <<EOF
1044 {
1045 "service_key": "${PD_SERVICE_KEY}",
1046 "event_type": "${t}",
@@ -1021,195 +1066,198 @@ send_pd() {
1066 }
1067 }
1068 EOF
1024 - )"
1025 - httpcode=$(docurl -X POST --data "${payload}" "https://events.pagerduty.com/generic/2010-04-15/create_event.json")
1026 - if [ "${httpcode}" = "200" ]; then
1027 - info "sent pagerduty notification for: ${host} ${chart}.${name} is ${status}'"
1028 - sent=$((sent + 1))
1029 - else
1030 - error "failed to send pagerduty notification for: ${host} ${chart}.${name} is ${status}, with HTTP response status code ${httpcode}."
1031 - fi
1032 - done
1033 -
1034 - [ ${sent} -gt 0 ] && return 0
1035 - fi
1036 -
1037 - return 1
1069 + )"
1070 + url="https://events.pagerduty.com/generic/2010-04-15/create_event.json"
1071 + response_code="200"
1072 + fi
1073 + httpcode=$(docurl -X POST --data "${payload}" ${url})
1074 + if [ "${httpcode}" = "${response_code}" ]; then
1075 + info "sent pagerduty notification for: ${host} ${chart}.${name} is ${status}'"
1076 + sent=$((sent + 1))
1077 + else
1078 + error "failed to send pagerduty notification for: ${host} ${chart}.${name} is ${status}, with HTTP response status code ${httpcode}."
1079 + fi
1080 + done
1081 +
1082 + [ ${sent} -gt 0 ] && return 0
1083 + fi
1084 +
1085 + return 1
1086 }
1087
1088 # -----------------------------------------------------------------------------
1089 # twilio sender
1090
1091 send_twilio() {
1044 - local accountsid="${1}" accounttoken="${2}" twilionumber="${3}" recipients="${4}" title="${5}" message="${6}" httpcode sent=0 user
1045 - if [ "${SEND_TWILIO}" = "YES" ] && [ -n "${accountsid}" ] && [ -n "${accounttoken}" ] && [ -n "${twilionumber}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
1046 - #https://www.twilio.com/packages/labs/code/bash/twilio-sms
1047 - for user in ${recipients}; do
1048 - httpcode=$(docurl -X POST \
1049 - --data-urlencode "From=${twilionumber}" \
1050 - --data-urlencode "To=${user}" \
1051 - --data-urlencode "Body=${title} ${message}" \
1052 - -u "${accountsid}:${accounttoken}" \
1053 - "https://api.twilio.com/2010-04-01/Accounts/${accountsid}/Messages.json")
1054 -
1055 - if [ "${httpcode}" = "201" ]; then
1056 - info "sent Twilio SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1057 - sent=$((sent + 1))
1058 - else
1059 - error "failed to send Twilio SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
1060 - fi
1061 - done
1062 -
1063 - [ ${sent} -gt 0 ] && return 0
1064 - fi
1065 -
1066 - return 1
1092 + local accountsid="${1}" accounttoken="${2}" twilionumber="${3}" recipients="${4}" title="${5}" message="${6}" httpcode sent=0 user
1093 + if [ "${SEND_TWILIO}" = "YES" ] && [ -n "${accountsid}" ] && [ -n "${accounttoken}" ] && [ -n "${twilionumber}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
1094 + #https://www.twilio.com/packages/labs/code/bash/twilio-sms
1095 + for user in ${recipients}; do
1096 + httpcode=$(docurl -X POST \
1097 + --data-urlencode "From=${twilionumber}" \
1098 + --data-urlencode "To=${user}" \
1099 + --data-urlencode "Body=${title} ${message}" \
1100 + -u "${accountsid}:${accounttoken}" \
1101 + "https://api.twilio.com/2010-04-01/Accounts/${accountsid}/Messages.json")
1102 +
1103 + if [ "${httpcode}" = "201" ]; then
1104 + info "sent Twilio SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1105 + sent=$((sent + 1))
1106 + else
1107 + error "failed to send Twilio SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
1108 + fi
1109 + done
1110 +
1111 + [ ${sent} -gt 0 ] && return 0
1112 + fi
1113 +
1114 + return 1
1115 }
1116
1117 # -----------------------------------------------------------------------------
1118 # hipchat sender
1119
1120 send_hipchat() {
1073 - local authtoken="${1}" recipients="${2}" message="${3}" httpcode sent=0 room color msg_format notify
1074 -
1075 - # remove <small></small> from the message
1076 - message="${message//<small>/}"
1077 - message="${message//<\/small>/}"
1078 -
1079 - if [ "${SEND_HIPCHAT}" = "YES" ] && [ -n "${HIPCHAT_SERVER}" ] && [ -n "${authtoken}" ] && [ -n "${recipients}" ] && [ -n "${message}" ]; then
1080 - # Valid values: html, text.
1081 - # Defaults to 'html'.
1082 - msg_format="html"
1083 -
1084 - # Background color for message. Valid values: yellow, green, red, purple, gray, random. Defaults to 'yellow'.
1085 - case "${status}" in
1086 - WARNING) color="yellow" ;;
1087 - CRITICAL) color="red" ;;
1088 - CLEAR) color="green" ;;
1089 - *) color="gray" ;;
1090 - esac
1091 -
1092 - # Whether this message should trigger a user notification (change the tab color, play a sound, notify mobile phones, etc).
1093 - # Each recipient's notification preferences are taken into account.
1094 - # Defaults to false.
1095 - notify="true"
1096 -
1097 - for room in ${recipients}; do
1098 - httpcode=$(docurl -X POST \
1099 - -H "Content-type: application/json" \
1100 - -H "Authorization: Bearer ${authtoken}" \
1101 - -d "{\"color\": \"${color}\", \"from\": \"${host}\", \"message_format\": \"${msg_format}\", \"message\": \"${message}\", \"notify\": \"${notify}\"}" \
1102 - "https://${HIPCHAT_SERVER}/v2/room/${room}/notification")
1103 -
1104 - if [ "${httpcode}" = "204" ]; then
1105 - info "sent HipChat notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
1106 - sent=$((sent + 1))
1107 - else
1108 - error "failed to send HipChat notification for: ${host} ${chart}.${name} is ${status} to '${room}' with HTTP response status code ${httpcode}."
1109 - fi
1110 - done
1111 -
1112 - [ ${sent} -gt 0 ] && return 0
1113 - fi
1114 -
1115 - return 1
1121 + local authtoken="${1}" recipients="${2}" message="${3}" httpcode sent=0 room color msg_format notify
1122 +
1123 + # remove <small></small> from the message
1124 + message="${message//<small>/}"
1125 + message="${message//<\/small>/}"
1126 +
1127 + if [ "${SEND_HIPCHAT}" = "YES" ] && [ -n "${HIPCHAT_SERVER}" ] && [ -n "${authtoken}" ] && [ -n "${recipients}" ] && [ -n "${message}" ]; then
1128 + # Valid values: html, text.
1129 + # Defaults to 'html'.
1130 + msg_format="html"
1131 +
1132 + # Background color for message. Valid values: yellow, green, red, purple, gray, random. Defaults to 'yellow'.
1133 + case "${status}" in
1134 + WARNING) color="yellow" ;;
1135 + CRITICAL) color="red" ;;
1136 + CLEAR) color="green" ;;
1137 + *) color="gray" ;;
1138 + esac
1139 +
1140 + # Whether this message should trigger a user notification (change the tab color, play a sound, notify mobile phones, etc).
1141 + # Each recipient's notification preferences are taken into account.
1142 + # Defaults to false.
1143 + notify="true"
1144 +
1145 + for room in ${recipients}; do
1146 + httpcode=$(docurl -X POST \
1147 + -H "Content-type: application/json" \
1148 + -H "Authorization: Bearer ${authtoken}" \
1149 + -d "{\"color\": \"${color}\", \"from\": \"${host}\", \"message_format\": \"${msg_format}\", \"message\": \"${message}\", \"notify\": \"${notify}\"}" \
1150 + "https://${HIPCHAT_SERVER}/v2/room/${room}/notification")
1151 +
1152 + if [ "${httpcode}" = "204" ]; then
1153 + info "sent HipChat notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
1154 + sent=$((sent + 1))
1155 + else
1156 + error "failed to send HipChat notification for: ${host} ${chart}.${name} is ${status} to '${room}' with HTTP response status code ${httpcode}."
1157 + fi
1158 + done
1159 +
1160 + [ ${sent} -gt 0 ] && return 0
1161 + fi
1162 +
1163 + return 1
1164 }
1165
1166 # -----------------------------------------------------------------------------
1167 # messagebird sender
1168
1169 send_messagebird() {
1122 - local accesskey="${1}" messagebirdnumber="${2}" recipients="${3}" title="${4}" message="${5}" httpcode sent=0 user
1123 - if [ "${SEND_MESSAGEBIRD}" = "YES" ] && [ -n "${accesskey}" ] && [ -n "${messagebirdnumber}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
1124 - #https://developers.messagebird.com/docs/messaging
1125 - for user in ${recipients}; do
1126 - httpcode=$(docurl -X POST \
1127 - --data-urlencode "originator=${messagebirdnumber}" \
1128 - --data-urlencode "recipients=${user}" \
1129 - --data-urlencode "body=${title} ${message}" \
1130 - --data-urlencode "datacoding=auto" \
1131 - -H "Authorization: AccessKey ${accesskey}" \
1132 - "https://rest.messagebird.com/messages")
1133 -
1134 - if [ "${httpcode}" = "201" ]; then
1135 - info "sent Messagebird SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1136 - sent=$((sent + 1))
1137 - else
1138 - error "failed to send Messagebird SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
1139 - fi
1140 - done
1141 -
1142 - [ ${sent} -gt 0 ] && return 0
1143 - fi
1144 -
1145 - return 1
1170 + local accesskey="${1}" messagebirdnumber="${2}" recipients="${3}" title="${4}" message="${5}" httpcode sent=0 user
1171 + if [ "${SEND_MESSAGEBIRD}" = "YES" ] && [ -n "${accesskey}" ] && [ -n "${messagebirdnumber}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
1172 + #https://developers.messagebird.com/docs/messaging
1173 + for user in ${recipients}; do
1174 + httpcode=$(docurl -X POST \
1175 + --data-urlencode "originator=${messagebirdnumber}" \
1176 + --data-urlencode "recipients=${user}" \
1177 + --data-urlencode "body=${title} ${message}" \
1178 + --data-urlencode "datacoding=auto" \
1179 + -H "Authorization: AccessKey ${accesskey}" \
1180 + "https://rest.messagebird.com/messages")
1181 +
1182 + if [ "${httpcode}" = "201" ]; then
1183 + info "sent Messagebird SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1184 + sent=$((sent + 1))
1185 + else
1186 + error "failed to send Messagebird SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
1187 + fi
1188 + done
1189 +
1190 + [ ${sent} -gt 0 ] && return 0
1191 + fi
1192 +
1193 + return 1
1194 }
1195
1196 # -----------------------------------------------------------------------------
1197 # kavenegar sender
1198
1199 send_kavenegar() {
1152 - local API_KEY="${1}" kavenegarsender="${2}" recipients="${3}" title="${4}" message="${5}" httpcode sent=0 user
1153 - if [ "${SEND_KAVENEGAR}" = "YES" ] && [ -n "${API_KEY}" ] && [ -n "${kavenegarsender}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
1154 - # http://api.kavenegar.com/v1/{API-KEY}/sms/send.json
1155 - for user in ${recipients}; do
1156 - httpcode=$(docurl -X POST http://api.kavenegar.com/v1/${API_KEY}/sms/send.json \
1157 - --data-urlencode "sender=${kavenegarsender}" \
1158 - --data-urlencode "receptor=${user}" \
1159 - --data-urlencode "message=${title} ${message}")
1160 -
1161 - if [ "${httpcode}" = "200" ]; then
1162 - info "sent Kavenegar SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1163 - sent=$((sent + 1))
1164 - else
1165 - error "failed to send Kavenegar SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
1166 - fi
1167 - done
1168 -
1169 - [ ${sent} -gt 0 ] && return 0
1170 - fi
1171 -
1172 - return 1
1200 + local API_KEY="${1}" kavenegarsender="${2}" recipients="${3}" title="${4}" message="${5}" httpcode sent=0 user
1201 + if [ "${SEND_KAVENEGAR}" = "YES" ] && [ -n "${API_KEY}" ] && [ -n "${kavenegarsender}" ] && [ -n "${recipients}" ] && [ -n "${message}" ] && [ -n "${title}" ]; then
1202 + # http://api.kavenegar.com/v1/{API-KEY}/sms/send.json
1203 + for user in ${recipients}; do
1204 + httpcode=$(docurl -X POST http://api.kavenegar.com/v1/${API_KEY}/sms/send.json \
1205 + --data-urlencode "sender=${kavenegarsender}" \
1206 + --data-urlencode "receptor=${user}" \
1207 + --data-urlencode "message=${title} ${message}")
1208 +
1209 + if [ "${httpcode}" = "200" ]; then
1210 + info "sent Kavenegar SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1211 + sent=$((sent + 1))
1212 + else
1213 + error "failed to send Kavenegar SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with HTTP response status code ${httpcode}."
1214 + fi
1215 + done
1216 +
1217 + [ ${sent} -gt 0 ] && return 0
1218 + fi
1219 +
1220 + return 1
1221 }
1222
1223 # -----------------------------------------------------------------------------
1224 # telegram sender
1225
1226 send_telegram() {
1179 - local bottoken="${1}" chatids="${2}" message="${3}" httpcode sent=0 chatid emoji disableNotification=""
1180 -
1181 - if [ "${status}" = "CLEAR" ]; then disableNotification="--data-urlencode disable_notification=true"; fi
1182 -
1183 - case "${status}" in
1184 - WARNING) emoji="⚠️" ;;
1185 - CRITICAL) emoji="🔴" ;;
1186 - CLEAR) emoji="✅" ;;
1187 - *) emoji="⚪️" ;;
1188 - esac
1189 -
1190 - if [ "${SEND_TELEGRAM}" = "YES" ] && [ -n "${bottoken}" ] && [ -n "${chatids}" ] && [ -n "${message}" ]; then
1191 - for chatid in ${chatids}; do
1192 - # https://core.telegram.org/bots/api#sendmessage
1193 - httpcode=$(docurl ${disableNotification} \
1194 - --data-urlencode "parse_mode=HTML" \
1195 - --data-urlencode "disable_web_page_preview=true" \
1196 - --data-urlencode "text=${emoji} ${message}" \
1197 - "https://api.telegram.org/bot${bottoken}/sendMessage?chat_id=${chatid}")
1198 -
1199 - if [ "${httpcode}" = "200" ]; then
1200 - info "sent telegram notification for: ${host} ${chart}.${name} is ${status} to '${chatid}'"
1201 - sent=$((sent + 1))
1202 - elif [ "${httpcode}" = "401" ]; then
1203 - error "failed to send telegram notification for: ${host} ${chart}.${name} is ${status} to '${chatid}': Wrong bot token."
1204 - else
1205 - error "failed to send telegram notification for: ${host} ${chart}.${name} is ${status} to '${chatid}' with HTTP response status code ${httpcode}."
1206 - fi
1207 - done
1208 -
1209 - [ ${sent} -gt 0 ] && return 0
1210 - fi
1211 -
1212 - return 1
1227 + local bottoken="${1}" chatids="${2}" message="${3}" httpcode sent=0 chatid emoji disableNotification=""
1228 +
1229 + if [ "${status}" = "CLEAR" ]; then disableNotification="--data-urlencode disable_notification=true"; fi
1230 +
1231 + case "${status}" in
1232 + WARNING) emoji="⚠️" ;;
1233 + CRITICAL) emoji="🔴" ;;
1234 + CLEAR) emoji="✅" ;;
1235 + *) emoji="⚪️" ;;
1236 + esac
1237 +
1238 + if [ "${SEND_TELEGRAM}" = "YES" ] && [ -n "${bottoken}" ] && [ -n "${chatids}" ] && [ -n "${message}" ]; then
1239 + for chatid in ${chatids}; do
1240 + # https://core.telegram.org/bots/api#sendmessage
1241 + httpcode=$(docurl ${disableNotification} \
1242 + --data-urlencode "parse_mode=HTML" \
1243 + --data-urlencode "disable_web_page_preview=true" \
1244 + --data-urlencode "text=${emoji} ${message}" \
1245 + "https://api.telegram.org/bot${bottoken}/sendMessage?chat_id=${chatid}")
1246 +
1247 + if [ "${httpcode}" = "200" ]; then
1248 + info "sent telegram notification for: ${host} ${chart}.${name} is ${status} to '${chatid}'"
1249 + sent=$((sent + 1))
1250 + elif [ "${httpcode}" = "401" ]; then
1251 + error "failed to send telegram notification for: ${host} ${chart}.${name} is ${status} to '${chatid}': Wrong bot token."
1252 + else
1253 + error "failed to send telegram notification for: ${host} ${chart}.${name} is ${status} to '${chatid}' with HTTP response status code ${httpcode}."
1254 + fi
1255 + done
1256 +
1257 + [ ${sent} -gt 0 ] && return 0
1258 + fi
1259 +
1260 + return 1
1261 }
1262
1263 # -----------------------------------------------------------------------------
@@ -1217,22 +1265,22 @@ send_telegram() {
1265
1266 send_msteam() {
1267
1220 - local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1268 + local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1269
1222 - [ "${SEND_MSTEAM}" != "YES" ] && return 1
1270 + [ "${SEND_MSTEAM}" != "YES" ] && return 1
1271
1224 - case "${status}" in
1225 - WARNING) icon="${MSTEAM_ICON_WARNING}" && color="${MSTEAM_COLOR_WARNING}" ;;
1226 - CRITICAL) icon="${MSTEAM_ICON_CRITICAL}" && color="${MSTEAM_COLOR_CRITICAL}" ;;
1227 - CLEAR) icon="${MSTEAM_ICON_CLEAR}" && color="${MSTEAM_COLOR_CLEAR}" ;;
1228 - *) icon="${MSTEAM_ICON_DEFAULT}" && color="${MSTEAM_COLOR_DEFAULT}" ;;
1229 - esac
1272 + case "${status}" in
1273 + WARNING) icon="${MSTEAM_ICON_WARNING}" && color="${MSTEAM_COLOR_WARNING}" ;;
1274 + CRITICAL) icon="${MSTEAM_ICON_CRITICAL}" && color="${MSTEAM_COLOR_CRITICAL}" ;;
1275 + CLEAR) icon="${MSTEAM_ICON_CLEAR}" && color="${MSTEAM_COLOR_CLEAR}" ;;
1276 + *) icon="${MSTEAM_ICON_DEFAULT}" && color="${MSTEAM_COLOR_DEFAULT}" ;;
1277 + esac
1278
1231 - for channel in ${channels}; do
1232 - ## More details are available here regarding the payload syntax options : https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference
1233 - ## Online designer : https://acdesignerbeta.azurewebsites.net/
1234 - payload="$(
1235 - cat <<EOF
1279 + for channel in ${channels}; do
1280 + ## More details are available here regarding the payload syntax options : https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference
1281 + ## Online designer : https://acdesignerbeta.azurewebsites.net/
1282 + payload="$(
1283 + cat <<EOF
1284 {
1285 "@context": "http://schema.org/extensions",
1286 "@type": "MessageCard",
@@ -1250,55 +1298,55 @@ send_msteam() {
1298 ]
1299 }
1300 EOF
1253 - )"
1301 + )"
1302
1255 - # Replacing in the webhook CHANNEL string by the MS Teams channel name from conf file.
1256 - webhook="${webhook//CHANNEL/${channel}}"
1303 + # Replacing in the webhook CHANNEL string by the MS Teams channel name from conf file.
1304 + webhook="${webhook//CHANNEL/${channel}}"
1305
1258 - httpcode=$(docurl -H "Content-Type: application/json" -d "${payload}" "${webhook}")
1306 + httpcode=$(docurl -H "Content-Type: application/json" -d "${payload}" "${webhook}")
1307
1260 - if [ "${httpcode}" = "200" ]; then
1261 - info "sent Microsoft team notification for: ${host} ${chart}.${name} is ${status} to '${webhook}'"
1262 - sent=$((sent + 1))
1263 - else
1264 - error "failed to send Microsoft team notification for: ${host} ${chart}.${name} is ${status} to '${webhook}', with HTTP response status code ${httpcode}."
1265 - fi
1266 - done
1308 + if [ "${httpcode}" = "200" ]; then
1309 + info "sent Microsoft team notification for: ${host} ${chart}.${name} is ${status} to '${webhook}'"
1310 + sent=$((sent + 1))
1311 + else
1312 + error "failed to send Microsoft team notification for: ${host} ${chart}.${name} is ${status} to '${webhook}', with HTTP response status code ${httpcode}."
1313 + fi
1314 + done
1315
1268 - [ ${sent} -gt 0 ] && return 0
1316 + [ ${sent} -gt 0 ] && return 0
1317
1270 - return 1
1318 + return 1
1319 }
1320
1321 # slack sender
1322
1323 send_slack() {
1276 - local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1277 -
1278 - [ "${SEND_SLACK}" != "YES" ] && return 1
1279 -
1280 - case "${status}" in
1281 - WARNING) color="warning" ;;
1282 - CRITICAL) color="danger" ;;
1283 - CLEAR) color="good" ;;
1284 - *) color="#777777" ;;
1285 - esac
1286 -
1287 - for channel in ${channels}; do
1288 - # Default entry in the recipient is without a hash in front (backwards-compatible). Accept specification of channel or user.
1289 - if [ "${channel::1}" != "#" ] && [ "${channel::1}" != "@" ]; then channel="#$channel"; fi
1290 -
1291 - # If channel is equal to "#" then do not send the channel attribute at all. Slack also defines channels and users in webhooks.
1292 - if [ "${channel}" = "#" ]; then
1293 - ch=""
1294 - chstr="without specifying a channel"
1295 - else
1296 - ch="\"channel\": \"${channel}\","
1297 - chstr="to '${channel}'"
1298 - fi
1299 -
1300 - payload="$(
1301 - cat <<EOF
1324 + local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1325 +
1326 + [ "${SEND_SLACK}" != "YES" ] && return 1
1327 +
1328 + case "${status}" in
1329 + WARNING) color="warning" ;;
1330 + CRITICAL) color="danger" ;;
1331 + CLEAR) color="good" ;;
1332 + *) color="#777777" ;;
1333 + esac
1334 +
1335 + for channel in ${channels}; do
1336 + # Default entry in the recipient is without a hash in front (backwards-compatible). Accept specification of channel or user.
1337 + if [ "${channel::1}" != "#" ] && [ "${channel::1}" != "@" ]; then channel="#$channel"; fi
1338 +
1339 + # If channel is equal to "#" then do not send the channel attribute at all. Slack also defines channels and users in webhooks.
1340 + if [ "${channel}" = "#" ]; then
1341 + ch=""
1342 + chstr="without specifying a channel"
1343 + else
1344 + ch="\"channel\": \"${channel}\","
1345 + chstr="to '${channel}'"
1346 + fi
1347 +
1348 + payload="$(
1349 + cat <<EOF
1350 {
1351 $ch
1352 "username": "netdata on ${host}",
@@ -1328,40 +1376,40 @@ send_slack() {
1376 ]
1377 }
1378 EOF
1331 - )"
1379 + )"
1380
1333 - httpcode=$(docurl -X POST --data-urlencode "payload=${payload}" "${webhook}")
1334 - if [ "${httpcode}" = "200" ]; then
1335 - info "sent slack notification for: ${host} ${chart}.${name} is ${status} ${chstr}"
1336 - sent=$((sent + 1))
1337 - else
1338 - error "failed to send slack notification for: ${host} ${chart}.${name} is ${status} ${chstr}, with HTTP response status code ${httpcode}."
1339 - fi
1340 - done
1381 + httpcode=$(docurl -X POST --data-urlencode "payload=${payload}" "${webhook}")
1382 + if [ "${httpcode}" = "200" ]; then
1383 + info "sent slack notification for: ${host} ${chart}.${name} is ${status} ${chstr}"
1384 + sent=$((sent + 1))
1385 + else
1386 + error "failed to send slack notification for: ${host} ${chart}.${name} is ${status} ${chstr}, with HTTP response status code ${httpcode}."
1387 + fi
1388 + done
1389
1342 - [ ${sent} -gt 0 ] && return 0
1390 + [ ${sent} -gt 0 ] && return 0
1391
1344 - return 1
1392 + return 1
1393 }
1394
1395 # -----------------------------------------------------------------------------
1396 # rocketchat sender
1397
1398 send_rocketchat() {
1351 - local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1399 + local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1400
1353 - [ "${SEND_ROCKETCHAT}" != "YES" ] && return 1
1401 + [ "${SEND_ROCKETCHAT}" != "YES" ] && return 1
1402
1355 - case "${status}" in
1356 - WARNING) color="warning" ;;
1357 - CRITICAL) color="danger" ;;
1358 - CLEAR) color="good" ;;
1359 - *) color="#777777" ;;
1360 - esac
1403 + case "${status}" in
1404 + WARNING) color="warning" ;;
1405 + CRITICAL) color="danger" ;;
1406 + CLEAR) color="good" ;;
1407 + *) color="#777777" ;;
1408 + esac
1409
1362 - for channel in ${channels}; do
1363 - payload="$(
1364 - cat <<EOF
1410 + for channel in ${channels}; do
1411 + payload="$(
1412 + cat <<EOF
1413 {
1414 "channel": "#${channel}",
1415 "alias": "netdata on ${host}",
@@ -1391,48 +1439,48 @@ send_rocketchat() {
1439 ]
1440 }
1441 EOF
1394 - )"
1442 + )"
1443
1396 - httpcode=$(docurl -X POST --data-urlencode "payload=${payload}" "${webhook}")
1397 - if [ "${httpcode}" = "200" ]; then
1398 - info "sent rocketchat notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1399 - sent=$((sent + 1))
1400 - else
1401 - error "failed to send rocketchat notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1402 - fi
1403 - done
1444 + httpcode=$(docurl -X POST --data-urlencode "payload=${payload}" "${webhook}")
1445 + if [ "${httpcode}" = "200" ]; then
1446 + info "sent rocketchat notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1447 + sent=$((sent + 1))
1448 + else
1449 + error "failed to send rocketchat notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1450 + fi
1451 + done
1452
1405 - [ ${sent} -gt 0 ] && return 0
1453 + [ ${sent} -gt 0 ] && return 0
1454
1407 - return 1
1455 + return 1
1456 }
1457
1458 # -----------------------------------------------------------------------------
1459 # alerta sender
1460
1461 send_alerta() {
1414 - local webhook="${1}" channels="${2}" httpcode sent=0 channel severity resource event payload auth
1415 -
1416 - [ "${SEND_ALERTA}" != "YES" ] && return 1
1417 -
1418 - case "${status}" in
1419 - CRITICAL) severity="critical" ;;
1420 - WARNING) severity="warning" ;;
1421 - CLEAR) severity="cleared" ;;
1422 - *) severity="indeterminate" ;;
1423 - esac
1424 -
1425 - if [[ ${chart} == httpcheck* ]]; then
1426 - resource=$chart
1427 - event=$name
1428 - else
1429 - resource="${host}:${family}"
1430 - event="${chart}.${name}"
1431 - fi
1432 -
1433 - for channel in ${channels}; do
1434 - payload="$(
1435 - cat <<EOF
1462 + local webhook="${1}" channels="${2}" httpcode sent=0 channel severity resource event payload auth
1463 +
1464 + [ "${SEND_ALERTA}" != "YES" ] && return 1
1465 +
1466 + case "${status}" in
1467 + CRITICAL) severity="critical" ;;
1468 + WARNING) severity="warning" ;;
1469 + CLEAR) severity="cleared" ;;
1470 + *) severity="indeterminate" ;;
1471 + esac
1472 +
1473 + if [[ ${chart} == httpcheck* ]]; then
1474 + resource=$chart
1475 + event=$name
1476 + else
1477 + resource="${host}:${family}"
1478 + event="${chart}.${name}"
1479 + fi
1480 +
1481 + for channel in ${channels}; do
1482 + payload="$(
1483 + cat <<EOF
1484 {
1485 "resource": "${resource}",
1486 "event": "${event}",
@@ -1456,46 +1504,46 @@ send_alerta() {
1504 "rawData": "${BASH_ARGV[@]}"
1505 }
1506 EOF
1459 - )"
1507 + )"
1508
1461 - if [ -n "${ALERTA_API_KEY}" ]; then
1462 - auth="Key ${ALERTA_API_KEY}"
1463 - fi
1509 + if [ -n "${ALERTA_API_KEY}" ]; then
1510 + auth="Key ${ALERTA_API_KEY}"
1511 + fi
1512
1465 - httpcode=$(docurl -X POST "${webhook}/alert" -H "Content-Type: application/json" -H "Authorization: $auth" --data "${payload}")
1513 + httpcode=$(docurl -X POST "${webhook}/alert" -H "Content-Type: application/json" -H "Authorization: $auth" --data "${payload}")
1514
1467 - if [ "${httpcode}" = "200" ] || [ "${httpcode}" = "201" ]; then
1468 - info "sent alerta notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1469 - sent=$((sent + 1))
1470 - elif [ "${httpcode}" = "202" ]; then
1471 - info "suppressed alerta notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1472 - else
1473 - error "failed to send alerta notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1474 - fi
1475 - done
1515 + if [ "${httpcode}" = "200" ] || [ "${httpcode}" = "201" ]; then
1516 + info "sent alerta notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1517 + sent=$((sent + 1))
1518 + elif [ "${httpcode}" = "202" ]; then
1519 + info "suppressed alerta notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1520 + else
1521 + error "failed to send alerta notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1522 + fi
1523 + done
1524
1477 - [ ${sent} -gt 0 ] && return 0
1525 + [ ${sent} -gt 0 ] && return 0
1526
1479 - return 1
1527 + return 1
1528 }
1529
1530 # -----------------------------------------------------------------------------
1531 # flock sender
1532
1533 send_flock() {
1486 - local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1534 + local webhook="${1}" channels="${2}" httpcode sent=0 channel color payload
1535
1488 - [ "${SEND_FLOCK}" != "YES" ] && return 1
1536 + [ "${SEND_FLOCK}" != "YES" ] && return 1
1537
1490 - case "${status}" in
1491 - WARNING) color="warning" ;;
1492 - CRITICAL) color="danger" ;;
1493 - CLEAR) color="good" ;;
1494 - *) color="#777777" ;;
1495 - esac
1538 + case "${status}" in
1539 + WARNING) color="warning" ;;
1540 + CRITICAL) color="danger" ;;
1541 + CLEAR) color="good" ;;
1542 + *) color="#777777" ;;
1543 + esac
1544
1497 - for channel in ${channels}; do
1498 - httpcode=$(docurl -X POST "${webhook}" -H "Content-Type: application/json" -d "{
1545 + for channel in ${channels}; do
1546 + httpcode=$(docurl -X POST "${webhook}" -H "Content-Type: application/json" -d "{
1547 \"sendAs\": {
1548 \"name\" : \"netdata on ${host}\",
1549 \"profileImage\" : \"${images_base_url}/images/banner-icon-144x144.png\"
@@ -1519,40 +1567,40 @@ send_flock() {
1567 }
1568 ]
1569 }")
1522 - if [ "${httpcode}" = "200" ]; then
1523 - info "sent flock notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1524 - sent=$((sent + 1))
1525 - else
1526 - error "failed to send flock notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1527 - fi
1528 - done
1570 + if [ "${httpcode}" = "200" ]; then
1571 + info "sent flock notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1572 + sent=$((sent + 1))
1573 + else
1574 + error "failed to send flock notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1575 + fi
1576 + done
1577
1530 - [ ${sent} -gt 0 ] && return 0
1578 + [ ${sent} -gt 0 ] && return 0
1579
1532 - return 1
1580 + return 1
1581 }
1582
1583 # -----------------------------------------------------------------------------
1584 # discord sender
1585
1586 send_discord() {
1539 - local webhook="${1}/slack" channels="${2}" httpcode sent=0 channel color payload username
1587 + local webhook="${1}/slack" channels="${2}" httpcode sent=0 channel color payload username
1588
1541 - [ "${SEND_DISCORD}" != "YES" ] && return 1
1589 + [ "${SEND_DISCORD}" != "YES" ] && return 1
1590
1543 - case "${status}" in
1544 - WARNING) color="warning" ;;
1545 - CRITICAL) color="danger" ;;
1546 - CLEAR) color="good" ;;
1547 - *) color="#777777" ;;
1548 - esac
1591 + case "${status}" in
1592 + WARNING) color="warning" ;;
1593 + CRITICAL) color="danger" ;;
1594 + CLEAR) color="good" ;;
1595 + *) color="#777777" ;;
1596 + esac
1597
1550 - for channel in ${channels}; do
1551 - username="netdata on ${host}"
1552 - [ ${#username} -gt 32 ] && username="${username:0:29}..."
1598 + for channel in ${channels}; do
1599 + username="netdata on ${host}"
1600 + [ ${#username} -gt 32 ] && username="${username:0:29}..."
1601
1554 - payload="$(
1555 - cat <<EOF
1602 + payload="$(
1603 + cat <<EOF
1604 {
1605 "channel": "#${channel}",
1606 "username": "${username}",
@@ -1578,285 +1626,285 @@ send_discord() {
1626 ]
1627 }
1628 EOF
1581 - )"
1629 + )"
1630
1583 - httpcode=$(docurl -X POST --data-urlencode "payload=${payload}" "${webhook}")
1584 - if [ "${httpcode}" = "200" ]; then
1585 - info "sent discord notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1586 - sent=$((sent + 1))
1587 - else
1588 - error "failed to send discord notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1589 - fi
1590 - done
1631 + httpcode=$(docurl -X POST --data-urlencode "payload=${payload}" "${webhook}")
1632 + if [ "${httpcode}" = "200" ]; then
1633 + info "sent discord notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
1634 + sent=$((sent + 1))
1635 + else
1636 + error "failed to send discord notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP response status code ${httpcode}."
1637 + fi
1638 + done
1639
1592 - [ ${sent} -gt 0 ] && return 0
1640 + [ ${sent} -gt 0 ] && return 0
1641
1594 - return 1
1642 + return 1
1643 }
1644
1645 # -----------------------------------------------------------------------------
1646 # fleep sender
1647
1648 send_fleep() {
1601 - local httpcode sent=0 webhooks="${1}" data message
1602 - if [ "${SEND_FLEEP}" = "YES" ]; then
1603 - message="${host} ${status_message}, \`${chart}\` (${family}), *${alarm}*\\n${info}"
1604 -
1605 - for hook in ${webhooks}; do
1606 - data="{ "
1607 - data="${data} 'message': '${message}', "
1608 - data="${data} 'user': '${FLEEP_SENDER}' "
1609 - data="${data} }"
1610 -
1611 - httpcode=$(docurl -X POST --data "${data}" "https://fleep.io/hook/${hook}")
1612 -
1613 - if [ "${httpcode}" = "200" ]; then
1614 - info "sent fleep data for: ${host} ${chart}.${name} is ${status} and user '${FLEEP_SENDER}'"
1615 - sent=$((sent + 1))
1616 - else
1617 - error "failed to send fleep data for: ${host} ${chart}.${name} is ${status} and user '${FLEEP_SENDER}' with HTTP response status code ${httpcode}."
1618 - fi
1619 - done
1620 -
1621 - [ ${sent} -gt 0 ] && return 0
1622 - fi
1623 -
1624 - return 1
1649 + local httpcode sent=0 webhooks="${1}" data message
1650 + if [ "${SEND_FLEEP}" = "YES" ]; then
1651 + message="${host} ${status_message}, \`${chart}\` (${family}), *${alarm}*\\n${info}"
1652 +
1653 + for hook in ${webhooks}; do
1654 + data="{ "
1655 + data="${data} 'message': '${message}', "
1656 + data="${data} 'user': '${FLEEP_SENDER}' "
1657 + data="${data} }"
1658 +
1659 + httpcode=$(docurl -X POST --data "${data}" "https://fleep.io/hook/${hook}")
1660 +
1661 + if [ "${httpcode}" = "200" ]; then
1662 + info "sent fleep data for: ${host} ${chart}.${name} is ${status} and user '${FLEEP_SENDER}'"
1663 + sent=$((sent + 1))
1664 + else
1665 + error "failed to send fleep data for: ${host} ${chart}.${name} is ${status} and user '${FLEEP_SENDER}' with HTTP response status code ${httpcode}."
1666 + fi
1667 + done
1668 +
1669 + [ ${sent} -gt 0 ] && return 0
1670 + fi
1671 +
1672 + return 1
1673 }
1674
1675 # -----------------------------------------------------------------------------
1676 # Prowl sender
1677
1678 send_prowl() {
1631 - local httpcode sent=0 data message keys prio=0 alarm_url event
1632 - if [ "${SEND_PROWL}" = "YES" ]; then
1633 - message="$(urlencode "${host} ${status_message}, \`${chart}\` (${family}), *${alarm}*\\n${info}")"
1634 - message="description=${message}"
1635 - keys="$(urlencode "$(echo "${1}" | tr ' ' ,)")"
1636 - keys="apikey=${keys}"
1637 - app="application=Netdata"
1638 -
1639 - case "${status}" in
1640 - CRITICAL)
1641 - prio=2
1642 - ;;
1643 - WARNING)
1644 - prio=1
1645 - ;;
1646 - esac
1647 - prio="priority=${prio}"
1648 -
1649 - alarm_url="$(urlencode ${goto_url})"
1650 - alarm_url="url=${alarm_url}"
1651 - event="$(urlencode "${host} ${status_message}")"
1652 - event="event=${event}"
1653 -
1654 - data="${keys}&${prio}&${alarm_url}&${app}&${event}&${message}"
1655 -
1656 - httpcode=$(docurl -X POST --data "${data}" "https://api.prowlapp.com/publicapi/add")
1657 -
1658 - if [ "${httpcode}" = "200" ]; then
1659 - info "sent prowl data for: ${host} ${chart}.${name} is ${status}"
1660 - sent=1
1661 - else
1662 - error "failed to send prowl data for: ${host} ${chart}.${name} is ${status} with with error code ${httpcode}."
1663 - fi
1664 -
1665 - [ ${sent} -gt 0 ] && return 0
1666 - fi
1667 -
1668 - return 1
1679 + local httpcode sent=0 data message keys prio=0 alarm_url event
1680 + if [ "${SEND_PROWL}" = "YES" ]; then
1681 + message="$(urlencode "${host} ${status_message}, \`${chart}\` (${family}), *${alarm}*\\n${info}")"
1682 + message="description=${message}"
1683 + keys="$(urlencode "$(echo "${1}" | tr ' ' ,)")"
1684 + keys="apikey=${keys}"
1685 + app="application=Netdata"
1686 +
1687 + case "${status}" in
1688 + CRITICAL)
1689 + prio=2
1690 + ;;
1691 + WARNING)
1692 + prio=1
1693 + ;;
1694 + esac
1695 + prio="priority=${prio}"
1696 +
1697 + alarm_url="$(urlencode ${goto_url})"
1698 + alarm_url="url=${alarm_url}"
1699 + event="$(urlencode "${host} ${status_message}")"
1700 + event="event=${event}"
1701 +
1702 + data="${keys}&${prio}&${alarm_url}&${app}&${event}&${message}"
1703 +
1704 + httpcode=$(docurl -X POST --data "${data}" "https://api.prowlapp.com/publicapi/add")
1705 +
1706 + if [ "${httpcode}" = "200" ]; then
1707 + info "sent prowl data for: ${host} ${chart}.${name} is ${status}"
1708 + sent=1
1709 + else
1710 + error "failed to send prowl data for: ${host} ${chart}.${name} is ${status} with with error code ${httpcode}."
1711 + fi
1712 +
1713 + [ ${sent} -gt 0 ] && return 0
1714 + fi
1715 +
1716 + return 1
1717 }
1718
1719 # -----------------------------------------------------------------------------
1720 # irc sender
1721
1722 send_irc() {
1675 - local NICKNAME="${1}" REALNAME="${2}" CHANNELS="${3}" NETWORK="${4}" SERVERNAME="${5}" MESSAGE="${6}" sent=0 channel color send_alarm reply_codes error
1676 -
1677 - if [ "${SEND_IRC}" = "YES" ] && [ -n "${NICKNAME}" ] && [ -n "${REALNAME}" ] && [ -n "${CHANNELS}" ] && [ -n "${NETWORK}" ] && [ -n "${SERVERNAME}" ]; then
1678 - case "${status}" in
1679 - WARNING) color="warning" ;;
1680 - CRITICAL) color="danger" ;;
1681 - CLEAR) color="good" ;;
1682 - *) color="#777777" ;;
1683 - esac
1684 -
1685 - SNDMESSAGE="${MESSAGE//$'\n'/", "}"
1686 - for CHANNEL in ${CHANNELS}; do
1687 - error=0
1688 - send_alarm=$(echo -e "USER ${NICKNAME} guest ${REALNAME} ${SERVERNAME}\\nNICK ${NICKNAME}\\nJOIN ${CHANNEL}\\nPRIVMSG ${CHANNEL} :${SNDMESSAGE}\\nQUIT\\n" \ | nc "${NETWORK}" 6667)
1689 - reply_codes=$(echo "${send_alarm}" | cut -d ' ' -f 2 | grep -o '[0-9]*')
1690 - for code in ${reply_codes}; do
1691 - if [ "${code}" -ge 400 ] && [ "${code}" -le 599 ]; then
1692 - error=1
1693 - break
1694 - fi
1695 - done
1696 -
1697 - if [ "${error}" -eq 0 ]; then
1698 - info "sent irc notification for: ${host} ${chart}.${name} is ${status} to '${CHANNEL}'"
1699 - sent=$((sent + 1))
1700 - else
1701 - error "failed to send irc notification for: ${host} ${chart}.${name} is ${status} to '${CHANNEL}', with error code ${code}."
1702 - fi
1703 - done
1704 - fi
1705 -
1706 - [ ${sent} -gt 0 ] && return 0
1707 -
1708 - return 1
1723 + local NICKNAME="${1}" REALNAME="${2}" CHANNELS="${3}" NETWORK="${4}" SERVERNAME="${5}" MESSAGE="${6}" sent=0 channel color send_alarm reply_codes error
1724 +
1725 + if [ "${SEND_IRC}" = "YES" ] && [ -n "${NICKNAME}" ] && [ -n "${REALNAME}" ] && [ -n "${CHANNELS}" ] && [ -n "${NETWORK}" ] && [ -n "${SERVERNAME}" ]; then
1726 + case "${status}" in
1727 + WARNING) color="warning" ;;
1728 + CRITICAL) color="danger" ;;
1729 + CLEAR) color="good" ;;
1730 + *) color="#777777" ;;
1731 + esac
1732 +
1733 + SNDMESSAGE="${MESSAGE//$'\n'/", "}"
1734 + for CHANNEL in ${CHANNELS}; do
1735 + error=0
1736 + send_alarm=$(echo -e "USER ${NICKNAME} guest ${REALNAME} ${SERVERNAME}\\nNICK ${NICKNAME}\\nJOIN ${CHANNEL}\\nPRIVMSG ${CHANNEL} :${SNDMESSAGE}\\nQUIT\\n" \ | nc "${NETWORK}" 6667)
1737 + reply_codes=$(echo "${send_alarm}" | cut -d ' ' -f 2 | grep -o '[0-9]*')
1738 + for code in ${reply_codes}; do
1739 + if [ "${code}" -ge 400 ] && [ "${code}" -le 599 ]; then
1740 + error=1
1741 + break
1742 + fi
1743 + done
1744 +
1745 + if [ "${error}" -eq 0 ]; then
1746 + info "sent irc notification for: ${host} ${chart}.${name} is ${status} to '${CHANNEL}'"
1747 + sent=$((sent + 1))
1748 + else
1749 + error "failed to send irc notification for: ${host} ${chart}.${name} is ${status} to '${CHANNEL}', with error code ${code}."
1750 + fi
1751 + done
1752 + fi
1753 +
1754 + [ ${sent} -gt 0 ] && return 0
1755 +
1756 + return 1
1757 }
1758
1759 # -----------------------------------------------------------------------------
1760 # Amazon SNS sender
1761
1762 send_awssns() {
1715 - local targets="${1}" message='' sent=0 region=''
1716 - local default_format="${status} on ${host} at ${date}: ${chart} ${value_string}"
1763 + local targets="${1}" message='' sent=0 region=''
1764 + local default_format="${status} on ${host} at ${date}: ${chart} ${value_string}"
1765
1718 - [ "${SEND_AWSSNS}" = "YES" ] || return 1
1766 + [ "${SEND_AWSSNS}" = "YES" ] || return 1
1767
1720 - message=${AWSSNS_MESSAGE_FORMAT:-${default_format}}
1768 + message=${AWSSNS_MESSAGE_FORMAT:-${default_format}}
1769
1722 - for target in ${targets}; do
1723 - # Extract the region from the target ARN. We need to explicitly specify the region so that it matches up correctly.
1724 - region="$(echo ${target} | cut -f 4 -d ':')"
1725 - if ${aws} sns publish --region "${region}" --subject "${host} ${status_message} - ${name//_/ } - ${chart}" --message "${message}" --target-arn ${target} &>/dev/null; then
1726 - info "sent Amazon SNS notification for: ${host} ${chart}.${name} is ${status} to '${target}'"
1727 - sent=$((sent + 1))
1728 - else
1729 - error "failed to send Amazon SNS notification for: ${host} ${chart}.${name} is ${status} to '${target}'"
1730 - fi
1731 - done
1770 + for target in ${targets}; do
1771 + # Extract the region from the target ARN. We need to explicitly specify the region so that it matches up correctly.
1772 + region="$(echo ${target} | cut -f 4 -d ':')"
1773 + if ${aws} sns publish --region "${region}" --subject "${host} ${status_message} - ${name//_/ } - ${chart}" --message "${message}" --target-arn ${target} &>/dev/null; then
1774 + info "sent Amazon SNS notification for: ${host} ${chart}.${name} is ${status} to '${target}'"
1775 + sent=$((sent + 1))
1776 + else
1777 + error "failed to send Amazon SNS notification for: ${host} ${chart}.${name} is ${status} to '${target}'"
1778 + fi
1779 + done
1780
1733 - [ ${sent} -gt 0 ] && return 0
1781 + [ ${sent} -gt 0 ] && return 0
1782
1735 - return 1
1783 + return 1
1784 }
1785
1786 # -----------------------------------------------------------------------------
1787 # Matrix sender
1788
1789 send_matrix() {
1742 - local homeserver="${1}" webhook accesstoken rooms="${2}" httpcode sent=0 payload
1743 -
1744 - [ "${SEND_MATRIX}" != "YES" ] && return 1
1745 - [ -z "${MATRIX_ACCESSTOKEN}" ] && return 1
1746 -
1747 - accesstoken="${MATRIX_ACCESSTOKEN}"
1748 -
1749 - case "${status}" in
1750 - WARNING) emoji="⚠️" ;;
1751 - CRITICAL) emoji="🔴" ;;
1752 - CLEAR) emoji="✅" ;;
1753 - *) emoji="⚪️" ;;
1754 - esac
1755 -
1756 - for room in ${rooms}; do
1757 - webhook="$homeserver/_matrix/client/r0/rooms/$(urlencode $room)/send/m.room.message?access_token=$accesstoken"
1758 - payload="$(
1759 - cat <<EOF
1760 - {
1761 - "msgtype": "m.notice",
1762 - "format": "org.matrix.custom.html",
1763 - "formatted_body": "${emoji} ${host} ${status_message} - <b>${name//_/ }</b><br>${chart} (${family})<br><a href=\"${goto_url}\">${alarm}</a><br><i>${info}</i>",
1764 - "body": "${emoji} ${host} ${status_message} - ${name//_/ } ${chart} (${family}) ${goto_url} ${alarm} ${info}"
1765 - }
1790 + local homeserver="${1}" webhook accesstoken rooms="${2}" httpcode sent=0 payload
1791 +
1792 + [ "${SEND_MATRIX}" != "YES" ] && return 1
1793 + [ -z "${MATRIX_ACCESSTOKEN}" ] && return 1
1794 +
1795 + accesstoken="${MATRIX_ACCESSTOKEN}"
1796 +
1797 + case "${status}" in
1798 + WARNING) emoji="⚠️" ;;
1799 + CRITICAL) emoji="🔴" ;;
1800 + CLEAR) emoji="✅" ;;
1801 + *) emoji="⚪️" ;;
1802 + esac
1803 +
1804 + for room in ${rooms}; do
1805 + webhook="$homeserver/_matrix/client/r0/rooms/$(urlencode $room)/send/m.room.message?access_token=$accesstoken"
1806 + payload="$(
1807 + cat <<EOF
1808 + {
1809 + "msgtype": "m.notice",
1810 + "format": "org.matrix.custom.html",
1811 + "formatted_body": "${emoji} ${host} ${status_message} - <b>${name//_/ }</b><br>${chart} (${family})<br><a href=\"${goto_url}\">${alarm}</a><br><i>${info}</i>",
1812 + "body": "${emoji} ${host} ${status_message} - ${name//_/ } ${chart} (${family}) ${goto_url} ${alarm} ${info}"
1813 + }
1814 EOF
1767 - )"
1815 + )"
1816
1769 - httpcode=$(docurl -X POST --data "${payload}" "${webhook}")
1770 - if [ "${httpcode}" == "200" ]; then
1771 - info "sent Matrix notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
1772 - sent=$((sent + 1))
1773 - else
1774 - error "failed to send Matrix notification for: ${host} ${chart}.${name} is ${status} to '${room}', with HTTP response status code ${httpcode}."
1775 - fi
1776 - done
1817 + httpcode=$(docurl -X POST --data "${payload}" "${webhook}")
1818 + if [ "${httpcode}" == "200" ]; then
1819 + info "sent Matrix notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
1820 + sent=$((sent + 1))
1821 + else
1822 + error "failed to send Matrix notification for: ${host} ${chart}.${name} is ${status} to '${room}', with HTTP response status code ${httpcode}."
1823 + fi
1824 + done
1825
1778 - [ ${sent} -gt 0 ] && return 0
1826 + [ ${sent} -gt 0 ] && return 0
1827
1780 - return 1
1828 + return 1
1829 }
1830
1831 # -----------------------------------------------------------------------------
1832 # syslog sender
1833
1834 send_syslog() {
1787 - local facility=${SYSLOG_FACILITY:-"local6"} level='info' targets="${1}"
1788 - local priority='' message='' host='' port='' prefix=''
1789 - local temp1='' temp2=''
1790 -
1791 - [ "${SEND_SYSLOG}" = "YES" ] || return 1
1792 -
1793 - if [ "${status}" = "CRITICAL" ]; then
1794 - level='crit'
1795 - elif [ "${status}" = "WARNING" ]; then
1796 - level='warning'
1797 - fi
1798 -
1799 - for target in ${targets}; do
1800 - priority="${facility}.${level}"
1801 - message=''
1802 - host=''
1803 - port=''
1804 - prefix=''
1805 - temp1=''
1806 - temp2=''
1807 -
1808 - prefix=$(echo ${target} | cut -d '/' -f 2)
1809 - temp1=$(echo ${target} | cut -d '/' -f 1)
1810 -
1811 - if [ ${prefix} != ${temp1} ]; then
1812 - if (echo ${temp1} | grep -q '@'); then
1813 - temp2=$(echo ${temp1} | cut -d '@' -f 1)
1814 - host=$(echo ${temp1} | cut -d '@' -f 2)
1815 -
1816 - if [ ${temp2} != ${host} ]; then
1817 - priority=${temp2}
1818 - fi
1819 -
1820 - port=$(echo ${host} | rev | cut -d ':' -f 1 | rev)
1821 -
1822 - if (echo ${host} | grep -E -q '\[.*\]'); then
1823 - if (echo ${port} | grep -q ']'); then
1824 - port=''
1825 - else
1826 - host=$(echo ${host} | rev | cut -d ':' -f 2- | rev)
1827 - fi
1828 - else
1829 - if [ ${port} = ${host} ]; then
1830 - port=''
1831 - else
1832 - host=$(echo ${host} | cut -d ':' -f 1)
1833 - fi
1834 - fi
1835 - else
1836 - priority=${temp1}
1837 - fi
1838 - fi
1839 -
1840 - message="${prefix} ${status} on ${host} at ${date}: ${chart} ${value_string}"
1841 -
1842 - if [ ${host} ]; then
1843 - logger_options="${logger_options} -n ${host}"
1844 - if [ ${port} ]; then
1845 - logger_options="${logger_options} -P ${port}"
1846 - fi
1847 - fi
1848 -
1849 - ${logger} -p ${priority} ${logger_options} "${message}"
1850 - done
1851 -
1852 - return $?
1835 + local facility=${SYSLOG_FACILITY:-"local6"} level='info' targets="${1}"
1836 + local priority='' message='' host='' port='' prefix=''
1837 + local temp1='' temp2=''
1838 +
1839 + [ "${SEND_SYSLOG}" = "YES" ] || return 1
1840 +
1841 + if [ "${status}" = "CRITICAL" ]; then
1842 + level='crit'
1843 + elif [ "${status}" = "WARNING" ]; then
1844 + level='warning'
1845 + fi
1846 +
1847 + for target in ${targets}; do
1848 + priority="${facility}.${level}"
1849 + message=''
1850 + host=''
1851 + port=''
1852 + prefix=''
1853 + temp1=''
1854 + temp2=''
1855 +
1856 + prefix=$(echo ${target} | cut -d '/' -f 2)
1857 + temp1=$(echo ${target} | cut -d '/' -f 1)
1858 +
1859 + if [ ${prefix} != ${temp1} ]; then
1860 + if (echo ${temp1} | grep -q '@'); then
1861 + temp2=$(echo ${temp1} | cut -d '@' -f 1)
1862 + host=$(echo ${temp1} | cut -d '@' -f 2)
1863 +
1864 + if [ ${temp2} != ${host} ]; then
1865 + priority=${temp2}
1866 + fi
1867 +
1868 + port=$(echo ${host} | rev | cut -d ':' -f 1 | rev)
1869 +
1870 + if (echo ${host} | grep -E -q '\[.*\]'); then
1871 + if (echo ${port} | grep -q ']'); then
1872 + port=''
1873 + else
1874 + host=$(echo ${host} | rev | cut -d ':' -f 2- | rev)
1875 + fi
1876 + else
1877 + if [ ${port} = ${host} ]; then
1878 + port=''
1879 + else
1880 + host=$(echo ${host} | cut -d ':' -f 1)
1881 + fi
1882 + fi
1883 + else
1884 + priority=${temp1}
1885 + fi
1886 + fi
1887 +
1888 + message="${prefix} ${status} on ${host} at ${date}: ${chart} ${value_string}"
1889 +
1890 + if [ ${host} ]; then
1891 + logger_options="${logger_options} -n ${host}"
1892 + if [ ${port} ]; then
1893 + logger_options="${logger_options} -P ${port}"
1894 + fi
1895 + fi
1896 +
1897 + ${logger} -p ${priority} ${logger_options} "${message}"
1898 + done
1899 +
1900 + return $?
1901 }
1902
1903 # -----------------------------------------------------------------------------
1904 # SMS sender
1905
1906 send_sms() {
1859 - local recipients="${1}" errcode errmessage sent=0
1907 + local recipients="${1}" errcode errmessage sent=0
1908
1909 # Human readable SMS
1910 local msg="${host} ${status_message}: ${chart} (${family}), ${alarm}"
@@ -1864,135 +1912,135 @@ send_sms() {
1912 # limit it to 160 characters
1913 msg="${msg:0:160}"
1914
1867 - if [ "${SEND_SMS}" = "YES" ] && [ -n "${sendsms}" ] && [ -n "${recipients}" ] && [ -n "${msg}" ]; then
1868 - # http://api.kavenegar.com/v1/{API-KEY}/sms/send.json
1869 - for phone in ${recipients}; do
1870 - errmessage=$($sendsms $phone "$msg" 2>&1)
1871 - errcode=$?
1872 - if [ ${errcode} -eq 0 ]; then
1873 - info "sent smstools3 SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1874 - sent=$((sent + 1))
1875 - else
1876 - error "failed to send smstools3 SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with error code ${errcode}: ${errmessage}."
1877 - fi
1878 - done
1879 -
1880 - [ ${sent} -gt 0 ] && return 0
1881 - fi
1882 -
1883 - return 1
1915 + if [ "${SEND_SMS}" = "YES" ] && [ -n "${sendsms}" ] && [ -n "${recipients}" ] && [ -n "${msg}" ]; then
1916 + # http://api.kavenegar.com/v1/{API-KEY}/sms/send.json
1917 + for phone in ${recipients}; do
1918 + errmessage=$($sendsms $phone "$msg" 2>&1)
1919 + errcode=$?
1920 + if [ ${errcode} -eq 0 ]; then
1921 + info "sent smstools3 SMS for: ${host} ${chart}.${name} is ${status} to '${user}'"
1922 + sent=$((sent + 1))
1923 + else
1924 + error "failed to send smstools3 SMS for: ${host} ${chart}.${name} is ${status} to '${user}' with error code ${errcode}: ${errmessage}."
1925 + fi
1926 + done
1927 +
1928 + [ ${sent} -gt 0 ] && return 0
1929 + fi
1930 +
1931 + return 1
1932 }
1933
1934 # -----------------------------------------------------------------------------
1935 # hangouts sender
1936
1937 send_hangouts() {
1890 - local rooms="${1}" httpcode sent=0 room color payload webhook thread
1891 -
1892 - [ "${SEND_HANGOUTS}" != "YES" ] && return 1
1893 -
1894 - case "${status}" in
1895 - WARNING) color="#ffa700" ;;
1896 - CRITICAL) color="#d62d20" ;;
1897 - CLEAR) color="#008744" ;;
1898 - *) color="#777777" ;;
1899 - esac
1900 -
1901 - for room in ${rooms}; do
1902 - if [ -z "${HANGOUTS_WEBHOOK_URI[$room]}" ] ; then
1903 - info "Can't send Hangouts notification for: ${host} ${chart}.${name} to room ${room}. HANGOUTS_WEBHOOK_URI[$room] not defined"
1904 - else
1905 - if [ -n "${HANGOUTS_WEBHOOK_THREAD[$room]}" ]; then
1906 - thread="\"name\" : \"${HANGOUTS_WEBHOOK_THREAD[$room]}\""
1907 - fi
1908 - webhook="${HANGOUTS_WEBHOOK_URI[$room]}"
1909 - payload="$(
1910 - cat <<EOF
1911 - {
1912 - "cards": [
1913 - {
1914 - "header": {
1915 - "title": "Netdata on ${host}",
1916 - "imageUrl": "${images_base_url}/images/banner-icon-144x144.png",
1917 - "imageStyle": "IMAGE"
1918 - },
1919 - "sections": [
1920 - {
1921 - "header": "<b>${host}</b>",
1922 - "widgets": [
1923 - {
1924 - "keyValue": {
1925 - "topLabel": "Status Message",
1926 - "content": "<b>${status_message}</b>",
1927 - "contentMultiline": "true",
1928 - "iconUrl": "${image}",
1929 - "onClick": {
1930 - "openLink": {
1931 - "url": "${goto_url}"
1932 - }
1933 - }
1934 - }
1935 - },
1936 - {
1937 - "keyValue": {
1938 - "topLabel": "${chart} | ${family}",
1939 - "content": "<font color=${color}>${alarm}</font>",
1940 - "contentMultiline": "true"
1941 - }
1942 - }
1943 - ]
1944 - },
1945 - {
1946 - "widgets": [
1947 - {
1948 - "textParagraph": {
1949 - "text": "<font color=\"#0057e7\">@ ${date}\n<b>${info}</b></font>"
1950 - }
1951 - }
1952 - ]
1953 - },
1954 - {
1955 - "widgets": [
1956 - {
1957 - "buttons": [
1958 - {
1959 - "textButton": {
1960 - "text": "Go to ${host}",
1961 - "onClick": {
1962 - "openLink": {
1963 - "url": "${goto_url}"
1964 - }
1965 - }
1966 - }
1967 - }
1968 - ]
1969 - }
1970 - ]
1971 - }
1972 - ]
1973 - }
1974 - ],
1975 - "thread": {
1976 - $thread
1977 - }
1978 - }
1938 + local rooms="${1}" httpcode sent=0 room color payload webhook thread
1939 +
1940 + [ "${SEND_HANGOUTS}" != "YES" ] && return 1
1941 +
1942 + case "${status}" in
1943 + WARNING) color="#ffa700" ;;
1944 + CRITICAL) color="#d62d20" ;;
1945 + CLEAR) color="#008744" ;;
1946 + *) color="#777777" ;;
1947 + esac
1948 +
1949 + for room in ${rooms}; do
1950 + if [ -z "${HANGOUTS_WEBHOOK_URI[$room]}" ] ; then
1951 + info "Can't send Hangouts notification for: ${host} ${chart}.${name} to room ${room}. HANGOUTS_WEBHOOK_URI[$room] not defined"
1952 + else
1953 + if [ -n "${HANGOUTS_WEBHOOK_THREAD[$room]}" ]; then
1954 + thread="\"name\" : \"${HANGOUTS_WEBHOOK_THREAD[$room]}\""
1955 + fi
1956 + webhook="${HANGOUTS_WEBHOOK_URI[$room]}"
1957 + payload="$(
1958 + cat <<EOF
1959 + {
1960 + "cards": [
1961 + {
1962 + "header": {
1963 + "title": "Netdata on ${host}",
1964 + "imageUrl": "${images_base_url}/images/banner-icon-144x144.png",
1965 + "imageStyle": "IMAGE"
1966 + },
1967 + "sections": [
1968 + {
1969 + "header": "<b>${host}</b>",
1970 + "widgets": [
1971 + {
1972 + "keyValue": {
1973 + "topLabel": "Status Message",
1974 + "content": "<b>${status_message}</b>",
1975 + "contentMultiline": "true",
1976 + "iconUrl": "${image}",
1977 + "onClick": {
1978 + "openLink": {
1979 + "url": "${goto_url}"
1980 + }
1981 + }
1982 + }
1983 + },
1984 + {
1985 + "keyValue": {
1986 + "topLabel": "${chart} | ${family}",
1987 + "content": "<font color=${color}>${alarm}</font>",
1988 + "contentMultiline": "true"
1989 + }
1990 + }
1991 + ]
1992 + },
1993 + {
1994 + "widgets": [
1995 + {
1996 + "textParagraph": {
1997 + "text": "<font color=\"#0057e7\">@ ${date}\n<b>${info}</b></font>"
1998 + }
1999 + }
2000 + ]
2001 + },
2002 + {
2003 + "widgets": [
2004 + {
2005 + "buttons": [
2006 + {
2007 + "textButton": {
2008 + "text": "Go to ${host}",
2009 + "onClick": {
2010 + "openLink": {
2011 + "url": "${goto_url}"
2012 + }
2013 + }
2014 + }
2015 + }
2016 + ]
2017 + }
2018 + ]
2019 + }
2020 + ]
2021 + }
2022 + ],
2023 + "thread": {
2024 + $thread
2025 + }
2026 + }
2027 EOF
1980 - )"
2028 + )"
2029
1982 - httpcode=$(docurl -H "Content-Type: application/json" -X POST -d "${payload}" "${webhook}")
2030 + httpcode=$(docurl -H "Content-Type: application/json" -X POST -d "${payload}" "${webhook}")
2031
1984 - if [ "${httpcode}" = "200" ]; then
1985 - info "sent hangouts notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
1986 - sent=$((sent + 1))
1987 - else
1988 - error "failed to send hangouts notification for: ${host} ${chart}.${name} is ${status} to '${room}', with HTTP response status code ${httpcode}."
1989 - fi
1990 - fi
1991 - done
2032 + if [ "${httpcode}" = "200" ]; then
2033 + info "sent hangouts notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
2034 + sent=$((sent + 1))
2035 + else
2036 + error "failed to send hangouts notification for: ${host} ${chart}.${name} is ${status} to '${room}', with HTTP response status code ${httpcode}."
2037 + fi
2038 + fi
2039 + done
2040
1993 - [ ${sent} -gt 0 ] && return 0
2041 + [ ${sent} -gt 0 ] && return 0
2042
1995 - return 1
2043 + return 1
2044 }
2045
2046 # -----------------------------------------------------------------------------
@@ -2160,22 +2208,22 @@ redirect_params="host=${url_host}&chart=${url_chart}&family=${url_family}&alarm=
2208 GOTOCLOUD=0
2209
2210 if [ "${NETDATA_REGISTRY_URL}" == "https://registry.my-netdata.io" ]; then
2163 - if [ -z "${NETDATA_REGISTRY_UNIQUE_ID}" ]; then
2164 - if [ -f "@registrydir_POST@/netdata.public.unique.id" ]; then
2165 - NETDATA_REGISTRY_UNIQUE_ID="$(cat "@registrydir_POST@/netdata.public.unique.id")"
2166 - fi
2167 - fi
2168 - if [ -n "${NETDATA_REGISTRY_UNIQUE_ID}" ]; then
2169 - GOTOCLOUD=1
2170 - fi
2211 + if [ -z "${NETDATA_REGISTRY_UNIQUE_ID}" ]; then
2212 + if [ -f "@registrydir_POST@/netdata.public.unique.id" ]; then
2213 + NETDATA_REGISTRY_UNIQUE_ID="$(cat "@registrydir_POST@/netdata.public.unique.id")"
2214 + fi
2215 + fi
2216 + if [ -n "${NETDATA_REGISTRY_UNIQUE_ID}" ]; then
2217 + GOTOCLOUD=1
2218 + fi
2219 fi
2220
2221 if [ ${GOTOCLOUD} -eq 0 ]; then
2174 - goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?${redirect_params}"
2222 + goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?${redirect_params}"
2223 else
2176 - # Temporarily disable alarm redirection, as the cloud endpoint no longer exists. This functionality will be restored after discussion on #9487. For now, just lead to netdata.cloud
2177 - #goto_url="${NETDATA_REGISTRY_CLOUD_BASE_URL}/alarms/redirect?agentID=${NETDATA_REGISTRY_UNIQUE_ID}&${redirect_params}"
2178 - goto_url="${NETDATA_REGISTRY_CLOUD_BASE_URL}"
2224 + # Temporarily disable alarm redirection, as the cloud endpoint no longer exists. This functionality will be restored after discussion on #9487. For now, just lead to netdata.cloud
2225 + #goto_url="${NETDATA_REGISTRY_CLOUD_BASE_URL}/alarms/redirect?agentID=${NETDATA_REGISTRY_UNIQUE_ID}&${redirect_params}"
2226 + goto_url="${NETDATA_REGISTRY_CLOUD_BASE_URL}"
2227 fi
2228
2229 # the severity of the alarm
@@ -2203,48 +2251,48 @@ image="${images_base_url}/images/banner-icon-144x144.png"
2251 # prepare the title based on status
2252 case "${status}" in
2253 CRITICAL)
2206 - image="${images_base_url}/images/alert-128-red.png"
2207 - status_message="is critical"
2208 - color="#ca414b"
2209 - ;;
2254 + image="${images_base_url}/images/alert-128-red.png"
2255 + status_message="is critical"
2256 + color="#ca414b"
2257 + ;;
2258
2259 WARNING)
2212 - image="${images_base_url}/images/alert-128-orange.png"
2213 - status_message="needs attention"
2214 - color="#ffc107"
2215 - ;;
2260 + image="${images_base_url}/images/alert-128-orange.png"
2261 + status_message="needs attention"
2262 + color="#ffc107"
2263 + ;;
2264
2265 CLEAR)
2218 - image="${images_base_url}/images/check-mark-2-128-green.png"
2219 - status_message="recovered"
2220 - color="#77ca6d"
2221 - ;;
2266 + image="${images_base_url}/images/check-mark-2-128-green.png"
2267 + status_message="recovered"
2268 + color="#77ca6d"
2269 + ;;
2270 esac
2271
2272 if [ "${status}" = "CLEAR" ]; then
2225 - severity="Recovered from ${old_status}"
2226 - if [ ${non_clear_duration} -gt ${duration} ]; then
2227 - raised_for="(alarm was raised for ${non_clear_duration_txt})"
2228 - fi
2273 + severity="Recovered from ${old_status}"
2274 + if [ ${non_clear_duration} -gt ${duration} ]; then
2275 + raised_for="(alarm was raised for ${non_clear_duration_txt})"
2276 + fi
2277
2230 - # don't show the value when the status is CLEAR
2231 - # for certain alarms, this value might not have any meaning
2232 - alarm="${name//_/ } ${raised_for}"
2278 + # don't show the value when the status is CLEAR
2279 + # for certain alarms, this value might not have any meaning
2280 + alarm="${name//_/ } ${raised_for}"
2281
2282 elif { [ "${old_status}" = "WARNING" ] && [ "${status}" = "CRITICAL" ]; }; then
2235 - severity="Escalated to ${status}"
2236 - if [ ${non_clear_duration} -gt ${duration} ]; then
2237 - raised_for="(alarm is raised for ${non_clear_duration_txt})"
2238 - fi
2283 + severity="Escalated to ${status}"
2284 + if [ ${non_clear_duration} -gt ${duration} ]; then
2285 + raised_for="(alarm is raised for ${non_clear_duration_txt})"
2286 + fi
2287
2288 elif { [ "${old_status}" = "CRITICAL" ] && [ "${status}" = "WARNING" ]; }; then
2241 - severity="Demoted to ${status}"
2242 - if [ ${non_clear_duration} -gt ${duration} ]; then
2243 - raised_for="(alarm is raised for ${non_clear_duration_txt})"
2244 - fi
2289 + severity="Demoted to ${status}"
2290 + if [ ${non_clear_duration} -gt ${duration} ]; then
2291 + raised_for="(alarm is raised for ${non_clear_duration_txt})"
2292 + fi
2293
2294 else
2247 - raised_for=
2295 + raised_for=
2296 fi
2297
2298 # prepare HTML versions of elements
@@ -2434,14 +2482,14 @@ SENT_SMS=$?
2482 # send the custom message
2483
2484 send_custom() {
2437 - # is it enabled?
2438 - [ "${SEND_CUSTOM}" != "YES" ] && return 1
2485 + # is it enabled?
2486 + [ "${SEND_CUSTOM}" != "YES" ] && return 1
2487
2440 - # do we have any sender?
2441 - [ -z "${1}" ] && return 1
2488 + # do we have any sender?
2489 + [ -z "${1}" ] && return 1
2490
2443 - # call the custom_sender function
2444 - custom_sender "${@}"
2491 + # call the custom_sender function
2492 + custom_sender "${@}"
2493 }
2494
2495 send_custom "${to_custom}"
@@ -2673,37 +2721,37 @@ SENT_OPSGENIE=$?
2721 # -----------------------------------------------------------------------------
2722 # let netdata know
2723 for state in "${SENT_EMAIL}" \
2676 - "${SENT_PUSHOVER}" \
2677 - "${SENT_TELEGRAM}" \
2678 - "${SENT_SLACK}" \
2679 - "${SENT_HANGOUTS}" \
2680 - "${SENT_ROCKETCHAT}" \
2681 - "${SENT_ALERTA}" \
2682 - "${SENT_FLOCK}" \
2683 - "${SENT_DISCORD}" \
2684 - "${SENT_TWILIO}" \
2685 - "${SENT_HIPCHAT}" \
2686 - "${SENT_MESSAGEBIRD}" \
2687 - "${SENT_KAVENEGAR}" \
2688 - "${SENT_PUSHBULLET}" \
2689 - "${SENT_KAFKA}" \
2690 - "${SENT_PD}" \
2691 - "${SENT_FLEEP}" \
2692 - "${SENT_PROWL}" \
2693 - "${SENT_CUSTOM}" \
2694 - "${SENT_IRC}" \
2695 - "${SENT_AWSSNS}" \
2696 - "${SENT_MATRIX}" \
2697 - "${SENT_SYSLOG}" \
2698 - "${SENT_SMS}" \
2699 - "${SENT_MSTEAM}" \
2700 - "${SENT_DYNATRACE}" \
2701 - "${SENT_STACKPULSE}" \
2724 + "${SENT_PUSHOVER}" \
2725 + "${SENT_TELEGRAM}" \
2726 + "${SENT_SLACK}" \
2727 + "${SENT_HANGOUTS}" \
2728 + "${SENT_ROCKETCHAT}" \
2729 + "${SENT_ALERTA}" \
2730 + "${SENT_FLOCK}" \
2731 + "${SENT_DISCORD}" \
2732 + "${SENT_TWILIO}" \
2733 + "${SENT_HIPCHAT}" \
2734 + "${SENT_MESSAGEBIRD}" \
2735 + "${SENT_KAVENEGAR}" \
2736 + "${SENT_PUSHBULLET}" \
2737 + "${SENT_KAFKA}" \
2738 + "${SENT_PD}" \
2739 + "${SENT_FLEEP}" \
2740 + "${SENT_PROWL}" \
2741 + "${SENT_CUSTOM}" \
2742 + "${SENT_IRC}" \
2743 + "${SENT_AWSSNS}" \
2744 + "${SENT_MATRIX}" \
2745 + "${SENT_SYSLOG}" \
2746 + "${SENT_SMS}" \
2747 + "${SENT_MSTEAM}" \
2748 + "${SENT_DYNATRACE}" \
2749 + "${SENT_STACKPULSE}" \
2750 "${SENT_OPSGENIE}"; do
2703 - if [ "${state}" -eq 0 ]; then
2704 - # we sent something
2705 - exit 0
2706 - fi
2751 + if [ "${state}" -eq 0 ]; then
2752 + # we sent something
2753 + exit 0
2754 + fi
2755 done
2756 # we did not send anything
2757 exit 1
health/notifications/health_alarm_notify.conf
+3
@@ -630,6 +630,9 @@ SEND_PD="YES"
630 # (empty = do not send a notification for unconfigured roles):
631 DEFAULT_RECIPIENT_PD=""
632
633 +# Which PD API are we going to use? For version 2 or newer, it is necessary to do a request for Pagerduty
634 +# before to set the version(https://developer.pagerduty.com/docs/events-api-v2/overview/).
635 +USE_PD_VERSION="1"
636
637 #------------------------------------------------------------------------------
638 # fleep notification options
health/notifications/pagerduty/README.md
+4
@@ -39,6 +39,10 @@ SEND_PD="YES"
39 # the "General API" pagerduty.com service that uses this service key.
40 # (empty = do not send a notification for unconfigured roles):
41 DEFAULT_RECIPIENT_PD="<service key>"
42 +
43 +# Which PD API are we going to use? For version 2 or newer, it is necessary to do a request for Pagerduty
44 +# before to set the version(https://developer.pagerduty.com/docs/events-api-v2/overview/).
45 +USE_PD_VERSION="1"
46 ```
47
48 [![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fhealth%2Fnotifications%2Fpagerduty%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>)