summaryrefslogtreecommitdiffstats
path: root/plugins.d
diff options
context:
space:
mode:
Diffstat (limited to 'plugins.d')
-rw-r--r--plugins.d/Makefile.in141
-rwxr-xr-xplugins.d/alarm-notify.sh162
-rwxr-xr-xplugins.d/cgroup-name.sh7
-rwxr-xr-xplugins.d/fping.plugin31
-rwxr-xr-xplugins.d/python.d.plugin76
-rwxr-xr-xplugins.d/tc-qos-helper.sh100
6 files changed, 351 insertions, 166 deletions
diff --git a/plugins.d/Makefile.in b/plugins.d/Makefile.in
index 7e90c9808..2a8806cb1 100644
--- a/plugins.d/Makefile.in
+++ b/plugins.d/Makefile.in
@@ -1,8 +1,9 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
-
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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.
@@ -16,61 +17,6 @@
VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
-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@
@@ -90,9 +36,11 @@ 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
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__generic.m4 $(top_srcdir)/m4/ax_c_lto.m4 \
$(top_srcdir)/m4/ax_c_mallinfo.m4 \
$(top_srcdir)/m4/ax_c_mallopt.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
@@ -101,8 +49,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___atomic.m4 \
$(top_srcdir)/m4/tcmalloc.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_plugins_SCRIPTS) \
- $(dist_plugins_DATA) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
@@ -136,32 +82,12 @@ 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)
-am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@@ -185,7 +111,11 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPMIMONITORING_CFLAGS = @IPMIMONITORING_CFLAGS@
+IPMIMONITORING_LIBS = @IPMIMONITORING_LIBS@
LDFLAGS = @LDFLAGS@
+LIBCAP_CFLAGS = @LIBCAP_CFLAGS@
+LIBCAP_LIBS = @LIBCAP_LIBS@
LIBMNL_CFLAGS = @LIBMNL_CFLAGS@
LIBMNL_LIBS = @LIBMNL_LIBS@
LIBOBJS = @LIBOBJS@
@@ -199,6 +129,10 @@ MKDIR_P = @MKDIR_P@
NFACCT_CFLAGS = @NFACCT_CFLAGS@
NFACCT_LIBS = @NFACCT_LIBS@
OBJEXT = @OBJEXT@
+OPTIONAL_IPMIMONITORING_CFLAGS = @OPTIONAL_IPMIMONITORING_CFLAGS@
+OPTIONAL_IPMIMONITORING_LIBS = @OPTIONAL_IPMIMONITORING_LIBS@
+OPTIONAL_LIBCAP_CFLAGS = @OPTIONAL_LIBCAP_CFLAGS@
+OPTIONAL_LIBCAP_LIBS = @OPTIONAL_LIBCAP_LIBS@
OPTIONAL_MATH_CLFAGS = @OPTIONAL_MATH_CLFAGS@
OPTIONAL_MATH_LIBS = @OPTIONAL_MATH_LIBS@
OPTIONAL_NFACCT_CLFAGS = @OPTIONAL_NFACCT_CLFAGS@
@@ -333,6 +267,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plugins.d/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu plugins.d/Makefile
+.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -352,11 +287,8 @@ $(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; \
@@ -387,11 +319,8 @@ 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"; \
@@ -406,11 +335,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:
-
-ctags CTAGS:
+tags: TAGS
+TAGS:
-cscope cscopelist:
+ctags: CTAGS
+CTAGS:
distdir: $(DISTFILES)
@@ -549,20 +478,18 @@ uninstall-am: uninstall-dist_pluginsDATA uninstall-dist_pluginsSCRIPTS
.MAKE: install-am install-strip
-.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
-
-.PRECIOUS: Makefile
+.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
# 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 d6f3d8b2a..d0188fe3b 100755
--- a/plugins.d/alarm-notify.sh
+++ b/plugins.d/alarm-notify.sh
@@ -16,6 +16,7 @@
# Supported notification methods:
# - emails by @ktsaou
# - 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
@@ -23,7 +24,7 @@
# - kafka notifications by @ktsaou #1342
# - pagerduty.com notifications by Jim Cooley @jimcooley PR #1373
# - messagebird.com notifications by @tech_no_logical #1453
-# - hipchart notifications by @ktsaou #1561
+# - hipchat notifications by @ktsaou #1561
# -----------------------------------------------------------------------------
# testing notifications
@@ -46,7 +47,7 @@ then
echo >&2
echo >&2 "# SENDING TEST ${x} ALARM TO ROLE: ${recipient}"
- "${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"
+ "${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"
if [ $? -ne 0 ]
then
echo >&2 "# FAILED"
@@ -138,6 +139,15 @@ duration="${15}" # the duration in seconds of the previous alarm state
non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
units="${17}" # the units of the value
info="${18}" # a short description of the alarm
+value_string="${19}" # friendly value (with units)
+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)"
# -----------------------------------------------------------------------------
# screen statuses we don't need to send a notification
@@ -145,14 +155,14 @@ info="${18}" # a short description of the alarm
# don't do anything if this is not WARNING, CRITICAL or CLEAR
if [ "${status}" != "WARNING" -a "${status}" != "CRITICAL" -a "${status}" != "CLEAR" ]
then
- info "not sending notification for ${status} on '${chart}.${name}'"
+ info "not sending notification for ${status} of '${host}.${chart}.${name}'"
exit 1
fi
# don't do anything if this is CLEAR, but it was not WARNING or CRITICAL
if [ "${old_status}" != "WARNING" -a "${old_status}" != "CRITICAL" -a "${status}" = "CLEAR" ]
then
- info "not sending notification for ${status} on '${chart}.${name}' (last status was ${old_status})"
+ info "not sending notification for ${status} of '${host}.${chart}.${name}' (last status was ${old_status})"
exit 1
fi
@@ -172,6 +182,7 @@ sendmail=
# enable / disable features
SEND_SLACK="YES"
+SEND_DISCORD="YES"
SEND_PUSHOVER="YES"
SEND_TWILIO="YES"
SEND_HIPCHAT="YES"
@@ -187,6 +198,11 @@ SLACK_WEBHOOK_URL=
DEFAULT_RECIPIENT_SLACK=
declare -A role_recipients_slack=()
+# discord configs
+DISCORD_WEBHOOK_URL=
+DEFAULT_RECIPIENT_DISCORD=
+declare -A role_recipients_discord=()
+
# pushover configs
PUSHOVER_APP_TOKEN=
DEFAULT_RECIPIENT_PUSHOVER=
@@ -205,6 +221,7 @@ DEFAULT_RECIPIENT_TWILIO=
declare -A role_recipients_twilio=()
# hipchat configs
+HIPCHAT_SERVER=
HIPCHAT_AUTH_TOKEN=
DEFAULT_RECIPIENT_HIPCHAT=
declare -A role_recipients_hipchat=()
@@ -283,6 +300,7 @@ filter_recipient_by_criticality() {
# find the recipients' addresses per method
declare -A arr_slack=()
+declare -A arr_discord=()
declare -A arr_pushover=()
declare -A arr_pushbullet=()
declare -A arr_twilio=()
@@ -363,6 +381,14 @@ do
[ "${r}" != "disabled" ] && filter_recipient_by_criticality slack "${r}" && arr_slack[${r/|*/}]="1"
done
+ # discord
+ a="${role_recipients_discord[${x}]}"
+ [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_DISCORD}"
+ for r in ${a//,/ }
+ do
+ [ "${r}" != "disabled" ] && filter_recipient_by_criticality discord "${r}" && arr_discord[${r/|*/}]="1"
+ done
+
# pagerduty.com
a="${role_recipients_pd[${x}]}"
[ -z "${a}" ] && a="${DEFAULT_RECIPIENT_PD}"
@@ -376,6 +402,10 @@ done
to_slack="${!arr_slack[*]}"
[ -z "${to_slack}" ] && SEND_SLACK="NO"
+# build the list of discord recipients (channels)
+to_discord="${!arr_discord[*]}"
+[ -z "${to_discord}" ] && SEND_DISCORD="NO"
+
# build the list of pushover recipients (user tokens)
to_pushover="${!arr_pushover[*]}"
[ -z "${to_pushover}" ] && SEND_PUSHOVER="NO"
@@ -420,6 +450,9 @@ done
# check slack
[ -z "${SLACK_WEBHOOK_URL}" ] && SEND_SLACK="NO"
+# check discord
+[ -z "${DISCORD_WEBHOOK_URL}" ] && SEND_DISCORD="NO"
+
# check pushover
[ -z "${PUSHOVER_APP_TOKEN}" ] && SEND_PUSHOVER="NO"
@@ -459,6 +492,7 @@ fi
if [ \( \
"${SEND_PUSHOVER}" = "YES" \
-o "${SEND_SLACK}" = "YES" \
+ -o "${SEND_DISCORD}" = "YES" \
-o "${SEND_HIPCHAT}" = "YES" \
-o "${SEND_TWILIO}" = "YES" \
-o "${SEND_MESSAGEBIRD}" = "YES" \
@@ -476,6 +510,7 @@ if [ \( \
SEND_PUSHBULLET="NO"
SEND_TELEGRAM="NO"
SEND_SLACK="NO"
+ SEND_DISCORD="NO"
SEND_TWILIO="NO"
SEND_HIPCHAT="NO"
SEND_MESSAGEBIRD="NO"
@@ -495,6 +530,7 @@ if [ "${SEND_EMAIL}" != "YES" \
-a "${SEND_PUSHOVER}" != "YES" \
-a "${SEND_TELEGRAM}" != "YES" \
-a "${SEND_SLACK}" != "YES" \
+ -a "${SEND_DISCORD}" != "YES" \
-a "${SEND_TWILIO}" != "YES" \
-a "${SEND_HIPCHAT}" != "YES" \
-a "${SEND_MESSAGEBIRD}" != "YES" \
@@ -503,17 +539,10 @@ if [ "${SEND_EMAIL}" != "YES" \
-a "${SEND_PD}" != "YES" \
]
then
- fatal "All notification methods are disabled. Not sending notification to '${roles}' for '${name}' = '${value}' of chart '${chart}' for status '${status}'."
+ fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'."
fi
# -----------------------------------------------------------------------------
-# 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)"
-
-# -----------------------------------------------------------------------------
# get the date the alarm happened
date="$(date --date=@${when} 2>/dev/null)"
@@ -747,13 +776,13 @@ send_pd() {
then
for PD_SERVICE_KEY in ${recipients}
do
- d="${status} ${name}=${value} ${units} - ${host}, ${family}"
+ d="${status} ${name} = ${value_string} - ${host}, ${family}"
${pd_send} -k ${PD_SERVICE_KEY} \
-t ${t} \
-d "${d}" \
-i ${alarm_id} \
-f 'info'="${info}" \
- -f 'value_w_units'="${value} ${units}" \
+ -f 'value_w_units'="${value_string}" \
-f 'when'="${when}" \
-f 'duration'="${duration}" \
-f 'roles'="${roles}" \
@@ -774,10 +803,10 @@ send_pd() {
retval=$?
if [ ${retval} -eq 0 ]
then
- info "sent pagerduty.com notification using service key ${PD_SERVICE_KEY::-26}....: ${d}"
+ info "sent pagerduty.com notification for host ${host} ${chart}.${name} using service key ${PD_SERVICE_KEY::-26}....: ${d}"
sent=$((sent + 1))
else
- error "failed to send pagerduty.com notification using service key ${PD_SERVICE_KEY::-26}.... (error code ${retval}): ${d}"
+ error "failed to send pagerduty.com notification for ${host} ${chart}.${name} using service key ${PD_SERVICE_KEY::-26}.... (error code ${retval}): ${d}"
fi
done
@@ -826,16 +855,15 @@ send_twilio() {
send_hipchat() {
local authtoken="${1}" recipients="${2}" message="${3}" httpcode sent=0 room color sender msg_format notify
- if [ "${SEND_HIPCHAT}" = "YES" -a ! -z "${authtoken}" -a ! -z "${recipients}" -a ! -z "${message}" ]
- then
-
+ if [ "${SEND_HIPCHAT}" = "YES" -a ! -z "${HIPCHAT_SERVER}" -a ! -z "${authtoken}" -a ! -z "${recipients}" -a ! -z "${message}" ]
+ then
# A label to be shown in addition to the sender's name
# Valid length range: 0 - 64.
sender="netdata"
# Valid values: html, text.
# Defaults to 'html'.
- msg_format="text"
+ msg_format="html"
# Background color for message. Valid values: yellow, green, red, purple, gray, random. Defaults to 'yellow'.
case "${status}" in
@@ -856,9 +884,9 @@ send_hipchat() {
-H "Content-type: application/json" \
-H "Authorization: Bearer ${authtoken}" \
-d "{\"color\": \"${color}\", \"from\": \"${netdata}\", \"message_format\": \"${msg_format}\", \"message\": \"${message}\", \"notify\": \"${notify}\"}" \
- "https://api.hipchat.com/v2/room/${room}/notification")
-
- if [ "${httpcode}" == "200" ]
+ "https://${HIPCHAT_SERVER}/v2/room/${room}/notification")
+
+ if [ "${httpcode}" == "204" ]
then
info "sent HipChat notification for: ${host} ${chart}.${name} is ${status} to '${room}'"
sent=$((sent + 1))
@@ -1008,6 +1036,66 @@ EOF
return 1
}
+# -----------------------------------------------------------------------------
+# discord sender
+
+send_discord() {
+ local webhook="${1}/slack" channels="${2}" httpcode sent=0 channel color payload
+
+ [ "${SEND_DISCORD}" != "YES" ] && return 1
+
+ case "${status}" in
+ WARNING) color="warning" ;;
+ CRITICAL) color="danger" ;;
+ CLEAR) color="good" ;;
+ *) color="#777777" ;;
+ esac
+
+ for channel in ${channels}
+ do
+ payload="$(cat <<EOF
+ {
+ "channel": "#${channel}",
+ "username": "netdata on ${host}",
+ "text": "${host} ${status_message}, \`${chart}\` (_${family}_), *${alarm}*",
+ "icon_url": "${images_base_url}/images/seo-performance-128.png",
+ "attachments": [
+ {
+ "color": "${color}",
+ "title": "${alarm}",
+ "title_link": "${goto_url}",
+ "text": "${info}",
+ "fields": [
+ {
+ "title": "${chart}",
+ "value": "${family}"
+ }
+ ],
+ "thumb_url": "${image}",
+ "footer_icon": "${images_base_url}/images/seo-performance-128.png",
+ "footer": "${host}",
+ "ts": ${when}
+ }
+ ]
+ }
+EOF
+ )"
+
+ httpcode=$(${curl} --write-out %{http_code} --silent --output /dev/null -X POST --data-urlencode "payload=${payload}" "${webhook}")
+ if [ "${httpcode}" == "200" ]
+ then
+ info "sent discord notification for: ${host} ${chart}.${name} is ${status} to '${channel}'"
+ sent=$((sent + 1))
+ else
+ error "failed to send discord notification for: ${host} ${chart}.${name} is ${status} to '${channel}', with HTTP error code ${httpcode}."
+ fi
+ done
+
+ [ ${sent} -gt 0 ] && return 0
+
+ return 1
+}
+
# -----------------------------------------------------------------------------
# prepare the content of the notification
@@ -1034,7 +1122,7 @@ status_message="status unknown"
color="grey"
# the alarm value
-alarm="${name//_/ } = ${value} ${units}"
+alarm="${name//_/ } = ${value_string}"
# the image of the alarm
image="${images_base_url}/images/seo-performance-128.png"
@@ -1109,6 +1197,15 @@ send_slack "${SLACK_WEBHOOK_URL}" "${to_slack}"
SENT_SLACK=$?
# -----------------------------------------------------------------------------
+# send the discord notification
+
+# discord aggregates posts from the same username
+# so we use "${host} ${status}" as the bot username, to make them diff
+
+send_discord "${DISCORD_WEBHOOK_URL}" "${to_discord}"
+SENT_DISCORD=$?
+
+# -----------------------------------------------------------------------------
# send the pushover notification
send_pushover "${PUSHOVER_APP_TOKEN}" "${to_pushover}" "${when}" "${goto_url}" "${status}" "${host} ${status_message} - ${name//_/ } - ${chart}" "
@@ -1187,14 +1284,13 @@ SENT_PD=$?
# -----------------------------------------------------------------------------
# send hipchat message
-send_hipchat "${HIPCHAT_AUTH_TOKEN}" "${to_hipchat}" "
-<b>${alarm}</b> ${info_html}<br/>&nbsp;
-<small><b>${chart}</b><br/>Chart<br/>&nbsp;</small>
-<small><b>${family}</b><br/>Family<br/>&nbsp;</small>
-<small><b>${severity}</b><br/>Severity<br/>&nbsp;</small>
-<small><b>${date}${raised_for_html}</b><br/>Time<br/>&nbsp;</small>
-<a href=\"${goto_url}\">View Netdata</a><br/>&nbsp;
-<small><small>The source of this alarm is line ${src}</small></small>
+send_hipchat "${HIPCHAT_AUTH_TOKEN}" "${to_hipchat}" " \
+${host} ${status_message}<br/> \
+<b>${alarm}</b> ${info_html}<br/> \
+<b>${chart}</b> (family <b>${family}</b>)<br/> \
+<b>${date}${raised_for_html}</b><br/> \
+<a href=\\\"${goto_url}\\\">View netdata dashboard</a> \
+(source of alarm ${src}) \
"
SENT_HIPCHAT=$?
@@ -1301,6 +1397,7 @@ if [ ${SENT_EMAIL} -eq 0 \
-o ${SENT_PUSHOVER} -eq 0 \
-o ${SENT_TELEGRAM} -eq 0 \
-o ${SENT_SLACK} -eq 0 \
+ -o ${SENT_DISCORD} -eq 0 \
-o ${SENT_TWILIO} -eq 0 \
-o ${SENT_HIPCHAT} -eq 0 \
-o ${SENT_MESSAGEBIRD} -eq 0 \
@@ -1315,3 +1412,4 @@ fi
# we did not send anything
exit 1
+
diff --git a/plugins.d/cgroup-name.sh b/plugins.d/cgroup-name.sh
index 9bb3bcabb..a1e3abe08 100755
--- a/plugins.d/cgroup-name.sh
+++ b/plugins.d/cgroup-name.sh
@@ -98,6 +98,8 @@ if [ -z "${NAME}" ]
then
if [[ "${CGROUP}" =~ ^.*docker[-_/\.][a-fA-F0-9]+[-_\.]?.*$ ]]
then
+ # docker containers
+
DOCKERID="$( echo "${CGROUP}" | sed "s|^.*docker[-_/]\([a-fA-F0-9]\+\)[-_\.]\?.*$|\1|" )"
# echo "DOCKERID=${DOCKERID}"
@@ -117,6 +119,11 @@ if [ -z "${NAME}" ]
info "docker container '${DOCKERID}' is named '${NAME}'"
fi
fi
+ elif [[ "${CGROUP}" =~ machine.slice_machine.*-qemu ]]
+ then
+ # libvirtd / qemu virtual machines
+
+ NAME="$(echo ${CGROUP} | sed 's/machine.slice_machine.*-qemu//; s/\/x2d//; s/\/x2d/\-/g; s/\.scope//g')"
fi
[ -z "${NAME}" ] && NAME="${CGROUP}"
diff --git a/plugins.d/fping.plugin b/plugins.d/fping.plugin
index d523f4474..232c00630 100755
--- a/plugins.d/fping.plugin
+++ b/plugins.d/fping.plugin
@@ -22,20 +22,39 @@ if [ "${1}" = "install" ]
"${@}" || exit 1
}
+ download() {
+ local curl="$(which curl 2>/dev/null || command -v curl 2>/dev/null)"
+ [ ! -z "${curl}" ] && run curl -s -L "${1}" && return 0
+
+ local wget="$(which wget 2>/dev/null || command -v wget 2>/dev/null)"
+ [ ! -z "${wget}" ] && run wget -q -O - "${1}" && return 0
+
+ echo >&2 "Cannot find 'curl' or 'wget' in this system." && exit 1
+ }
+
[ ! -d /usr/src ] && run mkdir -p /usr/src
[ ! -d /usr/local/bin ] && run mkdir -p /usr/local/bin
run cd /usr/src
- if [ -d fping-ktsaou.git ]
+ if [ -d fping-3.15 ]
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
+ run rm -rf fping-3.15 || exit 1
fi
+ download 'https://github.com/schweikert/fping/archive/3.15.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 ./configure --prefix=/usr/local
run make clean
diff --git a/plugins.d/python.d.plugin b/plugins.d/python.d.plugin
index b4e6473a6..efa62cbc5 100755
--- a/plugins.d/python.d.plugin
+++ b/plugins.d/python.d.plugin
@@ -67,6 +67,34 @@ try:
except ImportError:
msg.fatal('Cannot find yaml library')
+try:
+ from collections import OrderedDict
+ ORDERED = True
+ DICT = OrderedDict
+ msg.info('YAML output is ordered')
+except ImportError:
+ try:
+ from ordereddict import OrderedDict
+ ORDERED = True
+ DICT = OrderedDict
+ msg.info('YAML output is ordered')
+ except ImportError:
+ ORDERED = False
+ DICT = dict
+ msg.info('YAML output is unordered')
+if ORDERED:
+ def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
+ class OrderedLoader(Loader):
+ pass
+
+ def construct_mapping(loader, node):
+ loader.flatten_mapping(node)
+ return object_pairs_hook(loader.construct_pairs(node))
+ OrderedLoader.add_constructor(
+ yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
+ construct_mapping)
+ return yaml.load(stream, OrderedLoader)
+
class PythonCharts(object):
"""
@@ -77,12 +105,16 @@ class PythonCharts(object):
modules=None,
modules_path='../python.d/',
modules_configs='../conf.d/',
- modules_disabled=None):
+ modules_disabled=None,
+ modules_enabled=None,
+ default_run=None):
"""
:param modules: list
:param modules_path: str
:param modules_configs: str
:param modules_disabled: list
+ :param modules_enabled: list
+ :param default_run: bool
"""
if modules is None:
@@ -95,13 +127,13 @@ class PythonCharts(object):
self.configs = modules_configs
# load modules
- loaded_modules = self._load_modules(modules_path, modules, modules_disabled)
+ loaded_modules = self._load_modules(modules_path, modules, modules_disabled, modules_enabled, default_run)
# load configuration files
configured_modules = self._load_configs(loaded_modules)
# good economy and prosperity:
- self.jobs = self._create_jobs(configured_modules) # type: list
+ self.jobs = self._create_jobs(configured_modules) # type <list>
# enable timetable override like `python.d.plugin mysql debug 1`
if DEBUG_FLAG and OVERRIDE_UPDATE_EVERY:
@@ -131,7 +163,7 @@ class PythonCharts(object):
msg.error("Problem loading", name, str(e))
return None
- def _load_modules(self, path, modules, disabled):
+ def _load_modules(self, path, modules, disabled, enabled, default_run):
"""
Load modules from 'modules' list or dynamically every file from 'path' (only .chart.py files)
:param path: str
@@ -157,7 +189,10 @@ class PythonCharts(object):
msg.fatal('no modules found.')
else:
# scan directory specified in path and load all modules from there
- names = os.listdir(path)
+ if default_run is False:
+ names = [module for module in os.listdir(path) if module[:-9] in enabled]
+ else:
+ names = os.listdir(path)
for mod in names:
if mod.replace(MODULE_EXTENSION, "") in disabled:
msg.error(mod + ": disabled module ", mod.replace(MODULE_EXTENSION, ""))
@@ -235,7 +270,7 @@ class PythonCharts(object):
# check if there are dict in config dict
many_jobs = False
for name in config:
- if type(config[name]) is dict:
+ if isinstance(config[name], DICT):
many_jobs = True
break
@@ -343,7 +378,8 @@ class PythonCharts(object):
if job.override_name is not None:
new_name = job.__module__ + '_' + sub(r'\s+', '_', job.override_name)
if new_name in overridden:
- msg.info("DROPPED:", job.name, ", job '" + job.override_name + "' is already served by another job.")
+ msg.info("DROPPED:", job.name, ", job '" + job.override_name +
+ "' is already served by another job.")
self._stop(job)
i -= 1
else:
@@ -420,7 +456,10 @@ def read_config(path):
"""
try:
with open(path, 'r') as stream:
- config = yaml.load(stream)
+ if ORDERED:
+ config = ordered_load(stream, yaml.SafeLoader)
+ else:
+ config = yaml.load(stream)
except (OSError, IOError):
msg.error(str(path), "is not a valid configuration file")
return None
@@ -452,7 +491,7 @@ def parse_cmdline(directory, *commands):
elif cmd == "trace" or cmd == "all":
TRACE_FLAG = True
elif os.path.isfile(directory + cmd + ".chart.py") or os.path.isfile(directory + cmd):
- #DEBUG_FLAG = True
+ # DEBUG_FLAG = True
mods.append(cmd.replace(".chart.py", ""))
else:
try:
@@ -477,7 +516,9 @@ def run():
global DEBUG_FLAG, TRACE_FLAG, BASE_CONFIG
# read configuration file
- disabled = []
+ disabled = ['nginx_log', 'gunicorn_log']
+ enabled = list()
+ default_run = True
configfile = CONFIG_DIR + "python.d.conf"
msg.PROGRAM = PROGRAM
msg.info("reading configuration file:", configfile)
@@ -519,12 +560,17 @@ def run():
except (KeyError, TypeError):
pass
+ default_run = True if ('default_run' not in conf or conf.get('default_run')) else False
+
for k, v in conf.items():
- if k in ("update_every", "debug", "enabled"):
+ if k in ("update_every", "debug", "enabled", "default_run"):
continue
- if v is False:
- disabled.append(k)
-
+ if default_run:
+ if v is False:
+ disabled.append(k)
+ else:
+ if v is True:
+ enabled.append(k)
# parse passed command line arguments
modules = parse_cmdline(MODULES_DIR, *sys.argv)
msg.DEBUG_FLAG = DEBUG_FLAG
@@ -539,7 +585,7 @@ def run():
", ONLY_MODULES=" + str(modules))
# run plugins
- charts = PythonCharts(modules, MODULES_DIR, CONFIG_DIR + "python.d/", disabled)
+ charts = PythonCharts(modules, MODULES_DIR, CONFIG_DIR + "python.d/", disabled, enabled, default_run)
charts.check()
charts.create()
charts.update()
diff --git a/plugins.d/tc-qos-helper.sh b/plugins.d/tc-qos-helper.sh
index e9253c8f2..074fece9a 100755
--- a/plugins.d/tc-qos-helper.sh
+++ b/plugins.d/tc-qos-helper.sh
@@ -12,12 +12,58 @@
export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
export LC_ALL=C
+
+# -----------------------------------------------------------------------------
+# find /var/run/fireqos
+
+# the default
+fireqos_run_dir="/var/run/fireqos"
+
+function realdir {
+ local r="$1"
+ local t=$(readlink "$r")
+
+ while [ "$t" ]
+ do
+ r=$(cd $(dirname "$r") && cd $(dirname "$t") && pwd -P)/$(basename "$t")
+ t=$(readlink "$r")
+ done
+
+ dirname "$r"
+}
+
+if [ ! -d "${fireqos_run_dir}" ]
+ then
+
+ # the fireqos executable - we will use it to find its config
+ fireqos="$(which fireqos 2>/dev/null || command -v fireqos 2>/dev/null)"
+
+ if [ ! -z "${fireqos}" ]
+ then
+
+ fireqos_exec_dir="$(realdir ${fireqos})"
+
+ if [ ! -z "${fireqos_exec_dir}" -a "${fireqos_exec_dir}" != "." -a -f "${fireqos_exec_dir}/install.config" ]
+ then
+
+ LOCALSTATEDIR=
+ source "${fireqos_exec_dir}/install.config"
+
+ if [ -d "${LOCALSTATEDIR}/run/fireqos" ]
+ then
+ fireqos_run_dir="${LOCALSTATEDIR}/run/fireqos"
+ fi
+ fi
+ fi
+fi
+
+# -----------------------------------------------------------------------------
+# logging functions
+
PROGRAM_FILE="$0"
PROGRAM_NAME="$(basename $0)"
PROGRAM_NAME="${PROGRAM_NAME/.plugin}"
-# -----------------------------------------------------------------------------
-
logdate() {
date "+%Y-%m-%d %H:%M:%S"
}
@@ -52,6 +98,7 @@ debug() {
[ $debug -eq 1 ] && log DEBUG "${@}"
}
+
# -----------------------------------------------------------------------------
plugins_dir="${NETDATA_PLUGINS_DIR}"
@@ -59,23 +106,52 @@ plugins_dir="${NETDATA_PLUGINS_DIR}"
config_dir=${NETDATA_CONFIG_DIR-/etc/netdata}
tc="$(which tc 2>/dev/null || command -v tc 2>/dev/null)"
-fireqos_run_dir="/var/run/fireqos"
+
+
+# -----------------------------------------------------------------------------
+# user configuration
+
+# time in seconds to refresh QoS class/qdisc names
qos_get_class_names_every=120
+
+# time in seconds to exit - netdata will restart the script
qos_exit_every=3600
+# what to use? classes or qdiscs?
+tc_show="qdisc" # can also be "class"
+
+
+# -----------------------------------------------------------------------------
# check if we have a valid number for interval
+
t=${1}
update_every=$((t))
[ $((update_every)) -lt 1 ] && update_every=${NETDATA_UPDATE_EVERY}
[ $((update_every)) -lt 1 ] && update_every=1
+
+# -----------------------------------------------------------------------------
# allow the user to override our defaults
+
if [ -f "${config_dir}/tc-qos-helper.conf" ]
then
source "${config_dir}/tc-qos-helper.conf"
fi
+case "${tc_show}" in
+ qdisc|class)
+ ;;
+
+ *)
+ error "tc_show variable can be either 'qdisc' or 'class' but is set to '${tc_show}'. Assuming it is 'qdisc'."
+ tc_show="qdisc"
+ ;;
+esac
+
+
+# -----------------------------------------------------------------------------
# default sleep function
+
LOOPSLEEPMS_LASTWORK=0
loopsleepms() {
sleep $1
@@ -85,6 +161,10 @@ loopsleepms() {
# with a high resolution timer function for precise looping.
. "${plugins_dir}/loopsleepms.sh.inc"
+
+# -----------------------------------------------------------------------------
+# final checks we can run
+
if [ -z "${tc}" -o ! -x "${tc}" ]
then
fatal "cannot find command 'tc' in this system."
@@ -93,11 +173,20 @@ fi
tc_devices=
fix_names=
+# -----------------------------------------------------------------------------
+
setclassname() {
- echo "SETCLASSNAME $3 $2"
+ if [ "${tc_show}" = "qdisc" ]
+ then
+ echo "SETCLASSNAME $4 $2"
+ else
+ echo "SETCLASSNAME $3 $2"
+ fi
}
show_tc_cls() {
+ [ "${tc_show}" = "qdisc" ] && return 1
+
local x="${1}"
if [ -f /etc/iproute2/tc_cls ]
@@ -110,7 +199,6 @@ show_tc_cls() {
done </etc/iproute2/tc_cls
return 0
fi
-
return 1
}
@@ -144,7 +232,7 @@ show_tc() {
echo "BEGIN ${x}"
# netdata can parse the output of tc
- ${tc} -s class show dev ${x}
+ ${tc} -s ${tc_show} show dev ${x}
# check FireQOS names for classes
if [ ! -z "${fix_names}" ]