From 7c1af9474008209239f251b932f2cf33670fe23b Mon Sep 17 00:00:00 2001 From: Jan Arnold Date: Thu, 8 Sep 2016 14:44:26 +0200 Subject: [PATCH] added push alarm notification via Pushover --- conf.d/health_pushover_tokens.conf | 16 ++ plugins.d/alarm-pushover.sh | 230 +++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 conf.d/health_pushover_tokens.conf create mode 100644 plugins.d/alarm-pushover.sh diff --git a/conf.d/health_pushover_tokens.conf b/conf.d/health_pushover_tokens.conf new file mode 100644 index 00000000..4ba7d93e --- /dev/null +++ b/conf.d/health_pushover_tokens.conf @@ -0,0 +1,16 @@ +# Configuration for pushover alarms +# by Jan Arnold +# v0.1 +# 2016-09-12 +# +# This is the configuration file for alarm-pushover.sh, a shell script for using the Pushover (https://pushover.net) +# push service with netdata. Please copy this to the netdata config directory, which by default is "/etc/netdata/". +# Once Pushover is installed on your phone or computer, you need to create an account to receive a user token. +# This is needed so the push reaches your device. +# +# Further help for pushover: https://pushover.net/faq +# +# Generate an apptoken and a usertoken at https://pushover.net and insert them here + +APPTOKEN="" +USERTOKEN="" diff --git a/plugins.d/alarm-pushover.sh b/plugins.d/alarm-pushover.sh new file mode 100644 index 00000000..1d1e20ae --- /dev/null +++ b/plugins.d/alarm-pushover.sh @@ -0,0 +1,230 @@ +#!/usr/bin/env bash +# based on alarm-email.sh by netdata +# by Jan Arnold +# v0.1 +# 2016-09-12 +# +# This is a shell script for using the Pushover (https://pushover.net) push service. +# Copy this script to the netdata plugin folder which by default is "/usr/libexec/netdata/plugins.d/". +# In the config file for the alarm you want to use it for add: +# "exec: /usr/libexec/netdata/plugins.d/alarm-pushover.sh" +# Once Pushover client is installed on your phone or computer, you need to create an account to receive a +# user token. This is needed so the push reaches your device. +# +# Generate an apptoken at https://pushover.net and insert that and the usertoken into the +# "healt_pushover_tokens.conf" file which has to reside in the netdata config dir which by +# default is "/etc/netdata/". +# +# Further help for pushover: https://pushover.net/faq + +me="${0}" + +curl="$(which curl 2>/dev/null || command -v curl 2>/dev/null)" +if [ -z "${curl}" ] +then + echo >&2 "I cannot send push notifications - there is no curl command available." + exit 1 +fi + +if [ -f "${NETDATA_CONFIG_DIR}/health_pushover_tokens.conf" ] + then + source "${NETDATA_CONFIG_DIR}/health_pushover_tokens.conf" +else + echo >&2 "${me}: FAILED to source ${NETDATA_CONFIG_DIR}/health_pushover_tokens.conf for push token" + exit 1 +fi + +if ! [ "$APPTOKEN" ] + then + echo >&2 "${me}: FAILED - Please set pushover APPTOKEN in ${NETDATA_CONFIG_DIR}/health_pushover_tokens.conf" + exit 1 +fi + +if ! [ "$USERTOKEN" ] + then + echo >&2 "${me}: FAILED - Please set pushover USERTOKEN in ${NETDATA_CONFIG_DIR}/health_pushover_tokens.conf" + exit 1 +fi + +curl_pushover() { + httpcode=$(curl --write-out %{http_code} --silent --output /dev/null \ + --form-string "token=$APPTOKEN" \ + --form-string "user=$USERTOKEN" \ + --form-string "html=1" \ + --form-string "title=$TITLE" \ + --form-string "message=$MESSAGE" \ + https://api.pushover.net/1/messages.json) + + if [ "$httpcode" == "200" ] + then + echo >&2 "${me}: Sent notification push for ${status} on '${chart}.${name}'" + return 0 + else + echo >&2 "${me}: FAILED to send notification push for ${status} on '${chart}.${name}'" + return 1 + fi +} + +recipient="${1}" # the recepient of the push +hostname="${2}" # the hostname this event refers to +unique_id="${3}" # the unique id of this event +alarm_id="${4}" # the unique id of the alarm that generated this event +event_id="${5}" # the incremental id of the event, for this alarm +when="${6}" # the timestamp this event occured +name="${7}" # the name of the alarm, as given in netdata health.d entries +chart="${8}" # the name of the chart (type.id) +family="${9}" # the family of the chart +status="${10}" # the current status : UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL +old_status="${11}" # the previous status: UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL +value="${12}" # the current value +old_value="${13}" # the previous value +src="${14}" # the line number and file the alarm has been configured +duration="${15}" # the duration in seconds the previous state took +non_clear_duration="${16}" # the total duration in seconds this is non-clear +units="${17}" # the units of the value +info="${18}" # a short description of the alarm + +[ ! -z "${info}" ] && info="
${info}
" + +# get the system hostname +[ -z "${hostname}" ] && hostname="${NETDATA_HOSTNAME}" +[ -z "${hostname}" ] && hostname="${NETDATA_REGISTRY_HOSTNAME}" +[ -z "${hostname}" ] && hostname="$(hostname 2>/dev/null)" + +goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?machine_guid=${NETDATA_REGISTRY_UNIQUE_ID}&chart=${chart}&family=${family}" + +date="$(date --date=@${when} 2>/dev/null)" +[ -z "${date}" ] && date="$(date 2>/dev/null)" + +# convert a duration in seconds, to a human readable duration +# using DAYS, MINUTES, SECONDS +duration4human() { + local s="${1}" d=0 h=0 m=0 ds="day" hs="hour" ms="minute" ss="second" + d=$(( s / 86400 )) + s=$(( s - (d * 86400) )) + h=$(( s / 3600 )) + s=$(( s - (h * 3600) )) + m=$(( s / 60 )) + s=$(( s - (m * 60) )) + + if [ ${d} -gt 0 ] + then + [ ${m} -ge 30 ] && h=$(( h + 1 )) + [ ${d} -gt 1 ] && ds="days" + [ ${h} -gt 1 ] && hs="hours" + if [ ${h} -gt 0 ] + then + echo "${d} ${ds} and ${h} ${hs}" + else + echo "${d} ${ds}" + fi + elif [ ${h} -gt 0 ] + then + [ ${s} -ge 30 ] && m=$(( m + 1 )) + [ ${h} -gt 1 ] && hs="hours" + [ ${m} -gt 1 ] && ms="minutes" + if [ ${m} -gt 0 ] + then + echo "${h} ${hs} and ${m} ${ms}" + else + echo "${h} ${hs}" + fi + elif [ ${m} -gt 0 ] + then + [ ${m} -gt 1 ] && ms="minutes" + [ ${s} -gt 1 ] && ss="seconds" + if [ ${s} -gt 0 ] + then + echo "${m} ${ms} and ${s} ${ss}" + else + echo "${m} ${ms}" + fi + else + [ ${s} -gt 1 ] && ss="seconds" + echo "${s} ${ss}" + fi +} + +severity="${status}" +raised_for="
(was ${old_status,,} for $(duration4human ${duration}))" +status_message="status unknown" +color="grey" +alarm="${name} = ${value} ${units}" + +# prepare the title based on status +case "${status}" in + CRITICAL) + status_message="is critical" + color="#ca414b" + ;; + + WARNING) + status_message="needs attention" + color="#caca4b" + ;; + + CLEAR) + status_message="recovered" + color="#77ca6d" + + # don't show the value when the status is CLEAR + # for certain alarms, this value might not have any meaning + alarm="${name}" + ;; +esac + +if [ "${status}" != "WARNING" -a "${status}" != "CRITICAL" -a "${status}" != "CLEAR" ] +then + # don't do anything if this is not WARNING, CRITICAL or CLEAR + echo >&2 "${me}: not sending notification push for ${status} on '${chart}.${name}'" + exit 0 +elif [ "${old_status}" != "WARNING" -a "${old_status}" != "CRITICAL" -a "${status}" = "CLEAR" ] +then + # don't do anything if this is CLEAR, but it was not WARNING or CRITICAL + echo >&2 "${me}: not sending notification push for ${status} on '${chart}.${name}' (last status was ${old_status})" + exit 0 +elif [ "${status}" = "CLEAR" ] +then + severity="Recovered from ${old_status}" + if [ $non_clear_duration -gt $duration ] + then + raised_for="
(had issues for $(duration4human ${non_clear_duration}))" + fi + +elif [ "${old_status}" = "WARNING" -a "${status}" = "CRITICAL" ] +then + severity="Escalated to ${status}" + if [ $non_clear_duration -gt $duration ] + then + raised_for="
(has issues for $(duration4human ${non_clear_duration}))" + fi + +elif [ "${old_status}" = "CRITICAL" -a "${status}" = "WARNING" ] +then + severity="Demoted to ${status}" + if [ $non_clear_duration -gt $duration ] + then + raised_for="
(has issues for $(duration4human ${non_clear_duration}))" + fi + +else + raised_for= +fi + +# generate push message +TITLE="${hostname} ${status_message} - ${chart}.${name}" +MESSAGE="${hostname} ${status_message} + +${alarm}${info} + +Chart: ${chart} +Family: ${family} +Severity: ${severity} +Time: ${date} +${raised_for} +View Netdata + +The source of this alarm is line ${src}" + +# send the push +curl_pushover -- 2.39.2