diff options
-rw-r--r-- | CONTRIBUTORS.md | 4 | ||||
-rw-r--r-- | conf.d/Makefile.am | 1 | ||||
-rw-r--r-- | conf.d/health.d/apcupsd.conf | 40 | ||||
-rw-r--r-- | configs.signatures | 3 | ||||
-rwxr-xr-x | netdata-installer.sh | 1 | ||||
-rwxr-xr-x | plugins.d/charts.d.plugin | 2 | ||||
-rw-r--r-- | python.d/redis.chart.py | 2 | ||||
-rw-r--r-- | python.d/tomcat.chart.py | 18 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/rrdpush.c | 28 | ||||
-rw-r--r-- | src/web_server.c | 1 | ||||
-rw-r--r-- | src/web_server.h | 1 |
12 files changed, 91 insertions, 11 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 384e06f4a1..7d2d930074 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -89,3 +89,7 @@ username|name|email (optional) @ccremer|Christian Cremer| @jimcooley|Jim Cooley|jim.cooley@healthvana.com @Chocobo1|Mike Tzou| +@cosmix|Dimosthenis Kaponis| +@shadycuz|Levi Blaney|shadycuz+spam@gmail.com +@Flums|Philip Gabrielsen|philip@digno.no +@domschl|Dominik Schlösser|dominik.schloesser@gmail.com diff --git a/conf.d/Makefile.am b/conf.d/Makefile.am index 4e692266b7..0026e3f130 100644 --- a/conf.d/Makefile.am +++ b/conf.d/Makefile.am @@ -89,6 +89,7 @@ healthconfigdir=$(configdir)/health.d dist_healthconfig_DATA = \ health.d/apache.conf \ + health.d/apcupsd.conf \ health.d/backend.conf \ health.d/bcache.conf \ health.d/beanstalkd.conf \ diff --git a/conf.d/health.d/apcupsd.conf b/conf.d/health.d/apcupsd.conf new file mode 100644 index 0000000000..214974e230 --- /dev/null +++ b/conf.d/health.d/apcupsd.conf @@ -0,0 +1,40 @@ +# you can disable an alarm notification by setting the 'to' line to: silent + +template: 10min_ups_load + on: apcupsd.load + os: * + hosts: * + lookup: average -10m unaligned of percentage + units: % + every: 1m + warn: $this > (($status >= $WARNING) ? (70) : (80)) + crit: $this > (($status == $CRITICAL) ? (85) : (95)) + delay: down 10m multiplier 1.5 max 1h + info: average UPS load for the last 10 minutes + to: sitemgr + +# Discussion in https://github.com/firehol/netdata/pull/3928: +# Fire the alarm as soon as it's going on battery (99% charge) and clear only when full. +template: ups_charge + on: apcupsd.charge + os: * + hosts: * + lookup: average -60s unaligned of charge + units: % + every: 60s + warn: $this < 100 + crit: $this < (($status == $CRITICAL) ? (60) : (50)) + delay: down 10m multiplier 1.5 max 1h + info: current UPS charge, averaged over the last 60 seconds to reduce measurement errors + to: sitemgr + +template: apcupsd_last_collected_secs + on: apcupsd.load + calc: $now - $last_collected_t + every: 10s + units: seconds ago + warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every)) + crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every)) + delay: down 5m multiplier 1.5 max 1h + info: number of seconds since the last successful data collection + to: sitemgr diff --git a/configs.signatures b/configs.signatures index 04b2a79205..9f1dd24441 100644 --- a/configs.signatures +++ b/configs.signatures @@ -129,6 +129,7 @@ declare -A configs_signatures=( ['2da0a2e7117292ece11d69723a294bd7']='python.d/mongodb.conf' ['2ee5df033fe9c65a45566b6760b856e3']='python.d/web_log.conf' ['2f05e09b69ea20cda56d8f8b6fd3e86d']='health.d/couchdb.conf' + ['2f13a6b7d11eda826ff26569b2a77080']='health.d/apcupsd.conf' ['2f3a8e33df83f14e0af8ca2465697215']='python.d/exim.conf' ['2f4a85fedecce1bf425fa1039f6b021e']='apps_groups.conf' ['2fa8fb929fd597f2ab97b6efc540a043']='health_alarm_notify.conf' @@ -251,6 +252,7 @@ declare -A configs_signatures=( ['579c7c41c756745f57afd11c94a879d7']='python.d.conf' ['57be306944cb09b7f024079728fd04b9']='apps_groups.conf' ['5829812db29598db5857c9f433e96fef']='python.d/apache.conf' + ['58439d9c1253e33c74b399e6853143ab']='health.d/apcupsd.conf' ['5855dd70d71c8497e5591b0690162c9c']='health.d/tcp_resets.conf' ['58660dfcc260f77deec94b328b3838e8']='health_alarm_notify.conf' ['58e835b7176865ec5a6f59f7aba832bf']='health.d/named.conf' @@ -386,6 +388,7 @@ declare -A configs_signatures=( ['87615ae5ac2412d853c717383fa53781']='python.d/chrony.conf' ['87642c568093daf3b2c30c5beffe2225']='python.d/elasticsearch.conf' ['8810140ce9c09af1d18b9602c4003904']='health_alarm_notify.conf' + ['886975ecb9a4e856151dc71024b122e6']='health.d/apcupsd.conf' ['8891fb423f6b987281d7913bb6c1c024']='health.d/ipc.conf' ['88e3b51b6b3fe8f317df82a2d4fbb990']='python.d.conf' ['88f77865f75c9fb61c97d700bd4561ee']='python.d/mysql.conf' diff --git a/netdata-installer.sh b/netdata-installer.sh index 59436a2104..1c77e8f86a 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -80,6 +80,7 @@ REINSTALL_COMMAND="$(printf "%q " "$0" "${@}"; printf "\n")" # remove options that shown not be inherited by netdata-updater.sh REINSTALL_COMMAND="${REINSTALL_COMMAND// --dont-wait/}" REINSTALL_COMMAND="${REINSTALL_COMMAND// --dont-start-it/}" +[ "${REINSTALL_COMMAND:0:1}" != "." -a "${REINSTALL_COMMAND:0:1}" != "/" -a -f "./${0}" ] && REINSTALL_COMMAND="./${REINSTALL_COMMAND}" setcap="$(which setcap 2>/dev/null || command -v setcap 2>/dev/null)" diff --git a/plugins.d/charts.d.plugin b/plugins.d/charts.d.plugin index 544f863215..4a390a85fd 100755 --- a/plugins.d/charts.d.plugin +++ b/plugins.d/charts.d.plugin @@ -297,7 +297,7 @@ run() { { printf "$(logdate): ${PROGRAM_NAME}: ${status}: ${MODULE_NAME}: command '" printf "%q " "${@}" - printf "' failed:\n --- BEGIN TRACE ---\n" + printf "' failed with code ${ret}:\n --- BEGIN TRACE ---\n" cat "${TMP_DIR}/run.${pid}" printf " --- END TRACE ---\n" } >&2 diff --git a/python.d/redis.chart.py b/python.d/redis.chart.py index a40932b3aa..f924d55bf5 100644 --- a/python.d/redis.chart.py +++ b/python.d/redis.chart.py @@ -152,7 +152,7 @@ class Service(SocketService): resp = self._get_raw_data(request=self.auth_request) if not resp: return False - if not resp.strip() != '+OK': + if resp.strip() != '+OK': self.error("invalid password") return False return True diff --git a/python.d/tomcat.chart.py b/python.d/tomcat.chart.py index 148e5db546..7699c582f6 100644 --- a/python.d/tomcat.chart.py +++ b/python.d/tomcat.chart.py @@ -54,21 +54,21 @@ CHARTS = { 'options': [None, "Eden Memory Usage", "MB", "memory", "tomcat.jvm_eden", "area"], 'lines': [ ["eden_used", 'used', "absolute", 1, 1048576], - ["eden_commited", 'commited', "absolute", 1, 1048576], + ["eden_committed", 'committed', "absolute", 1, 1048576], ["eden_max", 'max', "absolute", 1, 1048576] ]}, 'jvm_survivor': { 'options': [None, "Survivor Memory Usage", "MB", "memory", "tomcat.jvm_survivor", "area"], 'lines': [ ["survivor_used", 'used', "absolute", 1, 1048576], - ["survivor_commited", 'commited', "absolute", 1, 1048576], + ["survivor_committed", 'committed', "absolute", 1, 1048576], ["survivor_max", 'max', "absolute", 1, 1048576] ]}, 'jvm_tenured': { 'options': [None, "Tenured Memory Usage", "MB", "memory", "tomcat.jvm_tenured", "area"], 'lines': [ ["tenured_used", 'used', "absolute", 1, 1048576], - ["tenured_commited", 'commited', "absolute", 1, 1048576], + ["tenured_committed", 'committed', "absolute", 1, 1048576], ["tenured_max", 'max', "absolute", 1, 1048576] ]}, } @@ -116,27 +116,27 @@ class Service(UrlService): name = pool.get('name') if 'Eden Space' in name: data['eden_used'] = pool.get('usageUsed') - data['eden_commited'] = pool.get('usageCommitted') + data['eden_committed'] = pool.get('usageCommitted') data['eden_max'] = pool.get('usageMax') elif 'Survivor Space' in name: data['survivor_used'] = pool.get('usageUsed') - data['survivor_commited'] = pool.get('usageCommitted') + data['survivor_committed'] = pool.get('usageCommitted') data['survivor_max'] = pool.get('usageMax') elif 'Tenured Gen' in name or 'Old Gen' in name: data['tenured_used'] = pool.get('usageUsed') - data['tenured_commited'] = pool.get('usageCommitted') + data['tenured_committed'] = pool.get('usageCommitted') data['tenured_max'] = pool.get('usageMax') elif name == 'Code Cache': data['code_cache_used'] = pool.get('usageUsed') - data['code_cache_commited'] = pool.get('usageCommitted') + data['code_cache_committed'] = pool.get('usageCommitted') data['code_cache_max'] = pool.get('usageMax') elif name == 'Compressed': data['compressed_used'] = pool.get('usageUsed') - data['compressed_commited'] = pool.get('usageCommitted') + data['compressed_committed'] = pool.get('usageCommitted') data['compressed_max'] = pool.get('usageMax') elif name == 'Metaspace': data['metaspace_used'] = pool.get('usageUsed') - data['metaspace_commited'] = pool.get('usageCommitted') + data['metaspace_committed'] = pool.get('usageCommitted') data['metaspace_max'] = pool.get('usageMax') if connector: diff --git a/src/main.c b/src/main.c index 277ffcdae2..9443095561 100644 --- a/src/main.c +++ b/src/main.c @@ -102,6 +102,7 @@ void web_server_threading_selection(void) { void web_server_config_options(void) { web_client_timeout = (int) config_get_number(CONFIG_SECTION_WEB, "disconnect idle clients after seconds", web_client_timeout); web_client_first_request_timeout = (int) config_get_number(CONFIG_SECTION_WEB, "timeout for first request", web_client_first_request_timeout); + web_client_streaming_rate_t = config_get_number(CONFIG_SECTION_WEB, "accept a streaming request every seconds", web_client_streaming_rate_t); respect_web_browser_do_not_track_policy = config_get_boolean(CONFIG_SECTION_WEB, "respect do not track policy", respect_web_browser_do_not_track_policy); web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", ""); diff --git a/src/rrdpush.c b/src/rrdpush.c index 68def2247b..c28512ee05 100644 --- a/src/rrdpush.c +++ b/src/rrdpush.c @@ -1006,6 +1006,14 @@ int rrdpush_receiver_permission_denied(struct web_client *w) { return 401; } +int rrdpush_receiver_too_busy_now(struct web_client *w) { + // we always respond with the same message and error code + // to prevent an attacker from gaining info about the error + buffer_flush(w->response.data); + buffer_sprintf(w->response.data, "The server is too busy now to accept this request. Try later."); + return 503; +} + int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url) { (void)host; @@ -1111,6 +1119,26 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url } } + if(unlikely(web_client_streaming_rate_t > 0)) { + static netdata_mutex_t stream_rate_mutex = NETDATA_MUTEX_INITIALIZER; + static volatile time_t last_stream_accepted_t = 0; + + netdata_mutex_lock(&stream_rate_mutex); + time_t now = now_realtime_sec(); + + if(unlikely(last_stream_accepted_t == 0)) + last_stream_accepted_t = now; + + if(now - last_stream_accepted_t < web_client_streaming_rate_t) { + netdata_mutex_unlock(&stream_rate_mutex); + error("STREAM [receive from [%s]:%s]: too busy to accept new streaming request. Will be allowed in %ld secs.", w->client_ip, w->client_port, (long)(web_client_streaming_rate_t - (now - last_stream_accepted_t))); + return rrdpush_receiver_too_busy_now(w); + } + + last_stream_accepted_t = now; + netdata_mutex_unlock(&stream_rate_mutex); + } + struct rrdpush_thread *rpt = callocz(1, sizeof(struct rrdpush_thread)); rpt->fd = w->ifd; rpt->key = strdupz(key); diff --git a/src/web_server.c b/src/web_server.c index 8c0aae46b5..ee8dddf7b9 100644 --- a/src/web_server.c +++ b/src/web_server.c @@ -409,6 +409,7 @@ static struct web_client *web_client_create_on_listenfd(int listener) { int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS; int web_client_first_request_timeout = DEFAULT_TIMEOUT_TO_RECEIVE_FIRST_WEB_REQUEST; +long web_client_streaming_rate_t = 0L; static void multi_threaded_web_client_worker_main_cleanup(void *ptr) { struct web_client *w = ptr; diff --git a/src/web_server.h b/src/web_server.h index 3542f30b26..3b7db2214a 100644 --- a/src/web_server.h +++ b/src/web_server.h @@ -43,5 +43,6 @@ extern int api_listen_sockets_setup(void); #define DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS 60 extern int web_client_timeout; extern int web_client_first_request_timeout; +extern long web_client_streaming_rate_t; #endif /* NETDATA_WEB_SERVER_H */ |