diff options
Diffstat (limited to 'plugins.d')
-rw-r--r-- | plugins.d/Makefile.in | 117 | ||||
-rwxr-xr-x | plugins.d/alarm-notify.sh | 147 | ||||
-rwxr-xr-x | plugins.d/alarm-test.sh | 2 | ||||
-rwxr-xr-x | plugins.d/cgroup-name.sh | 48 | ||||
-rwxr-xr-x | plugins.d/charts.d.plugin | 9 | ||||
-rwxr-xr-x | plugins.d/fping.plugin | 26 | ||||
-rwxr-xr-x | plugins.d/node.d.plugin | 6 | ||||
-rwxr-xr-x | plugins.d/python.d.plugin | 19 | ||||
-rwxr-xr-x | plugins.d/tc-qos-helper.sh | 9 |
9 files changed, 275 insertions, 108 deletions
diff --git a/plugins.d/Makefile.in b/plugins.d/Makefile.in index 2a8806cb1..256605f5d 100644 --- a/plugins.d/Makefile.in +++ b/plugins.d/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -17,6 +16,51 @@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -36,8 +80,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = plugins.d -DIST_COMMON = $(dist_plugins_DATA) $(dist_plugins_SCRIPTS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(dist_plugins_SCRIPTS) $(dist_plugins_DATA) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___atomic.m4 \ $(top_srcdir)/m4/ax_c__generic.m4 $(top_srcdir)/m4/ax_c_lto.m4 \ @@ -82,12 +126,31 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(pluginsdir)" "$(DESTDIR)$(pluginsdir)" SCRIPTS = $(dist_plugins_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DATA = $(dist_plugins_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -287,8 +350,11 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-dist_pluginsSCRIPTS: $(dist_plugins_SCRIPTS) @$(NORMAL_INSTALL) - test -z "$(pluginsdir)" || $(MKDIR_P) "$(DESTDIR)$(pluginsdir)" @list='$(dist_plugins_SCRIPTS)'; test -n "$(pluginsdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pluginsdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pluginsdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ @@ -319,8 +385,11 @@ uninstall-dist_pluginsSCRIPTS: dir='$(DESTDIR)$(pluginsdir)'; $(am__uninstall_files_from_dir) install-dist_pluginsDATA: $(dist_plugins_DATA) @$(NORMAL_INSTALL) - test -z "$(pluginsdir)" || $(MKDIR_P) "$(DESTDIR)$(pluginsdir)" @list='$(dist_plugins_DATA)'; test -n "$(pluginsdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pluginsdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pluginsdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -335,11 +404,11 @@ uninstall-dist_pluginsDATA: @list='$(dist_plugins_DATA)'; test -n "$(pluginsdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pluginsdir)'; $(am__uninstall_files_from_dir) -tags: TAGS -TAGS: +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -478,18 +547,18 @@ uninstall-am: uninstall-dist_pluginsDATA uninstall-dist_pluginsSCRIPTS .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_pluginsDATA install-dist_pluginsSCRIPTS \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ - uninstall-am uninstall-dist_pluginsDATA \ - uninstall-dist_pluginsSCRIPTS +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dist_pluginsDATA \ + install-dist_pluginsSCRIPTS install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-dist_pluginsDATA uninstall-dist_pluginsSCRIPTS # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/plugins.d/alarm-notify.sh b/plugins.d/alarm-notify.sh index d0188fe3b..4f619091f 100755 --- a/plugins.d/alarm-notify.sh +++ b/plugins.d/alarm-notify.sh @@ -2,7 +2,7 @@ # netdata # real-time performance and health monitoring, done right! -# (C) 2016 Costa Tsaousis <costa@tsaousis.gr> +# (C) 2017 Costa Tsaousis <costa@tsaousis.gr> # GPL v3+ # # Script to send alarm notifications for netdata @@ -18,13 +18,14 @@ # - slack.com notifications by @ktsaou # - discordapp.com notifications by @lowfive # - pushover.net notifications by @ktsaou -# - pushbullet.com push notifications by Tiago Peralta @tperalta82 PR #1070 -# - telegram.org notifications by @hashworks PR #1002 -# - twilio.com notifications by Levi Blaney @shadycuz PR #1211 +# - pushbullet.com push notifications by Tiago Peralta @tperalta82 #1070 +# - telegram.org notifications by @hashworks #1002 +# - twilio.com notifications by Levi Blaney @shadycuz #1211 # - kafka notifications by @ktsaou #1342 -# - pagerduty.com notifications by Jim Cooley @jimcooley PR #1373 +# - pagerduty.com notifications by Jim Cooley @jimcooley #1373 # - messagebird.com notifications by @tech_no_logical #1453 # - hipchat notifications by @ktsaou #1561 +# - custom notifications by @ktsaou # ----------------------------------------------------------------------------- # testing notifications @@ -103,6 +104,15 @@ debug() { [ ${debug} -eq 1 ] && log DEBUG "${@}" } + +# ----------------------------------------------------------------------------- +# this is to be overwritten by the config file + +custom_sender() { + info "not sending custom notification for ${status} of '${host}.${chart}.${name}'" +} + + # ----------------------------------------------------------------------------- # check for BASH v4+ (required for associative arrays) @@ -112,11 +122,9 @@ debug() { # ----------------------------------------------------------------------------- # defaults to allow running this script by hand -NETDATA_CONFIG_DIR="${NETDATA_CONFIG_DIR-/etc/netdata}" -NETDATA_CACHE_DIR="${NETDATA_CACHE_DIR-/var/cache/netdata}" +[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata" +[ -z "${NETDATA_CACHE_DIR}" ] && NETDATA_CACHE_DIR="$(dirname "${0}")/../../../../var/cache/netdata" [ -z "${NETDATA_REGISTRY_URL}" ] && NETDATA_REGISTRY_URL="https://registry.my-netdata.io" -[ -z "${NETDATA_HOSTNAME}" ] && NETDATA_HOSTNAME="$(hostname)" -[ -z "${NETDATA_REGISTRY_HOSTNAME}" ] && NETDATA_REGISTRY_HOSTNAME="${NETDATA_HOSTNAME}" # ----------------------------------------------------------------------------- # parse command line parameters @@ -130,8 +138,8 @@ when="${6}" # the timestamp this event occurred 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 : REMOVED, UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL -old_status="${11}" # the previous status: REMOVED, UNITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL +status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL +old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL value="${12}" # the current value of the alarm old_value="${13}" # the previous value of the alarm src="${14}" # the line number and file the alarm has been configured @@ -145,9 +153,8 @@ old_value_string="${20}" # friendly old value (with units) # ----------------------------------------------------------------------------- # find a suitable hostname to use, if netdata did not supply a hostname -[ -z "${host}" ] && host="${NETDATA_HOSTNAME}" -[ -z "${host}" ] && host="${NETDATA_REGISTRY_HOSTNAME}" -[ -z "${host}" ] && host="$(hostname 2>/dev/null)" +this_host=$(hostname -s 2>/dev/null) +[ -z "${host}" ] && host="${this_host}" # ----------------------------------------------------------------------------- # screen statuses we don't need to send a notification @@ -192,6 +199,7 @@ SEND_EMAIL="YES" SEND_PUSHBULLET="YES" SEND_KAFKA="YES" SEND_PD="YES" +SEND_CUSTOM="YES" # slack configs SLACK_WEBHOOK_URL= @@ -245,6 +253,10 @@ KAFKA_SENDER_IP= PD_SERVICE_KEY= declare -A role_recipients_pd=() +# custom configs +DEFAULT_RECIPIENT_CUSTOM= +declare -A role_recipients_custom=() + # email configs DEFAULT_RECIPIENT_EMAIL="root" declare -A role_recipients_email=() @@ -308,6 +320,7 @@ declare -A arr_hipchat=() declare -A arr_telegram=() declare -A arr_pd=() declare -A arr_email=() +declare -A arr_custom=() # netdata may call us with multiple roles, and roles may have multiple but # overlapping recipients - so, here we find the unique recipients. @@ -396,6 +409,15 @@ do do [ "${r}" != "disabled" ] && filter_recipient_by_criticality pd "${r}" && arr_pd[${r/|*/}]="1" done + + # custom + a="${role_recipients_custom[${x}]}" + [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_CUSTOM}" + for r in ${a//,/ } + do + [ "${r}" != "disabled" ] && filter_recipient_by_criticality custom "${r}" && arr_custom[${r/|*/}]="1" + done + done # build the list of slack recipients (channels) @@ -434,6 +456,10 @@ to_telegram="${!arr_telegram[*]}" to_pd="${!arr_pd[*]}" [ -z "${to_pd}" ] && SEND_PD="NO" +# build the list of custom recipients +to_custom="${!arr_custom[*]}" +[ -z "${to_custom}" ] && SEND_CUSTOM="NO" + # build the list of email recipients (email addresses) to_email= for x in "${!arr_email[@]}" @@ -492,7 +518,7 @@ fi if [ \( \ "${SEND_PUSHOVER}" = "YES" \ -o "${SEND_SLACK}" = "YES" \ - -o "${SEND_DISCORD}" = "YES" \ + -o "${SEND_DISCORD}" = "YES" \ -o "${SEND_HIPCHAT}" = "YES" \ -o "${SEND_TWILIO}" = "YES" \ -o "${SEND_MESSAGEBIRD}" = "YES" \ @@ -530,13 +556,14 @@ if [ "${SEND_EMAIL}" != "YES" \ -a "${SEND_PUSHOVER}" != "YES" \ -a "${SEND_TELEGRAM}" != "YES" \ -a "${SEND_SLACK}" != "YES" \ - -a "${SEND_DISCORD}" != "YES" \ + -a "${SEND_DISCORD}" != "YES" \ -a "${SEND_TWILIO}" != "YES" \ -a "${SEND_HIPCHAT}" != "YES" \ -a "${SEND_MESSAGEBIRD}" != "YES" \ -a "${SEND_PUSHBULLET}" != "YES" \ -a "${SEND_KAFKA}" != "YES" \ -a "${SEND_PD}" != "YES" \ + -a "${SEND_CUSTOM}" != "YES" \ ] then fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'." @@ -939,9 +966,16 @@ send_messagebird() { # telegram sender send_telegram() { - local bottoken="${1}" chatids="${2}" message="${3}" httpcode sent=0 chatid disableNotification="" + local bottoken="${1}" chatids="${2}" message="${3}" httpcode sent=0 chatid emoji disableNotification="" if [ "${status}" = "CLEAR" ]; then disableNotification="--data-urlencode disable_notification=true"; fi + + case "${status}" in + WARNING) emoji="⚠️" ;; + CRITICAL) emoji="🔴" ;; + CLEAR) emoji="✅" ;; + *) emoji="⚪️" ;; + esac if [ "${SEND_TELEGRAM}" = "YES" -a ! -z "${bottoken}" -a ! -z "${chatids}" -a ! -z "${message}" ]; then @@ -951,7 +985,7 @@ send_telegram() { httpcode=$(${curl} --write-out %{http_code} --silent --output /dev/null ${disableNotification} \ --data-urlencode "parse_mode=HTML" \ --data-urlencode "disable_web_page_preview=true" \ - --data-urlencode "text=${message}" \ + --data-urlencode "text=${emoji} ${message}" \ "https://api.telegram.org/bot${bottoken}/sendMessage?chat_id=${chatid}") if [ "${httpcode}" == "200" ] @@ -1040,7 +1074,7 @@ EOF # discord sender send_discord() { - local webhook="${1}/slack" channels="${2}" httpcode sent=0 channel color payload + local webhook="${1}/slack" channels="${2}" httpcode sent=0 channel color payload username [ "${SEND_DISCORD}" != "YES" ] && return 1 @@ -1053,10 +1087,13 @@ send_discord() { for channel in ${channels} do + username="netdata on ${host}" + [ ${#username} -gt 32 ] && username="${username:0:29}..." + payload="$(cat <<EOF { "channel": "#${channel}", - "username": "netdata on ${host}", + "username": "${username}", "text": "${host} ${status_message}, \`${chart}\` (_${family}_), *${alarm}*", "icon_url": "${images_base_url}/images/seo-performance-128.png", "attachments": [ @@ -1101,7 +1138,7 @@ EOF # prepare the content of the notification # the url to send the user on click -urlencode "${NETDATA_REGISTRY_HOSTNAME}" >/dev/null; url_host="${REPLY}" +urlencode "${host}" >/dev/null; url_host="${REPLY}" urlencode "${chart}" >/dev/null; url_chart="${REPLY}" urlencode "${family}" >/dev/null; url_family="${REPLY}" urlencode "${name}" >/dev/null; url_name="${REPLY}" @@ -1282,6 +1319,24 @@ SENT_PD=$? # ----------------------------------------------------------------------------- +# send the custom message + +send_custom() { + # is it enabled? + [ "${SEND_CUSTOM}" != "YES" ] && return 1 + + # do we have any sender? + [ -z "${1}" ] && return 1 + + # call the custom_sender function + custom_sender "${@}" +} + +send_custom "${to_custom}" +SENT_CUSTOM=$? + + +# ----------------------------------------------------------------------------- # send hipchat message send_hipchat "${HIPCHAT_AUTH_TOKEN}" "${to_hipchat}" " \ @@ -1295,17 +1350,40 @@ ${host} ${status_message}<br/> \ SENT_HIPCHAT=$? + # ----------------------------------------------------------------------------- # send the email send_email <<EOF To: ${to_email} Subject: ${host} ${status_message} - ${name//_/ } - ${chart} +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="multipart-boundary" + +This is a MIME-encoded multipart message + +--multipart-boundary +Content-Type: text/plain + +${host} ${status_message} + +${alarm} ${info} +${raised_for} + +Chart : ${chart} +Family : ${family} +Severity: ${severity} +URL : ${goto_url} +Source : ${src} +Date : ${date} +Notification generated on ${this_host} + +--multipart-boundary Content-Type: text/html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;"> -<body style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 14px; width: 100% !important; min-height: 100%; line-height: 1.6; background: #f6f6f6; margin:0; padding: 0;"> +<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;"> +<body style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; width: 100% !important; min-height: 100%; line-height: 1.6; background: #f6f6f6; margin:0; padding: 0;"> <table> <tbody> <tr> @@ -1316,12 +1394,12 @@ Content-Type: text/html <tbody> <tr> <td bgcolor="#eee" style="padding: 5px 20px 5px 20px; background-color: #eee;"> - <div style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 20px; color: #777; font-weight: bold;">netdata notification</div> + <div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 20px; color: #777; font-weight: bold;">netdata notification</div> </td> </tr> <tr> <td bgcolor="${color}" style="font-size: 16px; vertical-align: top; font-weight: 400; text-align: center; margin: 0; padding: 10px; color: #ffffff; background: ${color} !important; border: 1px solid ${color}; border-top-color: ${color};" align="center" valign="top"> - <h1 style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0;">${host} ${status_message}</h1> + <h1 style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0;">${host} ${status_message}</h1> </td> </tr> <tr> @@ -1330,46 +1408,46 @@ Content-Type: text/html <table width="100%" cellpadding="0" cellspacing="0" style="max-width:700px"> <tbody> <tr> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding:0 0 20px;" align="left" valign="top"> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding:0 0 20px;" align="left" valign="top"> <span>${chart}</span> <span style="display: block; color: #666666; font-size: 12px; font-weight: 300; line-height: 1; text-transform: uppercase;">Chart</span> </td> </tr> <tr style="margin: 0; padding: 0;"> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"> <span><b>${alarm}</b>${info_html}</span> <span style="display: block; color: #666666; font-size: 12px; font-weight: 300; line-height: 1; text-transform: uppercase;">Alarm</span> </td> </tr> <tr> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"> <span>${family}</span> <span style="display: block; color: #666666; font-size: 12px; font-weight: 300; line-height: 1; text-transform: uppercase;">Family</span> </td> </tr> <tr style="margin: 0; padding: 0;"> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"> <span>${severity}</span> <span style="display: block; color: #666666; font-size: 12px; font-weight: 300; line-height: 1; text-transform: uppercase;">Severity</span> </td> </tr> <tr style="margin: 0; padding: 0;"> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"><span>${date}</span> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;" align="left" valign="top"><span>${date}</span> <span>${raised_for_html}</span> <span style="display: block; color: #666666; font-size: 12px; font-weight: 300; line-height: 1; text-transform: uppercase;">Time</span> </td> </tr> <tr style="margin: 0; padding: 0;"> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;"> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 18px; vertical-align: top; margin: 0; padding: 0 0 20px;"> <a href="${goto_url}" style="font-size: 14px; color: #ffffff; text-decoration: none; line-height: 1.5; font-weight: bold; text-align: center; display: inline-block; text-transform: capitalize; background: #35568d; border-width: 1px; border-style: solid; border-color: #2b4c86; margin: 0; padding: 10px 15px;" target="_blank">View Netdata</a> </td> </tr> <tr style="text-align: center; margin: 0; padding: 0;"> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 11px; vertical-align: top; margin: 0; padding: 10px 0 0 0; color: #666666;" align="center" valign="bottom">The source of this alarm is line <code>${src}</code> + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 11px; vertical-align: top; margin: 0; padding: 10px 0 0 0; color: #666666;" align="center" valign="bottom">The source of this alarm is line <code>${src}</code><br/>(alarms are configurable, edit this file to adapt the alarm to your needs) </td> </tr> <tr style="text-align: center; margin: 0; padding: 0;"> - <td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; font-size: 12px; vertical-align: top; margin:0; padding: 20px 0 0 0; color: #666666; border-top: 1px solid #f0f0f0;" align="center" valign="bottom">Sent by - <a href="https://mynetdata.io/" target="_blank">netdata</a>, the real-time performance monitoring. + <td style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; vertical-align: top; margin:0; padding: 20px 0 0 0; color: #666666; border-top: 1px solid #f0f0f0;" align="center" valign="bottom">Sent by + <a href="https://mynetdata.io/" target="_blank">netdata</a>, the real-time performance and health monitoring, on <code>${this_host}</code>. </td> </tr> </tbody> @@ -1404,6 +1482,7 @@ if [ ${SENT_EMAIL} -eq 0 \ -o ${SENT_PUSHBULLET} -eq 0 \ -o ${SENT_KAFKA} -eq 0 \ -o ${SENT_PD} -eq 0 \ + -o ${SENT_CUSTOM} -eq 0 \ ] then # we did send something diff --git a/plugins.d/alarm-test.sh b/plugins.d/alarm-test.sh index 1963111a5..9df5361a9 100755 --- a/plugins.d/alarm-test.sh +++ b/plugins.d/alarm-test.sh @@ -2,7 +2,7 @@ # netdata # real-time performance and health monitoring, done right! -# (C) 2016 Costa Tsaousis <costa@tsaousis.gr> +# (C) 2017 Costa Tsaousis <costa@tsaousis.gr> # GPL v3+ # # Script to test alarm notifications for netdata diff --git a/plugins.d/cgroup-name.sh b/plugins.d/cgroup-name.sh index a1e3abe08..dc0bf7553 100755 --- a/plugins.d/cgroup-name.sh +++ b/plugins.d/cgroup-name.sh @@ -51,7 +51,7 @@ debug() { # ----------------------------------------------------------------------------- -NETDATA_CONFIG_DIR="${NETDATA_CONFIG_DIR-/etc/netdata}" +[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata" CONFIG="${NETDATA_CONFIG_DIR}/cgroups-names.conf" CGROUP="${1}" NAME= @@ -74,22 +74,22 @@ if [ -f "${CONFIG}" ] # info "configuration file '${CONFIG}' is not available." fi -function get_name_classic { - local DOCKERID="$1" - info "Running command: docker ps --filter=id=\"${DOCKERID}\" --format=\"{{.Names}}\"" - NAME="$( docker ps --filter=id="${DOCKERID}" --format="{{.Names}}" )" +function docker_get_name_classic { + local id="${1}" + info "Running command: docker ps --filter=id=\"${id}\" --format=\"{{.Names}}\"" + NAME="$( docker ps --filter=id="${id}" --format="{{.Names}}" )" return 0 } -function get_name_api { - local DOCKERID="$1" +function docker_get_name_api { + local id="${1}" if [ ! -S "/var/run/docker.sock" ] then warning "Can't find /var/run/docker.sock" return 1 fi - info "Running API command: /containers/${DOCKERID}/json" - JSON=$(echo -e "GET /containers/${DOCKERID}/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock | egrep '^{.*') + info "Running API command: /containers/${id}/json" + JSON=$(echo -e "GET /containers/${id}/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock | grep '^{.*') NAME=$(echo $JSON | jq -r .Name,.Config.Hostname | grep -v null | head -n1 | sed 's|^/||') return 0 } @@ -107,9 +107,9 @@ if [ -z "${NAME}" ] then if hash docker 2>/dev/null then - get_name_classic $DOCKERID + docker_get_name_classic ${DOCKERID} else - get_name_api $DOCKERID || get_name_classic $DOCKERID + docker_get_name_api ${DOCKERID} || docker_get_name_classic ${DOCKERID} fi if [ -z "${NAME}" ] then @@ -123,7 +123,31 @@ if [ -z "${NAME}" ] then # libvirtd / qemu virtual machines - NAME="$(echo ${CGROUP} | sed 's/machine.slice_machine.*-qemu//; s/\/x2d//; s/\/x2d/\-/g; s/\.scope//g')" + # NAME="$(echo ${CGROUP} | sed 's/machine.slice_machine.*-qemu//; s/\/x2d//; s/\/x2d/\-/g; s/\.scope//g')" + NAME="qemu_$(echo ${CGROUP} | sed 's/machine.slice_machine.*-qemu//; s/\/x2d[[:digit:]]*//; s/\/x2d//g; s/\.scope//g')" + + elif [[ "${CGROUP}" =~ qemu.slice_([0-9]+).scope && -d /etc/pve ]] + then + # Proxmox VMs + + FILENAME="/etc/pve/qemu-server/${BASH_REMATCH[1]}.conf" + if [[ -f $FILENAME && -r $FILENAME ]] + then + NAME="qemu_$(grep -e '^name: ' "/etc/pve/qemu-server/${BASH_REMATCH[1]}.conf" | head -1 | sed -rn 's|\s*name\s*:\s*(.*)?$|\1|p')" + else + error "proxmox config file missing ${FILENAME} or netdata does not have read access. Please ensure netdata is a member of www-data group." + fi + elif [[ "${CGROUP}" =~ lxc_([0-9]+) && -d /etc/pve ]] + then + # Proxmox Containers (LXC) + + FILENAME="/etc/pve/lxc/${BASH_REMATCH[1]}.conf" + if [[ -f ${FILENAME} && -r ${FILENAME} ]] + then + NAME=$(grep -e '^hostname: ' /etc/pve/lxc/${BASH_REMATCH[1]}.conf | head -1 | sed -rn 's|\s*hostname\s*:\s*(.*)?$|\1|p') + else + error "proxmox config file missing ${FILENAME} or netdata does not have read access. Please ensure netdata is a member of www-data group." + fi fi [ -z "${NAME}" ] && NAME="${CGROUP}" diff --git a/plugins.d/charts.d.plugin b/plugins.d/charts.d.plugin index 00206f95f..eda5c0de4 100755 --- a/plugins.d/charts.d.plugin +++ b/plugins.d/charts.d.plugin @@ -2,7 +2,7 @@ # netdata # real-time performance and health monitoring, done right! -# (C) 2016 Costa Tsaousis <costa@tsaousis.gr> +# (C) 2017 Costa Tsaousis <costa@tsaousis.gr> # GPL v3+ # # charts.d.plugin allows easy development of BASH plugins @@ -115,10 +115,11 @@ info "started from '$PROGRAM_FILE' with options: $*" # internal defaults # netdata exposes a few environment variables for us -pluginsd="${NETDATA_PLUGINS_DIR}" -[ -z "$pluginsd" ] && pluginsd="$( dirname $PROGRAM_FILE )" +[ -z "${NETDATA_PLUGINS_DIR}" ] && NETDATA_PLUGINS_DIR="$(dirname "${0}")" +[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata" -confd="${NETDATA_CONFIG_DIR-/etc/netdata}" +pluginsd="${NETDATA_PLUGINS_DIR}" +confd="${NETDATA_CONFIG_DIR}" chartsd="$pluginsd/../charts.d" myconfig="$confd/$PROGRAM_NAME.conf" diff --git a/plugins.d/fping.plugin b/plugins.d/fping.plugin index 232c00630..b6d981a85 100755 --- a/plugins.d/fping.plugin +++ b/plugins.d/fping.plugin @@ -2,7 +2,7 @@ # netdata # real-time performance and health monitoring, done right! -# (C) 2016 Costa Tsaousis <costa@tsaousis.gr> +# (C) 2017 Costa Tsaousis <costa@tsaousis.gr> # GPL v3+ # # This plugin requires a latest version of fping. @@ -37,25 +37,15 @@ if [ "${1}" = "install" ] run cd /usr/src - if [ -d fping-3.15 ] + if [ -d fping-4.0 ] then - run rm -rf fping-3.15 || exit 1 + run rm -rf fping-4.0 || exit 1 fi - download 'https://github.com/schweikert/fping/archive/3.15.tar.gz' | run tar -zxvpf - + download 'https://github.com/schweikert/fping/releases/download/v4.0/fping-4.0.tar.gz' | run tar -zxvpf - [ $? -ne 0 ] && exit 1 - run cd fping-3.15 || exit 1 - - #if [ -d fping-ktsaou.git ] - # then - # run cd fping-ktsaou.git - # run git pull - #else - # run git clone https://github.com/ktsaou/fping.git fping-ktsaou.git - # run cd fping-ktsaou.git - #fi - - run ./autogen.sh + run cd fping-4.0 || exit 1 + run ./configure --prefix=/usr/local run make clean run make @@ -139,7 +129,7 @@ update_every="${1-1}" # the netdata configuration directory # passed by netdata as an environment variable -NETDATA_CONFIG_DIR="${NETDATA_CONFIG_DIR-/etc/netdata}" +[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata" # ----------------------------------------------------------------------------- # configuration options @@ -173,7 +163,7 @@ source "${NETDATA_CONFIG_DIR}/${plugin}.conf" if [ -z "${hosts}" ] then - fatal "no hosts configued in '${NETDATA_CONFIG_DIR}/${plugin}.conf' - nothing to do." + fatal "no hosts configured in '${NETDATA_CONFIG_DIR}/${plugin}.conf' - nothing to do." fi if [ -z "${fping}" -o ! -x "${fping}" ] diff --git a/plugins.d/node.d.plugin b/plugins.d/node.d.plugin index 8b7047fcb..b16203912 100755 --- a/plugins.d/node.d.plugin +++ b/plugins.d/node.d.plugin @@ -4,13 +4,13 @@ // shebang hack from: // http://unix.stackexchange.com/questions/65235/universal-node-js-shebang -// Initially this is run as a shell script (#!/bin/sh). +// Initially this is run as a shell script. // Then, the second line, finds nodejs or node or js in the system path // and executes it with the shell parameters. // netdata // real-time performance and health monitoring, done right! -// (C) 2016 Costa Tsaousis <costa@tsaousis.gr> +// (C) 2017 Costa Tsaousis <costa@tsaousis.gr> // GPL v3+ // -------------------------------------------------------------------------------------------------------------------- @@ -21,7 +21,7 @@ // get NETDATA environment variables var NETDATA_PLUGINS_DIR = process.env.NETDATA_PLUGINS_DIR || __dirname; -var NETDATA_CONFIG_DIR = process.env.NETDATA_CONFIG_DIR || '/etc/netdata'; +var NETDATA_CONFIG_DIR = process.env.NETDATA_CONFIG_DIR || __dirname + '/../../../../etc/netdata'; var NETDATA_UPDATE_EVERY = process.env.NETDATA_UPDATE_EVERY || 1; var NODE_D_DIR = NETDATA_PLUGINS_DIR + '/../node.d'; diff --git a/plugins.d/python.d.plugin b/plugins.d/python.d.plugin index efa62cbc5..03c156f41 100755 --- a/plugins.d/python.d.plugin +++ b/plugins.d/python.d.plugin @@ -20,8 +20,11 @@ BASE_CONFIG = {'update_every': os.getenv('NETDATA_UPDATE_EVERY', 1), 'retries': 10} MODULES_DIR = os.path.abspath(os.getenv('NETDATA_PLUGINS_DIR', - os.path.dirname(__file__)) + "/../python.d") + "/" -CONFIG_DIR = os.getenv('NETDATA_CONFIG_DIR', "/etc/netdata/") + os.path.dirname(__file__)) + "/../python.d") + "/" + +CONFIG_DIR = os.getenv('NETDATA_CONFIG_DIR', + os.path.dirname(__file__) + "/../../../../etc/netdata") + # directories should end with '/' if CONFIG_DIR[-1] != "/": CONFIG_DIR += "/" @@ -307,7 +310,7 @@ class PythonCharts(object): ("/" + str(name) if name is not None else "") + ": cannot start job: '" + str(e)) - return None + continue else: # set chart_name (needed to plot run time graphs) job.chart_name = module.__name__ @@ -460,11 +463,11 @@ def read_config(path): config = ordered_load(stream, yaml.SafeLoader) else: config = yaml.load(stream) - except (OSError, IOError): - msg.error(str(path), "is not a valid configuration file") + except (OSError, IOError) as error: + msg.error(str(path), 'reading error:', str(error)) return None - except yaml.YAMLError as e: - msg.error(str(path), "is malformed:", e) + except yaml.YAMLError as error: + msg.error(str(path), "is malformed:", str(error)) return None return config @@ -516,7 +519,7 @@ def run(): global DEBUG_FLAG, TRACE_FLAG, BASE_CONFIG # read configuration file - disabled = ['nginx_log', 'gunicorn_log'] + disabled = ['nginx_log', 'gunicorn_log', 'apache_cache'] enabled = list() default_run = True configfile = CONFIG_DIR + "python.d.conf" diff --git a/plugins.d/tc-qos-helper.sh b/plugins.d/tc-qos-helper.sh index 074fece9a..9153f22e2 100755 --- a/plugins.d/tc-qos-helper.sh +++ b/plugins.d/tc-qos-helper.sh @@ -2,7 +2,7 @@ # netdata # real-time performance and health monitoring, done right! -# (C) 2016 Costa Tsaousis <costa@tsaousis.gr> +# (C) 2017 Costa Tsaousis <costa@tsaousis.gr> # GPL v3+ # # This script is a helper to allow netdata collect tc data. @@ -101,10 +101,11 @@ debug() { # ----------------------------------------------------------------------------- -plugins_dir="${NETDATA_PLUGINS_DIR}" -[ -z "$plugins_dir" ] && plugins_dir="$( dirname $PROGRAM_FILE )" +[ -z "${NETDATA_PLUGINS_DIR}" ] && NETDATA_PLUGINS_DIR="$(dirname "${0}")" +[ -z "${NETDATA_CONFIG_DIR}" ] && NETDATA_CONFIG_DIR="$(dirname "${0}")/../../../../etc/netdata" -config_dir=${NETDATA_CONFIG_DIR-/etc/netdata} +plugins_dir="${NETDATA_PLUGINS_DIR}" +config_dir="${NETDATA_CONFIG_DIR}" tc="$(which tc 2>/dev/null || command -v tc 2>/dev/null)" |