summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:22:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:22:31 +0000
commit8d4f58e49b9dc7d3545651023a36729de773ad86 (patch)
tree7bc7be4a8e9e298daa1349348400aa2a653866f2 /contrib
parentInitial commit. (diff)
downloadnetdata-4aa3875af220e78bf296859b10b66a92e9bbed37.tar.xz
netdata-4aa3875af220e78bf296859b10b66a92e9bbed37.zip
Adding upstream version 1.12.0.upstream/1.12.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README.md60
-rw-r--r--contrib/debian/compat1
-rw-r--r--contrib/debian/control25
-rw-r--r--contrib/debian/control.wheezy25
-rw-r--r--contrib/debian/copyright10
-rw-r--r--contrib/debian/netdata.conf16
-rw-r--r--contrib/debian/netdata.default5
-rw-r--r--contrib/debian/netdata.docs1
-rwxr-xr-xcontrib/debian/netdata.init56
-rw-r--r--contrib/debian/netdata.install1
-rw-r--r--contrib/debian/netdata.lintian-overrides16
-rw-r--r--contrib/debian/netdata.postinst.in41
-rw-r--r--contrib/debian/netdata.postrm43
-rw-r--r--contrib/debian/netdata.service14
-rwxr-xr-xcontrib/debian/rules85
-rw-r--r--contrib/debian/source/format1
-rwxr-xr-xcontrib/rhel/build-netdata-rpm.sh47
-rw-r--r--contrib/sles11/README.md11
-rwxr-xr-xcontrib/sles11/alarm-notify-basic.bash3.sh755
-rw-r--r--contrib/sles11/netdata-alarms-bash3.patch10
-rw-r--r--contrib/sles11/netdata-automake-no-dist-xz.patch13
-rw-r--r--contrib/sles11/netdata-python-plugin-sles11.patch28
-rwxr-xr-xcontrib/sles11/netdata.init65
23 files changed, 1329 insertions, 0 deletions
diff --git a/contrib/README.md b/contrib/README.md
new file mode 100644
index 0000000..c5ce873
--- /dev/null
+++ b/contrib/README.md
@@ -0,0 +1,60 @@
+# netdata contrib
+
+## Building .deb packages
+
+The `contrib/debian/` directory contains basic rules to build a
+Debian package. It has been tested on Debian Jessie and Wheezy,
+but should work, possibly with minor changes, if you have other
+dpkg-based systems such as Ubuntu or Mint.
+
+To build netdata for a Debian Jessie system, the debian directory
+has to be available in the root of the netdata source. The easiest
+way to do this is with a symlink:
+
+ ~/netdata$ ln -s contrib/debian
+
+Then build the debian package:
+
+ ~/netdata$ dpkg-buildpackage -us -uc -rfakeroot
+
+This should give a package that can be installed in the parent
+directory, which you can install manually with dpkg.
+
+ ~/netdata$ ls ../*.deb
+ ../netdata_1.0.0_amd64.deb
+ ~/netdata$ sudo dpkg -i ../netdata_1.0.0_amd64.deb
+
+
+### Building for a Debian system without systemd
+
+The included packaging is designed for modern Debian systems that
+are based on systemd. To build non-systemd packages (for example,
+for Debian wheezy), you will need to make a couple of minor
+updates first.
+
+* edit `contrib/debian/rules` and adjust the `dh` rule near the
+ top to remove systemd (see comments in that file).
+
+* rename `contrib/debian/control.wheezy` to `contrib/debian/control`.
+
+* change `control.wheezy from contrib/Makefile* to control`.
+
+* uncomment `EXTRA_OPTS="-P /var/run/netdata.pid"` in
+ `contrib/debian/netdata.default`
+
+* edit `contrib/debian/netdata.init` and change `PIDFILE` to
+ `/var/run/netdata.pid`
+
+* remove `dpkg-statoverride --update --add --force root netdata 0775 /var/lib/netdata/registry` from
+ `contrib/debian/netdata.postinst.in`. If you are going to handle the unique id file differently.
+
+Then proceed as the main instructions above.
+
+### Reinstalling netdata
+
+The recommended way to upgrade netdata packages built from this
+source is to remove the current package from your system, then
+install the new package. Upgrading on wheezy is known to not
+work cleanly; Jessie may behave as expected.
+
+[![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%2Fcontrib%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
diff --git a/contrib/debian/compat b/contrib/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/contrib/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/contrib/debian/control b/contrib/debian/control
new file mode 100644
index 0000000..0f4f1bc
--- /dev/null
+++ b/contrib/debian/control
@@ -0,0 +1,25 @@
+Source: netdata
+Build-Depends: debhelper (>= 9),
+ dh-autoreconf,
+ dh-systemd (>= 1.5),
+ dpkg-dev (>= 1.13.19),
+ zlib1g-dev,
+ uuid-dev
+Section: net
+Priority: optional
+Maintainer: Costa Tsaousis <costa@tsaousis.gr>
+Standards-Version: 3.9.6
+Homepage: https://github.com/netdata/netdata/wiki
+
+Package: netdata
+Architecture: any
+Depends: adduser,
+ libcap2-bin (>= 1:2.0),
+ lsb-base (>= 3.1-23.2),
+ ${misc:Depends},
+ ${shlibs:Depends}
+Description: real-time charts for system monitoring
+ Netdata is a daemon that collects data in realtime (per second)
+ and presents a web site to view and analyze them. The presentation
+ is also real-time and full of interactive charts that precisely
+ render all collected values.
diff --git a/contrib/debian/control.wheezy b/contrib/debian/control.wheezy
new file mode 100644
index 0000000..cde1d56
--- /dev/null
+++ b/contrib/debian/control.wheezy
@@ -0,0 +1,25 @@
+Source: netdata
+Build-Depends: debhelper (>= 9),
+ dh-autoreconf,
+ pkg-config,
+ dpkg-dev (>= 1.13.19),
+ zlib1g-dev,
+ uuid-dev
+Section: net
+Priority: optional
+Maintainer: Costa Tsaousis <costa@tsaousis.gr>
+Standards-Version: 3.9.6
+Homepage: https://github.com/netdata/netdata/wiki
+
+Package: netdata
+Architecture: any
+Depends: adduser,
+ libcap2-bin (>= 1:2.0),
+ lsb-base (>= 3.1-23.2),
+ ${misc:Depends},
+ ${shlibs:Depends}
+Description: real-time charts for system monitoring
+ Netdata is a daemon that collects data in realtime (per second)
+ and presents a web site to view and analyze them. The presentation
+ is also real-time and full of interactive charts that precisely
+ render all collected values.
diff --git a/contrib/debian/copyright b/contrib/debian/copyright
new file mode 100644
index 0000000..085580e
--- /dev/null
+++ b/contrib/debian/copyright
@@ -0,0 +1,10 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: Netdata
+Upstream-Contact: Costa Tsaousis <costa@tsaousis.gr>
+Source: https://github.com/netdata/netdata
+
+Files: *
+Copyright: 2014-2016, Costa Tsaousis
+License: GPL-3+
+ On Debian systems, the complete text of the GNU General Public
+ License version 3 can be found in /usr/share/common-licenses/GPL-3.
diff --git a/contrib/debian/netdata.conf b/contrib/debian/netdata.conf
new file mode 100644
index 0000000..a963d80
--- /dev/null
+++ b/contrib/debian/netdata.conf
@@ -0,0 +1,16 @@
+# NetData Configuration
+
+# The current full configuration can be retrieved from the running
+# server at the URL
+#
+# http://localhost:19999/netdata.conf
+#
+# for example:
+#
+# wget -O /etc/netdata/netdata.conf http://localhost:19999/netdata.conf
+#
+
+[global]
+ run as user = netdata
+ web files owner = root
+ web files group = netdata
diff --git a/contrib/debian/netdata.default b/contrib/debian/netdata.default
new file mode 100644
index 0000000..9e7f8ae
--- /dev/null
+++ b/contrib/debian/netdata.default
@@ -0,0 +1,5 @@
+# Extra arguments to pass to netdata
+#
+#EXTRA_OPTS=""
+#uncomment following line if you are building a wheezy-package
+#EXTRA_OPTS="-P /var/run/netdata.pid"
diff --git a/contrib/debian/netdata.docs b/contrib/debian/netdata.docs
new file mode 100644
index 0000000..1b763b1
--- /dev/null
+++ b/contrib/debian/netdata.docs
@@ -0,0 +1 @@
+CHANGELOG.md
diff --git a/contrib/debian/netdata.init b/contrib/debian/netdata.init
new file mode 100755
index 0000000..c1b2b74
--- /dev/null
+++ b/contrib/debian/netdata.init
@@ -0,0 +1,56 @@
+#!/bin/sh
+# Start/stop the netdata daemon.
+#
+### BEGIN INIT INFO
+# Provides: netdata
+# Required-Start: $remote_fs
+# Required-Stop: $remote_fs
+# Should-Start: $network
+# Should-Stop: $network
+# Default-Start: 2 3 4 5
+# Default-Stop:
+# Short-Description: Real-time charts for system monitoring
+# Description: Netdata is a daemon that collects data in realtime (per second)
+# and presents a web site to view and analyze them. The presentation
+# is also real-time and full of interactive charts that precisely
+# render all collected values.
+### END INIT INFO
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+DESC="netdata daemon"
+NAME=netdata
+DAEMON=/usr/sbin/netdata
+PIDFILE=/var/run/netdata/netdata.pid
+SCRIPTNAME=/etc/init.d/"$NAME"
+
+test -f $DAEMON || exit 0
+
+. /lib/lsb/init-functions
+
+[ -r /etc/default/netdata ] && . /etc/default/netdata
+
+case "$1" in
+start) log_daemon_msg "Starting real-time system monitoring" "netdata"
+ start_daemon -p $PIDFILE $DAEMON $EXTRA_OPTS
+ log_end_msg $?
+ ;;
+stop) log_daemon_msg "Stopping real-time system monitoring" "netdata"
+ killproc -p $PIDFILE $DAEMON
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && [ -e "$PIDFILE" ] && rm -f $PIDFILE
+ log_end_msg $RETVAL
+ # wait for plugins to exit
+ sleep 1
+ ;;
+restart|force-reload) log_daemon_msg "Restarting real-time system monitoring" "netdata"
+ $0 stop
+ $0 start
+ ;;
+status)
+ status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $?
+ ;;
+*) log_action_msg "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}"
+ exit 2
+ ;;
+esac
+exit 0
diff --git a/contrib/debian/netdata.install b/contrib/debian/netdata.install
new file mode 100644
index 0000000..45d42b6
--- /dev/null
+++ b/contrib/debian/netdata.install
@@ -0,0 +1 @@
+debian/netdata.conf /etc/netdata/
diff --git a/contrib/debian/netdata.lintian-overrides b/contrib/debian/netdata.lintian-overrides
new file mode 100644
index 0000000..45b2d86
--- /dev/null
+++ b/contrib/debian/netdata.lintian-overrides
@@ -0,0 +1,16 @@
+
+# See Debian policy 10.9. apps.plugin has extra capabilities, so don't let
+# normal users run it.
+netdata: non-standard-executable-perm usr/lib/*/netdata/plugins.d/apps.plugin 0754 != 0755
+
+
+# FontAwesome is at least in the fonts-font-awesome package, but this is
+# not available in wheezy. glyphicons-halflings-regular isn't currently in
+# a Debian package. Therefore don't complain about shipping them with netdata
+# for the time being.
+netdata: duplicate-font-file usr/share/netdata/fonts/*
+netdata: font-in-non-font-package usr/share/netdata/fonts/*
+
+# Files here are marked as conffiles so that local updates to the html files
+# isn't clobbered on upgrade.
+netdata: non-etc-file-marked-as-conffile var/lib/netdata/www/*
diff --git a/contrib/debian/netdata.postinst.in b/contrib/debian/netdata.postinst.in
new file mode 100644
index 0000000..29615f5
--- /dev/null
+++ b/contrib/debian/netdata.postinst.in
@@ -0,0 +1,41 @@
+#! /bin/sh
+
+set -e
+
+case "$1" in
+ configure)
+ if [ -z "$2" ]; then
+ if ! getent group netdata >/dev/null; then
+ addgroup --quiet --system netdata
+ fi
+
+ if ! getent passwd netdata >/dev/null; then
+ adduser --quiet --system --ingroup netdata --home /var/lib/netdata --no-create-home netdata
+ fi
+
+ if ! dpkg-statoverride --list /var/lib/netdata >/dev/null 2>&1; then
+ dpkg-statoverride --update --add netdata netdata 0755 /var/lib/netdata
+ fi
+
+ if ! dpkg-statoverride --list /var/lib/netdata/www >/dev/null 2>&1; then
+ dpkg-statoverride --update --add root netdata 0755 /var/lib/netdata/www
+ fi
+
+ if ! dpkg-statoverride --list /var/cache/netdata >/dev/null 2>&1; then
+ dpkg-statoverride --update --add netdata netdata 0755 /var/cache/netdata
+ fi
+
+ fi
+
+ dpkg-statoverride --update --add --force root netdata 0775 /var/lib/netdata/registry
+ chown -R root:netdata /usr/share/netdata/*
+ chown -R root:netdata /usr/lib/@DEB_HOST_MULTIARCH@/netdata/plugins.d
+ setcap cap_dac_read_search,cap_sys_ptrace+ep /usr/lib/@DEB_HOST_MULTIARCH@/netdata/plugins.d/apps.plugin
+
+#PERMS#
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/contrib/debian/netdata.postrm b/contrib/debian/netdata.postrm
new file mode 100644
index 0000000..4ab4eea
--- /dev/null
+++ b/contrib/debian/netdata.postrm
@@ -0,0 +1,43 @@
+#! /bin/sh
+
+set -e
+
+case "$1" in
+ remove)
+ ;;
+
+ purge)
+ if dpkg-statoverride --list | grep -qw /var/cache/netdata; then
+ dpkg-statoverride --remove /var/cache/netdata
+ fi
+
+ if dpkg-statoverride --list | grep -qw /var/lib/netdata/www; then
+ dpkg-statoverride --remove /var/lib/netdata/www
+ fi
+
+ if dpkg-statoverride --list | grep -qw /var/lib/netdata; then
+ dpkg-statoverride --remove /var/lib/netdata
+ fi
+
+ if getent passwd netdata >/dev/null; then
+ if [ -x /usr/sbin/deluser ]; then
+ deluser --quiet --system netdata || echo "Unable to remove netdata user"
+ fi
+ fi
+
+ if getent group netdata >/dev/null; then
+ if [ -x /usr/sbin/delgroup ]; then
+ delgroup --quiet --system netdata || echo "Unable to remove netdata group"
+ fi
+ fi
+
+ ;;
+
+ *)
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
+
diff --git a/contrib/debian/netdata.service b/contrib/debian/netdata.service
new file mode 100644
index 0000000..e5d3a38
--- /dev/null
+++ b/contrib/debian/netdata.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=netdata real-time system monitoring
+After=network.target
+
+[Service]
+Type=simple
+EnvironmentFile=-/etc/default/netdata
+ExecStart=/usr/sbin/netdata -D $EXTRA_OPTS
+TimeoutStopSec=30
+Restart=always
+RestartSec=5
+
+[Install]
+WantedBy=multi-user.target
diff --git a/contrib/debian/rules b/contrib/debian/rules
new file mode 100755
index 0000000..c193239
--- /dev/null
+++ b/contrib/debian/rules
@@ -0,0 +1,85 @@
+#!/usr/bin/make -f
+
+# Find the arch we are building for, as this determines
+# the location of plugins in /usr/lib
+DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
+TOP = $(CURDIR)/debian/netdata
+
+%:
+ # For jessie and beyond
+ #
+ dh $@ --with autoreconf,systemd
+
+ # For wheezy or other non-systemd distributions use the following. You
+ # should also see contrib/README.md which gives details of updates to
+ # make to debian/control.
+ #
+ #dh $@ --with autoreconf
+
+override_dh_auto_configure:
+ dh_auto_configure -- --with-math --with-webdir=/var/lib/netdata/www
+
+debian/%.postinst: debian/%.postinst.in
+ sed 's/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/g' $< > $@
+
+override_dh_install: debian/netdata.postinst
+ dh_install
+
+ # Remove unneeded .keep files
+ #
+ find "$(TOP)" -name .keep -exec rm '{}' ';'
+
+ # Move files that local user shouldn't be editing to /usr/share/netdata
+ #
+ mkdir -p "$(TOP)/usr/share/netdata"
+ for D in $$(find "$(TOP)/var/lib/netdata/www/" -maxdepth 1 -type d -printf '%f '); do \
+ echo Relocating $$D; \
+ mv "$(TOP)/var/lib/netdata/www/$$D" "$(TOP)/usr/share/netdata/$$D"; \
+ ln -s "/usr/share/netdata/$$D" "$(TOP)/var/lib/netdata/www/$$D"; \
+ done
+
+ # Update postinst to set correct group for www files on installation.
+ # Should probably be dpkg-statoverride really, but that gets *really*
+ # messy. We also set all web files in /var as conffiles so an upgrade
+ # doesn't splat them.
+ #
+ for D in $$(find "$(TOP)/var/lib/netdata/www/" -maxdepth 1 -type f -printf '%f '); do \
+ echo Updating postinst for $$D; \
+ sed -i "s/^#PERMS#/chgrp netdata \/var\/lib\/netdata\/www\/$$D\n#PERMS#/g" \
+ $(CURDIR)/debian/netdata.postinst; \
+ echo "/var/lib/netdata/www/$$D" >> $(CURDIR)/debian/netdata.conffiles; \
+ done
+ sed -i "/^#PERMS#/d" $(CURDIR)/debian/netdata.postinst
+
+override_dh_installdocs:
+ dh_installdocs
+
+ find . \
+ -name README.md \
+ -not -path './.travis/*' \
+ -not -path './debian/*' \
+ -exec cp \
+ --parents \
+ --target $(TOP)/usr/share/doc/netdata/ \
+ {} \;
+
+override_dh_fixperms:
+ dh_fixperms
+
+ # apps.plugin should only be runnable by the netdata user. It will be
+ # given extra capabilities in the postinst script.
+ #
+ chmod 0754 $(TOP)/usr/lib/$(DEB_HOST_MULTIARCH)/netdata/plugins.d/apps.plugin
+
+override_dh_installlogrotate:
+ cp system/netdata.logrotate debian/netdata.logrotate
+ dh_installlogrotate
+
+override_dh_clean:
+ dh_clean
+
+ # Tidy up copied/generated files
+ #
+ -[ -r $(CURDIR)/debian/netdata.logrotate ] && rm $(CURDIR)/debian/netdata.logrotate
+ -[ -r $(CURDIR)/debian/netdata.postinst ] && rm $(CURDIR)/debian/netdata.postinst
+ -[ -r $(CURDIR)/debian/netdata.conffiles ] && rm $(CURDIR)/debian/netdata.conffiles
diff --git a/contrib/debian/source/format b/contrib/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/contrib/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/contrib/rhel/build-netdata-rpm.sh b/contrib/rhel/build-netdata-rpm.sh
new file mode 100755
index 0000000..df33d80
--- /dev/null
+++ b/contrib/rhel/build-netdata-rpm.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+# docker run -it --rm centos:6.9 /bin/sh
+# yum -y install rpm-build redhat-rpm-config yum-utils autoconf automake curl gcc git libmnl-devel libuuid-devel make pkgconfig zlib-devel
+
+cd "$(dirname "$0")/../../" || exit 1
+# shellcheck disable=SC1091
+source "packaging/installer/functions.sh" || exit 1
+
+set -e
+
+run autoreconf -ivf
+run ./configure --enable-maintainer-mode
+run make dist
+
+version=$(grep PACKAGE_VERSION < config.h | cut -d '"' -f 2)
+if [ -z "${version}" ]
+then
+ echo >&2 "Cannot find netdata version."
+ exit 1
+fi
+
+tgz="netdata-${version}.tar.gz"
+if [ ! -f "${tgz}" ]
+then
+ echo >&2 "Cannot find the generated tar.gz file '${tgz}'"
+ exit 1
+fi
+
+srpm=$(run rpmbuild -ts "${tgz}" | cut -d ' ' -f 2)
+if [ -z "${srpm}" ] || [ ! -f "${srpm}" ]
+then
+ echo >&2 "Cannot find the generated SRPM file '${srpm}'"
+ exit 1
+fi
+
+#if which yum-builddep 2>/dev/null
+#then
+# run yum-builddep "${srpm}"
+#elif which dnf 2>/dev/null
+#then
+# [ "${UID}" = 0 ] && run dnf builddep "${srpm}"
+#fi
+
+run rpmbuild --rebuild "${srpm}"
+
+echo >&2 "All done!"
diff --git a/contrib/sles11/README.md b/contrib/sles11/README.md
new file mode 100644
index 0000000..d052b94
--- /dev/null
+++ b/contrib/sles11/README.md
@@ -0,0 +1,11 @@
+# spec to build netdata RPM for sles 11
+
+Based on [opensuse rpm spec](https://build.opensuse.org/package/show/network/netdata) with some
+changes and additions for sles 11 backport, namely:
+- init.d script
+- run-time dependency on python ordereddict backport
+- patch for netdata python.d plugin to work with older python
+- crude hack of notification script to work with bash 3 (email and syslog only, one destination,
+ see comments at the top)
+
+[![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%2Fcontrib%2Fsles11%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
diff --git a/contrib/sles11/alarm-notify-basic.bash3.sh b/contrib/sles11/alarm-notify-basic.bash3.sh
new file mode 100755
index 0000000..df38292
--- /dev/null
+++ b/contrib/sles11/alarm-notify-basic.bash3.sh
@@ -0,0 +1,755 @@
+#!/usr/bin/env bash
+
+# basic version of netdata notifier to work with bash3
+# only mail and syslog destinations are supported, one recipient each
+# - email: DEFAULT_RECIPIENT_EMAIL, "root" by default
+# - syslog: "netdata" with local6 facility; disabled by default
+# - also: setting recipient to "disabled" or "silent" stops notifications for this alert
+
+# in /etc/netdata/health_alarm_notify.conf set something like
+# EMAIL_SENDER="netdata@gesdev-vm.m0.maxidom.ru"
+# SEND_EMAIL="YES"
+# DEFAULT_RECIPIENT_EMAIL="root"
+# SEND_SYSLOG="YES"
+# SYSLOG_FACILITY="local6"
+# DEFAULT_RECIPIENT_SYSLOG="netdata"
+
+# netdata
+# real-time performance and health monitoring, done right!
+# (C) 2017 Costa Tsaousis <costa@tsaousis.gr>
+# GPL v3+
+#
+# Script to send alarm notifications for netdata
+#
+# Supported notification methods:
+# - emails by @ktsaou
+# - syslog messages by @Ferroin
+# - all the rest is pruned :)
+
+# -----------------------------------------------------------------------------
+# testing notifications
+
+if [ \( "${1}" = "test" -o "${2}" = "test" \) -a "${#}" -le 2 ]
+then
+ if [ "${2}" = "test" ]
+ then
+ recipient="${1}"
+ else
+ recipient="${2}"
+ fi
+
+ [ -z "${recipient}" ] && recipient="sysadmin"
+
+ id=1
+ last="CLEAR"
+ test_res=0
+ for x in "WARNING" "CRITICAL" "CLEAR"
+ do
+ 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" "new value" "old value"
+ if [ $? -ne 0 ]
+ then
+ echo >&2 "# FAILED"
+ test_res=1
+ else
+ echo >&2 "# OK"
+ fi
+
+ last="${x}"
+ id=$((id + 1))
+ done
+
+ exit $test_res
+fi
+
+export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
+export LC_ALL=C
+
+# -----------------------------------------------------------------------------
+
+PROGRAM_NAME="$(basename "${0}")"
+
+logdate() {
+ date "+%Y-%m-%d %H:%M:%S"
+}
+
+log() {
+ local status="${1}"
+ shift
+
+ echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}"
+
+}
+
+warning() {
+ log WARNING "${@}"
+}
+
+error() {
+ log ERROR "${@}"
+}
+
+info() {
+ log INFO "${@}"
+}
+
+fatal() {
+ log FATAL "${@}"
+ exit 1
+}
+
+debug=${NETDATA_ALARM_NOTIFY_DEBUG-0}
+debug() {
+ [ "${debug}" = "1" ] && log DEBUG "${@}"
+}
+
+docurl() {
+ if [ -z "${curl}" ]
+ then
+ error "\${curl} is unset."
+ return 1
+ fi
+
+ if [ "${debug}" = "1" ]
+ then
+ echo >&2 "--- BEGIN curl command ---"
+ printf >&2 "%q " ${curl} "${@}"
+ echo >&2
+ echo >&2 "--- END curl command ---"
+
+ local out=$(mktemp /tmp/netdata-health-alarm-notify-XXXXXXXX)
+ local code=$(${curl} ${curl_options} --write-out %{http_code} --output "${out}" --silent --show-error "${@}")
+ local ret=$?
+ echo >&2 "--- BEGIN received response ---"
+ cat >&2 "${out}"
+ echo >&2
+ echo >&2 "--- END received response ---"
+ echo >&2 "RECEIVED HTTP RESPONSE CODE: ${code}"
+ rm "${out}"
+ echo "${code}"
+ return ${ret}
+ fi
+
+ ${curl} ${curl_options} --write-out %{http_code} --output /dev/null --silent --show-error "${@}"
+ return $?
+}
+
+# -----------------------------------------------------------------------------
+# 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)
+[ $(( ${BASH_VERSINFO[0]} )) -lt 3 ] && \
+ fatal "BASH version 3 or later is required (this is ${BASH_VERSION})."
+
+# -----------------------------------------------------------------------------
+# defaults to allow running this script by hand
+
+[ -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"
+
+# -----------------------------------------------------------------------------
+# parse command line parameters
+
+roles="${1}" # the roles that should be notified for this event
+host="${2}" # the host generated this event
+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 id
+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, 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
+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
+
+this_host=$(hostname -s 2>/dev/null)
+[ -z "${host}" ] && host="${this_host}"
+
+# -----------------------------------------------------------------------------
+# screen statuses we don't need to send a notification
+
+# 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} 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} of '${host}.${chart}.${name}' (last status was ${old_status})"
+ exit 1
+fi
+
+# -----------------------------------------------------------------------------
+# load configuration
+
+# By default fetch images from the global public registry.
+# This is required by default, since all notification methods need to download
+# images via the Internet, and private registries might not be reachable.
+# This can be overwritten at the configuration file.
+images_base_url="https://registry.my-netdata.io"
+
+# curl options to use
+curl_options=
+
+# needed commands
+# if empty they will be searched in the system path
+curl=
+sendmail=
+
+# enable / disable features
+SEND_EMAIL="YES"
+SEND_SYSLOG="YES"
+
+# syslog configs
+SYSLOG_FACILITY="local6"
+
+# email configs
+EMAIL_SENDER=
+DEFAULT_RECIPIENT_EMAIL="root"
+EMAIL_CHARSET=$(locale charmap 2>/dev/null)
+
+# load the user configuration
+# this will overwrite the variables above
+if [ -f "${NETDATA_CONFIG_DIR}/health_alarm_notify.conf" ]
+ then
+ source "${NETDATA_CONFIG_DIR}/health_alarm_notify.conf"
+else
+ error "Cannot find file ${NETDATA_CONFIG_DIR}/health_alarm_notify.conf. Using internal defaults."
+fi
+
+# If we didn't autodetect the character set for e-mail and it wasn't
+# set by the user, we need to set it to a reasonable default. UTF-8
+# should be correct for almost all modern UNIX systems.
+if [ -z ${EMAIL_CHARSET} ]
+ then
+ EMAIL_CHARSET="UTF-8"
+fi
+
+# disable if role = silent or disabled
+if [[ "${role}" = "silent" || "${role}" = "disabled" ]]; then
+ SEND_EMAIL="NO"
+ SEND_SYSLOG="NO"
+fi
+
+if [[ "SEND_EMAIL" != "NO" ]]; then
+ to_email=$DEFAULT_RECIPIENT_EMAIL
+else
+ to_email=''
+fi
+
+if [[ "SEND_SYSLOG" != "NO" ]]; then
+ to_syslog=$DEFAULT_RECIPIENT_SYSLOG
+else
+ to_syslog=''
+fi
+
+# if we need sendmail, check for the sendmail command
+if [ "${SEND_EMAIL}" = "YES" -a -z "${sendmail}" ]
+ then
+ sendmail="$(which sendmail 2>/dev/null || command -v sendmail 2>/dev/null)"
+ if [ -z "${sendmail}" ]
+ then
+ debug "Cannot find sendmail command in the system path. Disabling email notifications."
+ SEND_EMAIL="NO"
+ fi
+fi
+
+# if we need logger, check for the logger command
+if [ "${SEND_SYSLOG}" = "YES" -a -z "${logger}" ]
+ then
+ logger="$(which logger 2>/dev/null || command -v logger 2>/dev/null)"
+ if [ -z "${logger}" ]
+ then
+ debug "Cannot find logger command in the system path. Disabling syslog notifications."
+ SEND_SYSLOG="NO"
+ fi
+fi
+
+# check that we have at least a method enabled
+if [ "${SEND_EMAIL}" != "YES" \
+ -a "${SEND_SYSLOG}" != "YES" \
+ ]
+ then
+ fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'."
+fi
+
+# -----------------------------------------------------------------------------
+# get the date the alarm happened
+
+date=$(date --date=@${when} "${DATE_FORMAT}" 2>/dev/null)
+[ -z "${date}" ] && date=$(date "${DATE_FORMAT}" 2>/dev/null)
+[ -z "${date}" ] && date=$(date --date=@${when} 2>/dev/null)
+[ -z "${date}" ] && date=$(date 2>/dev/null)
+
+# -----------------------------------------------------------------------------
+# function to URL encode a string
+
+urlencode() {
+ local string="${1}" strlen encoded pos c o
+
+ strlen=${#string}
+ for (( pos=0 ; pos<strlen ; pos++ ))
+ do
+ c=${string:${pos}:1}
+ case "${c}" in
+ [-_.~a-zA-Z0-9])
+ o="${c}"
+ ;;
+
+ *)
+ printf -v o '%%%02x' "'${c}"
+ ;;
+ esac
+ encoded+="${o}"
+ done
+
+ REPLY="${encoded}"
+ echo "${REPLY}"
+}
+
+# -----------------------------------------------------------------------------
+# function to 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" ret
+ 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
+ ret="${d} ${ds} and ${h} ${hs}"
+ else
+ ret="${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
+ ret="${h} ${hs} and ${m} ${ms}"
+ else
+ ret="${h} ${hs}"
+ fi
+ elif [ ${m} -gt 0 ]
+ then
+ [ ${m} -gt 1 ] && ms="minutes"
+ [ ${s} -gt 1 ] && ss="seconds"
+ if [ ${s} -gt 0 ]
+ then
+ ret="${m} ${ms} and ${s} ${ss}"
+ else
+ ret="${m} ${ms}"
+ fi
+ else
+ [ ${s} -gt 1 ] && ss="seconds"
+ ret="${s} ${ss}"
+ fi
+
+ REPLY="${ret}"
+ echo "${REPLY}"
+}
+
+# -----------------------------------------------------------------------------
+# email sender
+
+send_email() {
+ local ret= opts=
+ if [[ "${SEND_EMAIL}" == "YES" ]]
+ then
+
+ if [[ ! -z "${EMAIL_SENDER}" ]]
+ then
+ if [[ "${EMAIL_SENDER}" =~ \".*\"\ \<.*\> ]]
+ then
+ # the name includes single quotes
+ opts=" -f $(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1) -F $(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)"
+ elif [[ "${EMAIL_SENDER}" =~ \'.*\'\ \<.*\> ]]
+ then
+ # the name includes double quotes
+ opts=" -f $(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1) -F $(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)"
+ elif [[ "${EMAIL_SENDER}" =~ .*\ \<.*\> ]]
+ then
+ # the name does not have any quotes
+ opts=" -f $(echo "${EMAIL_SENDER}" | cut -d '<' -f 2 | cut -d '>' -f 1) -F '$(echo "${EMAIL_SENDER}" | cut -d '<' -f 1)'"
+ else
+ # no name at all
+ opts=" -f ${EMAIL_SENDER}"
+ fi
+ fi
+
+ if [[ "${debug}" = "1" ]]
+ then
+ echo >&2 "--- BEGIN sendmail command ---"
+ printf >&2 "%q " "${sendmail}" -t ${opts}
+ echo >&2
+ echo >&2 "--- END sendmail command ---"
+ fi
+
+ "${sendmail}" -t ${opts}
+ ret=$?
+
+ if [ ${ret} -eq 0 ]
+ then
+ info "sent email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}'"
+ return 0
+ else
+ error "failed to send email notification for: ${host} ${chart}.${name} is ${status} to '${to_email}' with error code ${ret}."
+ return 1
+ fi
+ fi
+
+ return 1
+}
+
+# -----------------------------------------------------------------------------
+# syslog sender
+
+send_syslog() {
+ local facility=${SYSLOG_FACILITY:-"local6"} level='info' targets="${1}"
+ local priority='' message='' host='' port='' prefix=''
+ local temp1='' temp2=''
+
+ [[ "${SEND_SYSLOG}" == "YES" ]] || return 1
+
+ if [[ "${status}" == "CRITICAL" ]] ; then
+ level='crit'
+ elif [[ "${status}" == "WARNING" ]] ; then
+ level='warning'
+ fi
+
+ for target in ${targets} ; do
+ priority="${facility}.${level}"
+ message=''
+ host=''
+ port=''
+ prefix=''
+ temp1=''
+ temp2=''
+
+ prefix=$(echo ${target} | cut -d '/' -f 2)
+ temp1=$(echo ${target} | cut -d '/' -f 1)
+
+ if [[ ${prefix} != ${temp1} ]] ; then
+ if (echo ${temp1} | grep -q '@' ) ; then
+ temp2=$(echo ${temp1} | cut -d '@' -f 1)
+ host=$(echo ${temp1} | cut -d '@' -f 2)
+
+ if [ ${temp2} != ${host} ] ; then
+ priority=${temp2}
+ fi
+
+ port=$(echo ${host} | rev | cut -d ':' -f 1 | rev)
+
+ if ( echo ${host} | grep -E -q '\[.*\]' ) ; then
+ if ( echo ${port} | grep -q ']' ) ; then
+ port=''
+ else
+ host=$(echo ${host} | rev | cut -d ':' -f 2- | rev)
+ fi
+ else
+ if [ ${port} = ${host} ] ; then
+ port=''
+ else
+ host=$(echo ${host} | cut -d ':' -f 1)
+ fi
+ fi
+ else
+ priority=${temp1}
+ fi
+ fi
+
+ # message="${prefix} ${status} on ${host} at ${date}: ${chart} ${value_string}"
+
+ message="${prefix} ${status}: ${chart} ${value_string}"
+
+ if [ ${host} ] ; then
+ logger_options="${logger_options} -n ${host}"
+ if [ ${port} ] ; then
+ logger_options="${logger_options} -P ${port}"
+ fi
+ fi
+
+ ${logger} -p ${priority} ${logger_options} "${message}"
+ done
+
+ return $?
+}
+
+
+# -----------------------------------------------------------------------------
+# prepare the content of the notification
+
+# the url to send the user on click
+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}"
+goto_url="${NETDATA_REGISTRY_URL}/goto-host-from-alarm.html?host=${url_host}&chart=${url_chart}&family=${url_family}&alarm=${url_name}&alarm_unique_id=${unique_id}&alarm_id=${alarm_id}&alarm_event_id=${event_id}"
+
+# the severity of the alarm
+severity="${status}"
+
+# the time the alarm was raised
+duration4human ${duration} >/dev/null; duration_txt="${REPLY}"
+duration4human ${non_clear_duration} >/dev/null; non_clear_duration_txt="${REPLY}"
+raised_for="(was ${old_status} for ${duration_txt})"
+
+# the key status message
+status_message="status unknown"
+
+# the color of the alarm
+color="grey"
+
+# the alarm value
+alarm="${name//_/ } = ${value_string}"
+
+# the image of the alarm
+image="${images_base_url}/images/seo-performance-128.png"
+
+# prepare the title based on status
+case "${status}" in
+ CRITICAL)
+ image="${images_base_url}/images/alert-128-red.png"
+ status_message="is critical"
+ color="#ca414b"
+ ;;
+
+ WARNING)
+ image="${images_base_url}/images/alert-128-orange.png"
+ status_message="needs attention"
+ color="#ffc107"
+ ;;
+
+ CLEAR)
+ image="${images_base_url}/images/check-mark-2-128-green.png"
+ status_message="recovered"
+ color="#77ca6d"
+ ;;
+esac
+
+if [ "${status}" = "CLEAR" ]
+then
+ severity="Recovered from ${old_status}"
+ if [ ${non_clear_duration} -gt ${duration} ]
+ then
+ raised_for="(alarm was raised for ${non_clear_duration_txt})"
+ fi
+
+ # don't show the value when the status is CLEAR
+ # for certain alarms, this value might not have any meaning
+ alarm="${name//_/ } ${raised_for}"
+
+elif [ "${old_status}" = "WARNING" -a "${status}" = "CRITICAL" ]
+then
+ severity="Escalated to ${status}"
+ if [ ${non_clear_duration} -gt ${duration} ]
+ then
+ raised_for="(alarm is raised for ${non_clear_duration_txt})"
+ fi
+
+elif [ "${old_status}" = "CRITICAL" -a "${status}" = "WARNING" ]
+then
+ severity="Demoted to ${status}"
+ if [ ${non_clear_duration} -gt ${duration} ]
+ then
+ raised_for="(alarm is raised for ${non_clear_duration_txt})"
+ fi
+
+else
+ raised_for=
+fi
+
+# prepare HTML versions of elements
+info_html=
+[ ! -z "${info}" ] && info_html=" <small><br/>${info}</small>"
+
+raised_for_html=
+[ ! -z "${raised_for}" ] && raised_for_html="<br/><small>${raised_for}</small>"
+
+
+# -----------------------------------------------------------------------------
+# send the syslog message
+
+send_syslog ${to_syslog}
+
+SENT_SYSLOG=$?
+
+# -----------------------------------------------------------------------------
+# 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; encoding=${EMAIL_CHARSET}
+Content-Disposition: inline
+Content-Transfer-Encoding: 8bit
+
+${host} ${status_message}
+
+${alarm} ${info}
+${raised_for}
+
+Chart : ${chart}
+Family : ${family}
+Severity: ${severity}
+URL : ${goto_url}
+Source : ${src}
+Date : ${date}
+Value : ${value_string}
+Notification generated on ${this_host}
+
+--multipart-boundary
+Content-Type: text/html; encoding=${EMAIL_CHARSET}
+Content-Disposition: inline
+Content-Transfer-Encoding: 8bit
+
+<!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, 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>
+ <td style="vertical-align: top;" valign="top"></td>
+ <td width="700" style="vertical-align: top; display: block !important; max-width: 700px !important; clear: both !important; margin: 0 auto; padding: 0;" valign="top">
+ <div style="max-width: 700px; display: block; margin: 0 auto; padding: 20px;">
+ <table width="100%" cellpadding="0" cellspacing="0" style="background: #fff; border: 1px solid #e9e9e9;">
+ <tbody>
+ <tr>
+ <td bgcolor="#eee" style="padding: 5px 20px 5px 20px; background-color: #eee;">
+ <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, Arial, sans-serif; font-weight: 400; margin: 0;">${host} ${status_message}</h1>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" valign="top">
+ <div style="margin: 0; padding: 20px; max-width: 700px;">
+ <table width="100%" cellpadding="0" cellspacing="0" style="max-width:700px">
+ <tbody>
+ <tr>
+ <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>
+ <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>${value_string}</span>
+ <span style="display: block; color: #666666; font-size: 12px; font-weight: 300; line-height: 1; text-transform: uppercase;">Value</span>
+ </td>
+ </tr>
+ <tr style="margin: 0; padding: 0;">
+ <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, 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, 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, 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, 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, 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, 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>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</body>
+</html>
+--multipart-boundary--
+EOF
+
+SENT_EMAIL=$?
+
+# -----------------------------------------------------------------------------
+# let netdata know
+
+if [ ${SENT_EMAIL} -eq 0 \
+ -o ${SENT_SYSLOG} -eq 0 \
+ ]
+ then
+ # we did send something
+ exit 0
+fi
+
+# we did not send anything
+exit 1
diff --git a/contrib/sles11/netdata-alarms-bash3.patch b/contrib/sles11/netdata-alarms-bash3.patch
new file mode 100644
index 0000000..142659b
--- /dev/null
+++ b/contrib/sles11/netdata-alarms-bash3.patch
@@ -0,0 +1,10 @@
+--- system/netdata.conf.orig 2018-05-10 19:44:49.000000000 +0300
++++ system/netdata.conf 2018-05-10 19:45:14.000000000 +0300
+@@ -22,3 +22,7 @@
+ [web]
+ web files owner = root
+ web files group = netdata
++
++[health]
++ # script for sles 11, mail notifications only
++ script to execute on alarm = /usr/lib64/netdata/plugins.d/alarm-notify.bash3.sh
diff --git a/contrib/sles11/netdata-automake-no-dist-xz.patch b/contrib/sles11/netdata-automake-no-dist-xz.patch
new file mode 100644
index 0000000..d373efa
--- /dev/null
+++ b/contrib/sles11/netdata-automake-no-dist-xz.patch
@@ -0,0 +1,13 @@
+diff -u netdata-1.6.0.orig/Makefile.am netdata-1.6.0/Makefile.am
+--- netdata-1.6.0.orig/Makefile.am 2017-03-20 19:32:47.000000000 +0100
++++ netdata-1.6.0/Makefile.am 2017-06-25 23:46:14.403426661 +0200
+@@ -1,7 +1,7 @@
+ #
+ # Copyright (C) 2015 Alon Bar-Lev <alon.barlev@gmail.com>
+ #
+-AUTOMAKE_OPTIONS=foreign dist-bzip2 dist-xz 1.10
++AUTOMAKE_OPTIONS=foreign dist-bzip2 1.10
+ ACLOCAL_AMFLAGS = -I m4
+
+ MAINTAINERCLEANFILES= \
+
diff --git a/contrib/sles11/netdata-python-plugin-sles11.patch b/contrib/sles11/netdata-python-plugin-sles11.patch
new file mode 100644
index 0000000..d2e8f6b
--- /dev/null
+++ b/contrib/sles11/netdata-python-plugin-sles11.patch
@@ -0,0 +1,28 @@
+diff -u netdata-1.10.0.orig/plugins.d/python.d.plugin netdata-1.10.0/plugins.d/python.d.plugin
+--- netdata-1.10.0.orig/plugins.d/python.d.plugin 2018-05-08 20:01:40.000000000 +0300
++++ netdata-1.10.0/plugins.d/python.d.plugin 2018-05-08 20:06:57.000000000 +0300
+@@ -15,10 +15,8 @@
+ from sys import version_info, argv
+ from time import sleep
+
+-try:
+- from time import monotonic as time
+-except ImportError:
+- from time import time
++# from time import monotonic as time
++from time import time
+
+ PY_VERSION = version_info[:2]
+ PLUGIN_CONFIG_DIR = os.getenv('NETDATA_CONFIG_DIR', os.path.dirname(__file__) + '/../../../../etc/netdata') + '/'
+@@ -32,10 +30,7 @@
+ from bases.loggers import PythonDLogger
+ from bases.collection import setdefault_values, run_and_exit
+
+-try:
+- from collections import OrderedDict
+-except ImportError:
+- from third_party.ordereddict import OrderedDict
++from ordereddict import OrderedDict
+
+ BASE_CONFIG = {'update_every': os.getenv('NETDATA_UPDATE_EVERY', 1),
+ 'retries': 60,
diff --git a/contrib/sles11/netdata.init b/contrib/sles11/netdata.init
new file mode 100755
index 0000000..3081c42
--- /dev/null
+++ b/contrib/sles11/netdata.init
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+### BEGIN INIT INFO
+# Provides: netdata
+# Required-Start: $all
+# Should-Start:
+# Required-Stop: $all
+# Should-Stop:
+# Default-Start: 2 3 5
+# Default-Stop:
+# Short-Description: Start and stop the netdata real-time monitoring server daemon
+# Description: Controls the main netdata monitoring server daemon "netdata".
+### END INIT INFO
+
+DAEMON="netdata"
+DAEMON_BIN="/usr/sbin/${DAEMON}"
+DAEMON_PID="/var/run/${DAEMON}.pid"
+DAEMON_ARGS=""
+
+. /etc/rc.status
+rc_reset
+
+if [ ! -x $DAEMON_BIN ]; then
+ echo -n >&2 "${DAEMON} binary is not installed. "
+ rc_status -s
+ exit 5
+fi
+
+case "$1" in
+ start)
+ echo -n "Starting $DAEMON"
+ /sbin/startproc $DAEMON_BIN $DAEMON_ARGS
+ rc_status -v
+ ;;
+
+ stop)
+ echo -n "Stopping $DAEMON"
+ /sbin/killproc $DAEMON_BIN
+ rc_status -v
+ ;;
+
+ reload)
+ # netdata: HUP reopen log files, USR1 save DB, USR2 reload health config
+ echo -n "Reloading $DAEMON config"
+ /sbin/killproc -USR2 $DAEMON_BIN
+ ;;
+
+ restart)
+ $0 stop
+ $0 start
+ ;;
+
+ status)
+ echo -n "Checking $DAEMON"
+ /sbin/checkproc $DAEMON_BIN
+ rc_status -v
+ ;;
+
+ *)
+ echo "Usage: $0 {start|stop|status|reload|restart}"
+ exit 1
+ ;;
+
+esac
+rc_exit