From 171d8f5d01f17dddbd531139b86e1a1c96f95b0d Mon Sep 17 00:00:00 2001
From: "Pavlos Emm. Katsoulakis" <paul@netdata.rocks>
Date: Fri, 28 Jun 2019 08:27:57 +0200
Subject: [PATCH] Revert "Easily disable alarms, by persisting the silencers
 configuration (#6274)"

This reverts commit 60a73e90de2aa1c2eaae2ebbc45dd1fb96034df2.

Emergency rollback of potential culprit as per issue #6356
Will be re-merging the change after investigation
---
 CMakeLists.txt                                |  17 +-
 Makefile.am                                   |  12 +-
 configure.ac                                  |  39 --
 health/health.c                               | 101 +---
 health/health.h                               |  44 +-
 health/health_config.c                        |   2 +-
 libnetdata/Makefile.am                        |   2 -
 libnetdata/health/Makefile.am                 |   8 -
 libnetdata/health/health.c                    | 154 -----
 libnetdata/health/health.h                    |  54 --
 libnetdata/json/Makefile.am                   |   9 -
 libnetdata/json/README.md                     |   5 -
 libnetdata/json/jsmn.c                        | 326 -----------
 libnetdata/json/jsmn.h                        |  75 ---
 libnetdata/json/json.c                        | 546 ------------------
 libnetdata/json/json.h                        |  72 ---
 libnetdata/libnetdata.h                       |   2 -
 netdata-installer.sh                          |   2 -
 .../expected_list/ALARM_CPU_IOWAIT-list.json  |   1 -
 .../expected_list/ALARM_CPU_USAGE-list.json   |   1 -
 .../CONTEXT_SYSTEM_CPU-list.json              |   1 -
 .../expected_list/DISABLE-list.json           |   1 -
 .../expected_list/DISABLE_ALL-list.json       |   1 -
 .../expected_list/DISABLE_ALL_ERROR-list.json |   1 -
 .../DISABLE_SYSTEM_LOAD-list.json             |   1 -
 .../expected_list/FAMILIES_LOAD-list.json     |   1 -
 .../expected_list/HOSTS-list.json             |   1 -
 .../expected_list/RESET-list.json             |   1 -
 .../expected_list/SILENCE-list.json           |   1 -
 .../expected_list/SILENCE_2-list.json         |   1 -
 .../expected_list/SILENCE_3-list.json         |   1 -
 .../SILENCE_ALARM_CPU_USAGE-list.json         |   1 -
 ...NCE_ALARM_CPU_USAGE_LOAD_TRIGGER-list.json |   1 -
 .../expected_list/SILENCE_ALL-list.json       |   1 -
 tests/health_mgmtapi/health-cmdapi-test.sh.in |  40 +-
 web/api/health/README.md                      |  51 +-
 web/api/health/health_cmdapi.c                | 176 +++---
 web/api/health/health_cmdapi.h                |   2 +-
 web/api/netdata-swagger.json                  |   5 +-
 web/api/netdata-swagger.yaml                  |   4 +-
 40 files changed, 126 insertions(+), 1638 deletions(-)
 delete mode 100644 libnetdata/health/Makefile.am
 delete mode 100644 libnetdata/health/health.c
 delete mode 100644 libnetdata/health/health.h
 delete mode 100644 libnetdata/json/Makefile.am
 delete mode 100644 libnetdata/json/README.md
 delete mode 100644 libnetdata/json/jsmn.c
 delete mode 100644 libnetdata/json/jsmn.h
 delete mode 100644 libnetdata/json/json.c
 delete mode 100644 libnetdata/json/json.h
 delete mode 100644 tests/health_mgmtapi/expected_list/ALARM_CPU_IOWAIT-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/ALARM_CPU_USAGE-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/CONTEXT_SYSTEM_CPU-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/DISABLE-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/DISABLE_ALL-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/DISABLE_ALL_ERROR-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/DISABLE_SYSTEM_LOAD-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/FAMILIES_LOAD-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/HOSTS-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/RESET-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/SILENCE-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/SILENCE_2-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/SILENCE_3-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE_LOAD_TRIGGER-list.json
 delete mode 100644 tests/health_mgmtapi/expected_list/SILENCE_ALL-list.json

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7a90d680d9..e6109c2fc2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -130,14 +130,6 @@ set(NETDATA_COMMON_CFLAGS ${NETDATA_COMMON_CFLAGS} ${OPENSSL_CFLAGS_OTHER})
 set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} ${OPENSSL_LIBRARIES})
 set(NETDATA_COMMON_INCLUDE_DIRS ${NETDATA_COMMON_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS})
 
-# -----------------------------------------------------------------------------
-# JSON-C used to health
-
-pkg_check_modules(JSON REQUIRED json-c)
-set(NETDATA_COMMON_CFLAGS ${NETDATA_COMMON_CFLAGS} ${JSONC_CFLAGS_OTHER})
-set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} ${JSON_LIBRARIES})
-set(NETDATA_COMMON_INCLUDE_DIRS ${NETDATA_COMMON_INCLUDE_DIRS} ${JSON_INCLUDE_DIRS})
-
 # -----------------------------------------------------------------------------
 # Detect libcap
 
@@ -313,15 +305,8 @@ set(LIBNETDATA_FILES
         libnetdata/threads/threads.h
         libnetdata/url/url.c
         libnetdata/url/url.h
-        libnetdata/health/health.c
-        libnetdata/health/health.h
         libnetdata/socket/security.c
-        libnetdata/socket/security.h
-        libnetdata/json/json.c
-        libnetdata/json/json.h
-        libnetdata/json/jsmn.c
-        libnetdata/json/jsmn.h
-        )
+        libnetdata/socket/security.h)
 
 add_library(libnetdata OBJECT ${LIBNETDATA_FILES})
 
diff --git a/Makefile.am b/Makefile.am
index 2729af38ad..6dacd825ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -159,14 +159,8 @@ LIBNETDATA_FILES = \
     libnetdata/storage_number/storage_number.h \
     libnetdata/threads/threads.c \
     libnetdata/threads/threads.h \
-    libnetdata/url/url.c \
-    libnetdata/url/url.h \
-    libnetdata/json/jsmn.h \
-    libnetdata/json/jsmn.c \
-    libnetdata/json/json.h \
-    libnetdata/json/json.c \
-    libnetdata/health/health.c \
-    libnetdata/health/health.h \
+	libnetdata/url/url.c \
+	libnetdata/url/url.h \
     $(NULL)
 
 APPS_PLUGIN_FILES = \
@@ -512,12 +506,12 @@ endif
 NETDATA_COMMON_LIBS = \
 	$(OPTIONAL_MATH_LIBS) \
 	$(OPTIONAL_ZLIB_LIBS) \
+	$(OPTIONAL_SSL_LIBS) \
 	$(OPTIONAL_UUID_LIBS) \
 	$(OPTIONAL_UV_LIBS) \
 	$(OPTIONAL_LZ4_LIBS) \
 	$(OPTIONAL_JUDY_LIBS) \
 	$(OPTIONAL_SSL_LIBS) \
-	$(OPTIONAL_JSONC_LIBS) \
 	$(NULL)
 
 sbin_PROGRAMS += netdata
diff --git a/configure.ac b/configure.ac
index fcf1931fcc..1b021255a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -142,12 +142,6 @@ AC_ARG_ENABLE(
     ,
     [enable_https="detect"]
 )
-AC_ARG_ENABLE(
-    [jsonc],
-    [AS_HELP_STRING([--enable-jsonc], [Enable JSON-C support @<:@default autodetect@:>@])],
-    ,
-    [enable_jsonc="detect"]
-)
 AC_ARG_ENABLE(
     [dbengine],
     [AS_HELP_STRING([--disable-dbengine], [disable netdata dbengine @<:@default autodetect@:>@])],
@@ -353,20 +347,6 @@ AC_CHECK_LIB(
 OPTIONAL_SSL_CFLAGS="${SSL_CFLAGS}"
 OPTIONAL_SSL_LIBS="${SSL_LIBS}"
 
-# -----------------------------------------------------------------------------
-# JSON-C library
-
-PKG_CHECK_MODULES([JSON],[json-c],AC_CHECK_LIB(
-    [json-c],
-    [json_object_get_type],
-    [JSONC_LIBS="-ljson-c"]),AC_CHECK_LIB(
-        [json],
-        [json_object_get_type],
-        [JSONC_LIBS="-ljson"])
-    )
-
-OPTIONAL_JSONC_LIBS="${JSONC_LIBS}"
-
 # -----------------------------------------------------------------------------
 # DB engine and HTTPS
 test "${enable_dbengine}" = "yes" -a -z "${UV_LIBS}" && \
@@ -401,22 +381,6 @@ fi
 AC_MSG_RESULT([${enable_https}])
 AM_CONDITIONAL([ENABLE_HTTPS], [test "${enable_https}" = "yes"])
 
-# -----------------------------------------------------------------------------
-# JSON-C
-test "${enable_jsonc}" = "yes" -a -z "${JSONC_LIBS}" && \
-    AC_MSG_ERROR([JSON-C required but not found. Try installing 'libjson-c-dev' or 'json-c'.])
-
-AC_MSG_CHECKING([if json-c should be used])
-if test "${enable_jsonc}" != "no" -a "${JSONC_LIBS}"; then
-	enable_jsonc="yes"
-	AC_DEFINE([ENABLE_JSONC], [1], [netdata json-c usability])
-else
-	enable_jsonc="no"
-fi
-AC_MSG_RESULT([${enable_jsonc}])
-AM_CONDITIONAL([ENABLE_JSONC], [test "${enable_jsonc}" = "yes"])
-
-
 # -----------------------------------------------------------------------------
 # compiler options
 
@@ -1011,7 +975,6 @@ AC_SUBST([OPTIONAL_UV_LIBS])
 AC_SUBST([OPTIONAL_LZ4_LIBS])
 AC_SUBST([OPTIONAL_JUDY_LIBS])
 AC_SUBST([OPTIONAL_SSL_LIBS])
-AC_SUBST([OPTIONAL_JSONC_LIBS])
 AC_SUBST([OPTIONAL_NFACCT_CFLAGS])
 AC_SUBST([OPTIONAL_NFACCT_LIBS])
 AC_SUBST([OPTIONAL_ZLIB_CFLAGS])
@@ -1078,8 +1041,6 @@ AC_CONFIG_FILES([
     libnetdata/config/Makefile
     libnetdata/dictionary/Makefile
     libnetdata/eval/Makefile
-    libnetdata/json/Makefile
-    libnetdata/health/Makefile
     libnetdata/locks/Makefile
     libnetdata/log/Makefile
     libnetdata/popen/Makefile
diff --git a/health/health.c b/health/health.c
index 55d44e955d..f92a1ba6b0 100644
--- a/health/health.c
+++ b/health/health.c
@@ -1,6 +1,5 @@
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-#include <libnetdata/json/json.h>
 #include "health.h"
 
 struct health_cmdapi_thread_status {
@@ -14,79 +13,18 @@ unsigned int default_health_enabled = 1;
 // ----------------------------------------------------------------------------
 // health initialization
 
-/**
- * User Config directory
- *
- * Get the config directory for health and return it.
- *
- * @return a pointer to the user config directory
- */
 inline char *health_user_config_dir(void) {
     char buffer[FILENAME_MAX + 1];
     snprintfz(buffer, FILENAME_MAX, "%s/health.d", netdata_configured_user_config_dir);
     return config_get(CONFIG_SECTION_HEALTH, "health configuration directory", buffer);
 }
 
-/**
- * Stock Config Directory
- *
- * Get the Stock config directory and return it.
- *
- * @return a pointer to the stock config directory.
- */
 inline char *health_stock_config_dir(void) {
     char buffer[FILENAME_MAX + 1];
     snprintfz(buffer, FILENAME_MAX, "%s/health.d", netdata_configured_stock_config_dir);
     return config_get(CONFIG_SECTION_HEALTH, "stock health configuration directory", buffer);
 }
 
-
-/**
- * Silencers init
- *
- * Function used to initialize the silencer structure.
- */
-void health_silencers_init(void) {
-    silencers = mallocz(sizeof(SILENCERS));
-    silencers->all_alarms=0;
-    silencers->stype=STYPE_NONE;
-    silencers->silencers=NULL;
-
-    char filename[FILENAME_MAX + 1];
-    snprintfz(filename, FILENAME_MAX, "%s/health.silencers.json", netdata_configured_varlib_dir);
-    silencers_filename = config_get(CONFIG_SECTION_HEALTH, "silencers file", filename);
-
-    struct stat statbuf;
-    if (!stat(silencers_filename,&statbuf)) {
-        off_t length = statbuf.st_size;
-        if (length && length < HEALTH_SILENCERS_MAX_FILE_LEN) {
-            FILE *fd = fopen(silencers_filename, "r");
-            if (fd) {
-                char *str = mallocz((length+1)* sizeof(char));
-                if(str) {
-                    fread(str, sizeof(char), length, fd);
-                    str[length] = 0x00;
-                    json_parse(str, NULL, health_silencers_json_read_callback);
-                    freez(str);
-                    info("Parsed health silencers file %s", silencers_filename);
-                }
-                fclose(fd);
-            } else {
-                error("Cannot open the file %s",silencers_filename);
-            }
-        } else {
-            error("Health silencers file %s has the size %ld that is out of range[ 1 , %d ]. Aborting read.", silencers_filename, length, HEALTH_SILENCERS_MAX_FILE_LEN);
-        }
-    } else {
-        error("Cannot open the file %s",silencers_filename);
-    }
-}
-
-/**
- * Health Init
- *
- * Initialize the health thread.
- */
 void health_init(void) {
     debug(D_HEALTH, "Health configuration initializing");
 
@@ -94,20 +32,11 @@ void health_init(void) {
         debug(D_HEALTH, "Health is disabled.");
         return;
     }
-
-    health_silencers_init();
 }
 
 // ----------------------------------------------------------------------------
 // re-load health configuration
 
-/**
- * Reload host
- *
- * Reload configuration for a specific host.
- *
- * @param host the structure of the host that the function will reload the configuration.
- */
 void health_reload_host(RRDHOST *host) {
     if(unlikely(!host->health_enabled))
         return;
@@ -155,11 +84,6 @@ void health_reload_host(RRDHOST *host) {
     rrdhost_unlock(host);
 }
 
-/**
- * Reload
- *
- * Reload the host configuration for all hosts.
- */
 void health_reload(void) {
 
     rrd_rdlock();
@@ -501,16 +425,6 @@ SILENCE_TYPE check_silenced(RRDCALC *rc, char* host, SILENCERS *silencers) {
     return STYPE_NONE;
 }
 
-/**
- * Update Disabled Silenced
- *
- * Update the variable rrdcalc_flags of the structure RRDCALC according with the values of the host structure
- *
- * @param host structure that contains information about the host monitored.
- * @param rc structure with information about the alarm
- *
- * @return It returns 1 case rrdcalc_flags is DISABLED or 0 otherwise
- */
 int update_disabled_silenced(RRDHOST *host, RRDCALC *rc) {
 	uint32_t rrdcalc_flags_old = rc->rrdcalc_flags;
 	// Clear the flags
@@ -540,15 +454,6 @@ int update_disabled_silenced(RRDHOST *host, RRDCALC *rc) {
 		return 0;
 }
 
-/**
- * Health Main
- *
- * The main thread of the health system. In this function all the alarms will be processed.
- *
- * @param ptr is a pointer to the netdata_static_thread structure.
- *
- * @return It always returns NULL
- */
 void *health_main(void *ptr) {
     netdata_thread_cleanup_push(health_main_cleanup, ptr);
 
@@ -560,6 +465,11 @@ void *health_main(void *ptr) {
 
     unsigned int loop = 0;
 
+    silencers =  mallocz(sizeof(SILENCERS));
+    silencers->all_alarms=0;
+    silencers->stype=STYPE_NONE;
+    silencers->silencers=NULL;
+
     while(!netdata_exit) {
 		loop++;
 		debug(D_HEALTH, "Health monitoring iteration no %u started", loop);
@@ -613,7 +523,6 @@ void *health_main(void *ptr) {
 			// the first loop is to lookup values from the db
 			for (rc = host->alarms; rc; rc = rc->next) {
 
-			    //case it is disabled I will get the next rc
 				if (update_disabled_silenced(host, rc))
 					continue;
 
diff --git a/health/health.h b/health/health.h
index acbcf827c2..1511f36486 100644
--- a/health/health.h
+++ b/health/health.h
@@ -35,9 +35,16 @@ extern unsigned int default_health_enabled;
 #define HEALTH_LISTEN_BACKLOG 4096
 #endif
 
-
+#define HEALTH_ALARM_KEY "alarm"
+#define HEALTH_TEMPLATE_KEY "template"
 #define HEALTH_ON_KEY "on"
-
+#define HEALTH_CONTEXT_KEY "context"
+#define HEALTH_CHART_KEY "chart"
+#define HEALTH_HOST_KEY "hosts"
+#define HEALTH_OS_KEY "os"
+#define HEALTH_FAMILIES_KEY "families"
+#define HEALTH_LOOKUP_KEY "lookup"
+#define HEALTH_CALC_KEY "calc"
 #define HEALTH_EVERY_KEY "every"
 #define HEALTH_GREEN_KEY "green"
 #define HEALTH_RED_KEY "red"
@@ -50,9 +57,38 @@ extern unsigned int default_health_enabled;
 #define HEALTH_DELAY_KEY "delay"
 #define HEALTH_OPTIONS_KEY "options"
 
-#define HEALTH_SILENCERS_MAX_FILE_LEN 10000
+typedef struct silencer {
+    char *alarms;
+    SIMPLE_PATTERN *alarms_pattern;
 
-char *silencers_filename;
+    char *hosts;
+    SIMPLE_PATTERN *hosts_pattern;
+
+    char *contexts;
+    SIMPLE_PATTERN *contexts_pattern;
+
+    char *charts;
+    SIMPLE_PATTERN *charts_pattern;
+
+    char *families;
+    SIMPLE_PATTERN *families_pattern;
+
+    struct silencer *next;
+} SILENCER;
+
+typedef enum silence_type {
+    STYPE_NONE,
+    STYPE_DISABLE_ALARMS,
+    STYPE_SILENCE_NOTIFICATIONS
+} SILENCE_TYPE;
+
+typedef struct silencers {
+    int all_alarms;
+    SILENCE_TYPE stype;
+    SILENCER *silencers;
+} SILENCERS;
+
+SILENCERS *silencers;
 
 extern void health_init(void);
 extern void *health_main(void *ptr);
diff --git a/health/health_config.c b/health/health_config.c
index 54d11b6a1c..35fde90bc2 100644
--- a/health/health_config.c
+++ b/health/health_config.c
@@ -481,7 +481,7 @@ static int health_readfile(const char *filename, void *data) {
             if(append < HEALTH_CONF_MAX_LINE)
                 continue;
             else {
-                error("Health configuration has too long multi-line at line %zu of file '%s'.", line, filename);
+                error("Health configuration has too long muli-line at line %zu of file '%s'.", line, filename);
             }
         }
         append = 0;
diff --git a/libnetdata/Makefile.am b/libnetdata/Makefile.am
index 8f41d82105..d2710f0a3e 100644
--- a/libnetdata/Makefile.am
+++ b/libnetdata/Makefile.am
@@ -21,8 +21,6 @@ SUBDIRS = \
     storage_number \
     threads \
     url \
-    json \
-    health \
     $(NULL)
 
 dist_noinst_DATA = \
diff --git a/libnetdata/health/Makefile.am b/libnetdata/health/Makefile.am
deleted file mode 100644
index 9b7995f175..0000000000
--- a/libnetdata/health/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-AUTOMAKE_OPTIONS = subdir-objects
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
-
-
-dist_noinst_DATA = \
-	$(NULL)
diff --git a/libnetdata/health/health.c b/libnetdata/health/health.c
deleted file mode 100644
index b3d342d406..0000000000
--- a/libnetdata/health/health.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "health.h"
-
-/**
- * Create Silencer
- *
- * Allocate a new silencer to Netdata.
- *
- * @return It returns the address off the silencer on success and NULL otherwise
- */
-SILENCER *create_silencer(void) {
-    SILENCER *t = callocz(1, sizeof(SILENCER));
-    debug(D_HEALTH, "HEALTH command API: Created empty silencer");
-
-    return t;
-}
-
-/**
- * Health Silencers add
- *
- * Add more one silencer to the list of silenecers.
- *
- * @param silencer
- */
-void health_silencers_add(SILENCER *silencer) {
-    // Add the created instance to the linked list in silencers
-    silencer->next = silencers->silencers;
-    silencers->silencers = silencer;
-    debug(D_HEALTH, "HEALTH command API: Added silencer %s:%s:%s:%s:%s", silencer->alarms,
-          silencer->charts, silencer->contexts, silencer->hosts, silencer->families
-    );
-}
-
-/**
- * Silencers Add Parameter
- *
- * Create a new silencer and adjust the variables
- *
- * @param silencer a pointer to the silencer that will be adjusted
- * @param key the key value sent by client
- * @param value the value sent to the key
- *
- * @return It returns the silencer configured on success and NULL otherwise
- */
-SILENCER *health_silencers_addparam(SILENCER *silencer, char *key, char *value) {
-    static uint32_t
-            hash_alarm = 0,
-            hash_template = 0,
-            hash_chart = 0,
-            hash_context = 0,
-            hash_host = 0,
-            hash_families = 0;
-
-    if (unlikely(!hash_alarm)) {
-        hash_alarm = simple_uhash(HEALTH_ALARM_KEY);
-        hash_template = simple_uhash(HEALTH_TEMPLATE_KEY);
-        hash_chart = simple_uhash(HEALTH_CHART_KEY);
-        hash_context = simple_uhash(HEALTH_CONTEXT_KEY);
-        hash_host = simple_uhash(HEALTH_HOST_KEY);
-        hash_families = simple_uhash(HEALTH_FAMILIES_KEY);
-    }
-
-    uint32_t hash = simple_uhash(key);
-    if (unlikely(silencer == NULL)) {
-        if (
-                (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) ||
-                (hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) ||
-                (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) ||
-                (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) ||
-                (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) ||
-                (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY))
-                ) {
-            silencer = create_silencer();
-            if(!silencer) {
-                error("Cannot add a new silencer to Netdata");
-                return NULL;
-            }
-        }
-    }
-
-    if (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
-        silencer->alarms = strdupz(value);
-        silencer->alarms_pattern = simple_pattern_create(silencer->alarms, NULL, SIMPLE_PATTERN_EXACT);
-    } else if (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) {
-        silencer->charts = strdupz(value);
-        silencer->charts_pattern = simple_pattern_create(silencer->charts, NULL, SIMPLE_PATTERN_EXACT);
-    } else if (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) {
-        silencer->contexts = strdupz(value);
-        silencer->contexts_pattern = simple_pattern_create(silencer->contexts, NULL, SIMPLE_PATTERN_EXACT);
-    } else if (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) {
-        silencer->hosts = strdupz(value);
-        silencer->hosts_pattern = simple_pattern_create(silencer->hosts, NULL, SIMPLE_PATTERN_EXACT);
-    } else if (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) {
-        silencer->families = strdupz(value);
-        silencer->families_pattern = simple_pattern_create(silencer->families, NULL, SIMPLE_PATTERN_EXACT);
-    }
-
-    return silencer;
-}
-
-/**
- * JSON Read Callback
- *
- * Callback called by netdata to create the silencer.
- *
- * @param e the main json structure
- *
- * @return It always return 0.
- */
-int health_silencers_json_read_callback(JSON_ENTRY *e)
-{
-    switch(e->type) {
-        case JSON_OBJECT:
-#ifndef ENABLE_JSONC
-            e->callback_function = health_silencers_json_read_callback;
-            if(e->name && strcmp(e->name,"")) {
-                // init silencer
-                debug(D_HEALTH, "JSON: Got object with a name, initializing new silencer for %s",e->name);
-#endif
-            e->callback_data = create_silencer();
-            if(e->callback_data) {
-                health_silencers_add(e->callback_data);
-            }
-#ifndef ENABLE_JSONC
-            }
-#endif
-            break;
-
-        case JSON_ARRAY:
-            e->callback_function = health_silencers_json_read_callback;
-            break;
-
-        case JSON_STRING:
-            if(!strcmp(e->name,"type")) {
-                debug(D_HEALTH, "JSON: Processing type=%s",e->data.string);
-                if (!strcmp(e->data.string,"SILENCE")) silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
-                else if (!strcmp(e->data.string,"DISABLE")) silencers->stype = STYPE_DISABLE_ALARMS;
-            } else {
-                debug(D_HEALTH, "JSON: Adding %s=%s", e->name, e->data.string);
-                health_silencers_addparam(e->callback_data, e->name, e->data.string);
-            }
-            break;
-
-        case JSON_BOOLEAN:
-            debug(D_HEALTH, "JSON: Processing all_alarms");
-            silencers->all_alarms=e->data.boolean?1:0;
-            break;
-
-        case JSON_NUMBER:
-        case JSON_NULL:
-            break;
-    }
-
-    return 0;
-}
diff --git a/libnetdata/health/health.h b/libnetdata/health/health.h
deleted file mode 100644
index 7d560fe95c..0000000000
--- a/libnetdata/health/health.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef NETDATA_HEALTH_LIB
-# define NETDATA_HEALTH_LIB 1
-
-# include "../libnetdata.h"
-
-#define HEALTH_ALARM_KEY "alarm"
-#define HEALTH_TEMPLATE_KEY "template"
-#define HEALTH_CONTEXT_KEY "context"
-#define HEALTH_CHART_KEY "chart"
-#define HEALTH_HOST_KEY "hosts"
-#define HEALTH_OS_KEY "os"
-#define HEALTH_FAMILIES_KEY "families"
-#define HEALTH_LOOKUP_KEY "lookup"
-#define HEALTH_CALC_KEY "calc"
-
-typedef struct silencer {
-    char *alarms;
-    SIMPLE_PATTERN *alarms_pattern;
-
-    char *hosts;
-    SIMPLE_PATTERN *hosts_pattern;
-
-    char *contexts;
-    SIMPLE_PATTERN *contexts_pattern;
-
-    char *charts;
-    SIMPLE_PATTERN *charts_pattern;
-
-    char *families;
-    SIMPLE_PATTERN *families_pattern;
-
-    struct silencer *next;
-} SILENCER;
-
-typedef enum silence_type {
-    STYPE_NONE,
-    STYPE_DISABLE_ALARMS,
-    STYPE_SILENCE_NOTIFICATIONS
-} SILENCE_TYPE;
-
-typedef struct silencers {
-    int all_alarms;
-    SILENCE_TYPE stype;
-    SILENCER *silencers;
-} SILENCERS;
-
-SILENCERS *silencers;
-
-extern SILENCER *create_silencer(void);
-extern int health_silencers_json_read_callback(JSON_ENTRY *e);
-extern void health_silencers_add(SILENCER *silencer);
-extern SILENCER * health_silencers_addparam(SILENCER *silencer, char *key, char *value);
-
-#endif
diff --git a/libnetdata/json/Makefile.am b/libnetdata/json/Makefile.am
deleted file mode 100644
index 1cb69ed99a..0000000000
--- a/libnetdata/json/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-AUTOMAKE_OPTIONS = subdir-objects
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
-
-
-dist_noinst_DATA = \
-	README.md \
-	$(NULL)
diff --git a/libnetdata/json/README.md b/libnetdata/json/README.md
deleted file mode 100644
index fd6cb0f319..0000000000
--- a/libnetdata/json/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# json
-
-`json` contains a parser for json strings, based on `jsmn` (https://github.com/zserge/jsmn), but case you have installed the JSON-C library, the installation script will prefer it, you can also force its use with `--enable-jsonc` in the compilation time.
-
-[![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%2Flibnetdata%2Fjson%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
diff --git a/libnetdata/json/jsmn.c b/libnetdata/json/jsmn.c
deleted file mode 100644
index c8d9e73db9..0000000000
--- a/libnetdata/json/jsmn.c
+++ /dev/null
@@ -1,326 +0,0 @@
-#include <stdlib.h>
-
-#include "jsmn.h"
-
-/**
- * Alloc token
- *
- * Allocates a fresh unused token from the token pull.
- *
- * @param parser the controller
- * @param tokens the tokens I am working
- * @param num_tokens the number total of tokens.
- *
- * @return it returns the next token to work.
- */
-static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
-                                   jsmntok_t *tokens, size_t num_tokens) {
-    jsmntok_t *tok;
-    if (parser->toknext >= num_tokens) {
-        return NULL;
-    }
-    tok = &tokens[parser->toknext++];
-    tok->start = tok->end = -1;
-    tok->size = 0;
-#ifdef JSMN_PARENT_LINKS
-    tok->parent = -1;
-#endif
-    return tok;
-}
-
-/**
- * Fill Token
- *
- * Fills token type and boundaries.
- *
- * @param token the structure to set the values
- * @param type is the token type
- * @param start is the first position of the value
- * @param end is the end of the value
- */
-static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
-                            int start, int end) {
-    token->type = type;
-    token->start = start;
-    token->end = end;
-    token->size = 0;
-}
-
-/**
- * Parse primitive
- *
- * Fills next available token with JSON primitive.
- *
- * @param parser is the control structure
- * @param js is the json string
- * @param type is the token type
- */
-static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
-                                      size_t len, jsmntok_t *tokens, size_t num_tokens) {
-    jsmntok_t *token;
-    int start;
-
-    start = parser->pos;
-
-    for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
-        switch (js[parser->pos]) {
-#ifndef JSMN_STRICT
-            /* In strict mode primitive must be followed by "," or "}" or "]" */
-            case ':':
-#endif
-            case '\t' : case '\r' : case '\n' : case ' ' :
-            case ','  : case ']'  : case '}' :
-                goto found;
-        }
-        if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
-            parser->pos = start;
-            return JSMN_ERROR_INVAL;
-        }
-    }
-#ifdef JSMN_STRICT
-    /* In strict mode primitive must be followed by a comma/object/array */
-	parser->pos = start;
-	return JSMN_ERROR_PART;
-#endif
-
-    found:
-    if (tokens == NULL) {
-        parser->pos--;
-        return 0;
-    }
-    token = jsmn_alloc_token(parser, tokens, num_tokens);
-    if (token == NULL) {
-        parser->pos = start;
-        return JSMN_ERROR_NOMEM;
-    }
-    jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
-#ifdef JSMN_PARENT_LINKS
-    token->parent = parser->toksuper;
-#endif
-    parser->pos--;
-    return 0;
-}
-
-/**
- * Parse string
- *
- * Fills next token with JSON string.
- *
- * @param parser is the control structure
- * @param js is the json string
- * @param len is the js length
- * @param tokens is structure with the tokens mapped.
- * @param num_tokens is the total number of tokens
- *
- * @return It returns 0 on success and another integer otherwise
- */
-static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
-                                   size_t len, jsmntok_t *tokens, size_t num_tokens) {
-    jsmntok_t *token;
-
-    int start = parser->pos;
-
-    parser->pos++;
-
-    /* Skip starting quote */
-    for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
-        char c = js[parser->pos];
-
-        /* Quote: end of string */
-        if (c == '\"') {
-            if (tokens == NULL) {
-                return 0;
-            }
-            token = jsmn_alloc_token(parser, tokens, num_tokens);
-            if (token == NULL) {
-                parser->pos = start;
-                return JSMN_ERROR_NOMEM;
-            }
-            jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
-#ifdef JSMN_PARENT_LINKS
-            token->parent = parser->toksuper;
-#endif
-            return 0;
-        }
-
-        /* Backslash: Quoted symbol expected */
-        if (c == '\\') {
-            parser->pos++;
-            switch (js[parser->pos]) {
-                /* Allowed escaped symbols */
-                case '\"': case '/' : case '\\' : case 'b' :
-                case 'f' : case 'r' : case 'n'  : case 't' :
-                    break;
-                    /* Allows escaped symbol \uXXXX */
-                case 'u':
-                    parser->pos++;
-                    int i = 0;
-                    for(; i < 4 && js[parser->pos] != '\0'; i++) {
-                        /* If it isn't a hex character we have an error */
-                        if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
-                             (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
-                             (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
-                            parser->pos = start;
-                            return JSMN_ERROR_INVAL;
-                        }
-                        parser->pos++;
-                    }
-                    parser->pos--;
-                    break;
-                    /* Unexpected symbol */
-                default:
-                    parser->pos = start;
-                    return JSMN_ERROR_INVAL;
-            }
-        }
-    }
-    parser->pos = start;
-    return JSMN_ERROR_PART;
-}
-
-/**
- * JSMN Parse
- *
- * Parse JSON string and fill tokens.
- *
- * @param parser the auxiliar vector used to parser
- * @param js the string to parse
- * @param len the string length
- * @param tokens the place to map the tokens
- * @param num_tokens the number of tokens present in the tokens structure.
- *
- * @return It returns the number of tokens present in the string on success or a negative number otherwise
- */
-jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
-                     jsmntok_t *tokens, unsigned int num_tokens) {
-    jsmnerr_t r;
-    int i;
-    jsmntok_t *token;
-    int count = 0;
-
-    for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
-        char c;
-        jsmntype_t type;
-
-        c = js[parser->pos];
-        switch (c) {
-            case '{': case '[':
-                count++;
-                if (tokens == NULL) {
-                    break;
-                }
-                token = jsmn_alloc_token(parser, tokens, num_tokens);
-                if (token == NULL)
-                    return JSMN_ERROR_NOMEM;
-                if (parser->toksuper != -1) {
-                    tokens[parser->toksuper].size++;
-#ifdef JSMN_PARENT_LINKS
-                    token->parent = parser->toksuper;
-#endif
-                }
-                token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
-                token->start = parser->pos;
-                parser->toksuper = parser->toknext - 1;
-                break;
-            case '}': case ']':
-                if (tokens == NULL)
-                    break;
-                type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
-#ifdef JSMN_PARENT_LINKS
-            if (parser->toknext < 1) {
-					return JSMN_ERROR_INVAL;
-				}
-				token = &tokens[parser->toknext - 1];
-				for (;;) {
-					if (token->start != -1 && token->end == -1) {
-						if (token->type != type) {
-							return JSMN_ERROR_INVAL;
-						}
-						token->end = parser->pos + 1;
-						parser->toksuper = token->parent;
-						break;
-					}
-					if (token->parent == -1) {
-						break;
-					}
-					token = &tokens[token->parent];
-				}
-#else
-                for (i = parser->toknext - 1; i >= 0; i--) {
-                    token = &tokens[i];
-                    if (token->start != -1 && token->end == -1) {
-                        if (token->type != type) {
-                            return JSMN_ERROR_INVAL;
-                        }
-                        parser->toksuper = -1;
-                        token->end = parser->pos + 1;
-                        break;
-                    }
-                }
-                /* Error if unmatched closing bracket */
-                if (i == -1) return JSMN_ERROR_INVAL;
-                for (; i >= 0; i--) {
-                    token = &tokens[i];
-                    if (token->start != -1 && token->end == -1) {
-                        parser->toksuper = i;
-                        break;
-                    }
-                }
-#endif
-                break;
-            case '\"':
-                r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
-                if (r < 0) return r;
-                count++;
-                if (parser->toksuper != -1 && tokens != NULL)
-                    tokens[parser->toksuper].size++;
-                break;
-            case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
-                break;
-#ifdef JSMN_STRICT
-            /* In strict mode primitives are: numbers and booleans */
-			case '-': case '0': case '1' : case '2': case '3' : case '4':
-			case '5': case '6': case '7' : case '8': case '9':
-			case 't': case 'f': case 'n' :
-#else
-                /* In non-strict mode every unquoted value is a primitive */
-            default:
-#endif
-                r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
-                if (r < 0) return r;
-                count++;
-                if (parser->toksuper != -1 && tokens != NULL)
-                    tokens[parser->toksuper].size++;
-                break;
-
-#ifdef JSMN_STRICT
-            /* Unexpected char in strict mode */
-			default:
-				return JSMN_ERROR_INVAL;
-#endif
-        }
-    }
-
-    for (i = parser->toknext - 1; i >= 0; i--) {
-        /* Unmatched opened object or array */
-        if (tokens[i].start != -1 && tokens[i].end == -1) {
-            return JSMN_ERROR_PART;
-        }
-    }
-
-    return count;
-}
-
-/**
- * JSMN Init
- *
- * Creates a new parser based over a given  buffer with an array of tokens
- * available.
- *
- * @param parser is the structure with values to reset
- */
-void jsmn_init(jsmn_parser *parser) {
-    parser->pos = 0;
-    parser->toknext = 0;
-    parser->toksuper = -1;
-}
\ No newline at end of file
diff --git a/libnetdata/json/jsmn.h b/libnetdata/json/jsmn.h
deleted file mode 100644
index beff586c66..0000000000
--- a/libnetdata/json/jsmn.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef __JSMN_H_
-#define __JSMN_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-/**
- * JSON type identifier. Basic types are:
- * 	o Object
- * 	o Array
- * 	o String
- * 	o Other primitive: number, boolean (true/false) or null
- */
-typedef enum {
-    JSMN_PRIMITIVE = 0,
-    JSMN_OBJECT = 1,
-    JSMN_ARRAY = 2,
-    JSMN_STRING = 3
-} jsmntype_t;
-
-typedef enum {
-    /* Not enough tokens were provided */
-            JSMN_ERROR_NOMEM = -1,
-    /* Invalid character inside JSON string */
-            JSMN_ERROR_INVAL = -2,
-    /* The string is not a full JSON packet, more bytes expected */
-            JSMN_ERROR_PART = -3,
-} jsmnerr_t;
-
-/**
- * JSON token description.
- *
- * @param		type	type (object, array, string etc.)
- * @param		start	start position in JSON data string
- * @param		end		end position in JSON data string
- */
-typedef struct {
-    jsmntype_t type;
-    int start;
-    int end;
-    int size;
-#ifdef JSMN_PARENT_LINKS
-    int parent;
-#endif
-} jsmntok_t;
-
-/**
- * JSON parser. Contains an array of token blocks available. Also stores
- * the string being parsed now and current position in that string
- */
-typedef struct {
-    unsigned int pos; /* offset in the JSON string */
-    unsigned int toknext; /* next token to allocate */
-    int toksuper; /* superior token node, e.g parent object or array */
-} jsmn_parser;
-
-/**
- * Create JSON parser over an array of tokens
- */
-void jsmn_init(jsmn_parser *parser);
-
-/**
- * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
- * a single JSON object.
- */
-jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
-                     jsmntok_t *tokens, unsigned int num_tokens);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __JSMN_H_ */
\ No newline at end of file
diff --git a/libnetdata/json/json.c b/libnetdata/json/json.c
deleted file mode 100644
index c9ff39b056..0000000000
--- a/libnetdata/json/json.c
+++ /dev/null
@@ -1,546 +0,0 @@
-#include "jsmn.h"
-#include "../libnetdata.h"
-#include "json.h"
-#include "libnetdata/libnetdata.h"
-#include "../../health/health.h"
-
-#define JSON_TOKENS 1024
-
-int json_tokens = JSON_TOKENS;
-
-/**
- * Json Tokenise
- *
- * Map the string given inside tokens.
- *
- * @param js is the string used to create the tokens
- * @param len is the string length
- * @param count the number of tokens present in the string
- *
- * @return it returns the json parsed in tokens
- */
-#ifdef ENABLE_JSONC
-json_object *json_tokenise(char *js) {
-    if(!js) {
-        error("JSON: json string is empty.");
-        return NULL;
-    }
-
-    json_object *token = json_tokener_parse(js);
-    if(!token) {
-        error("JSON: Invalid json string.");
-        return NULL;
-    }
-
-    return token;
-}
-#else
-jsmntok_t *json_tokenise(char *js, size_t len, size_t *count)
-{
-    int n = json_tokens;
-    if(!js || !len) {
-        error("JSON: json string is empty.");
-        return NULL;
-    }
-
-    jsmn_parser parser;
-    jsmn_init(&parser);
-
-    jsmntok_t *tokens = mallocz(sizeof(jsmntok_t) * n);
-    if(!tokens) return NULL;
-
-    int ret = jsmn_parse(&parser, js, len, tokens, n);
-    while (ret == JSMN_ERROR_NOMEM) {
-        n *= 2;
-        jsmntok_t *new = reallocz(tokens, sizeof(jsmntok_t) * n);
-        if(!new) {
-            freez(tokens);
-            return NULL;
-        }
-        tokens = new;
-        ret = jsmn_parse(&parser, js, len, tokens, n);
-    }
-
-    if (ret == JSMN_ERROR_INVAL) {
-        error("JSON: Invalid json string.");
-        freez(tokens);
-        return NULL;
-    }
-    else if (ret == JSMN_ERROR_PART) {
-        error("JSON: Truncated JSON string.");
-        freez(tokens);
-        return NULL;
-    }
-
-    if(count) *count = (size_t)ret;
-
-    if(json_tokens < n) json_tokens = n;
-    return tokens;
-}
-#endif
-
-/**
- * Callback Print
- *
- * Set callback print case necesary and wrinte an information inside a buffer to write in the log.
- *
- * @param e a pointer for a structure that has the complete information about json structure.
- *
- * @return It always return 0
- */
-int json_callback_print(JSON_ENTRY *e)
-{
-    BUFFER *wb=buffer_create(300);
-
-    buffer_sprintf(wb,"%s = ", e->name);
-    char txt[50];
-    switch(e->type) {
-        case JSON_OBJECT:
-            e->callback_function = json_callback_print;
-            buffer_strcat(wb,"OBJECT");
-            break;
-
-        case JSON_ARRAY:
-            e->callback_function = json_callback_print;
-            sprintf(txt,"ARRAY[%lu]", e->data.items);
-            buffer_strcat(wb, txt);
-            break;
-
-        case JSON_STRING:
-            buffer_strcat(wb, e->data.string);
-            break;
-
-        case JSON_NUMBER:
-            sprintf(txt,"%Lf", e->data.number);
-            buffer_strcat(wb,txt);
-
-            break;
-
-        case JSON_BOOLEAN:
-            buffer_strcat(wb, e->data.boolean?"TRUE":"FALSE");
-            break;
-
-        case JSON_NULL:
-            buffer_strcat(wb,"NULL");
-            break;
-    }
-    info("JSON: %s", buffer_tostring(wb));
-    buffer_free(wb);
-    return 0;
-}
-
-/**
- * JSONC Set String
- *
- * Set the string value of the structure JSON_ENTRY.
- *
- * @param e the output structure
- */
-static inline void json_jsonc_set_string(JSON_ENTRY *e,char *key,const char *value) {
-    size_t length = strlen(key);
-    e->type = JSON_STRING;
-    memcpy(e->name,key,length);
-    e->name[length] = 0x00;
-    e->data.string = (char *) value;
-}
-
-
-#ifdef ENABLE_JSONC
-/**
- * JSONC set Boolean
- *
- * Set the boolean value of the structure JSON_ENTRY
- *
- * @param e the output structure
- * @param value the input value
- */
-static inline void json_jsonc_set_boolean(JSON_ENTRY *e,int value) {
-    e->type = JSON_BOOLEAN;
-    e->data.boolean = value;
-}
-
-/**
- * Parse Array
- *
- * Parse the array object.
- *
- * @param ptr the pointer for the object that we will parse.
- * @param callback_data additional data to be used together the callback function
- * @param callback_function function used to create a silencer.
- */
-static inline void json_jsonc_parse_array(json_object *ptr, void *callback_data,int (*callback_function)(struct json_entry *)) {
-    int end = json_object_array_length(ptr);
-    JSON_ENTRY e;
-
-    if(end) {
-        int i;
-        i = 0;
-
-        enum json_type type;
-        do {
-            json_object *jvalue =  json_object_array_get_idx(ptr, i);
-            if(jvalue) {
-                e.callback_data = callback_data;
-                e.type = JSON_OBJECT;
-                callback_function(&e);
-                json_object_object_foreach(jvalue, key, val) {
-                    type = json_object_get_type(val);
-                    if (type == json_type_array) {
-                        e.type = JSON_ARRAY;
-                        json_jsonc_parse_array(val, callback_data, callback_function);
-                    } else if (type == json_type_object) {
-                        json_walk(val,callback_data,callback_function);
-                    } else if (type == json_type_string) {
-                        json_jsonc_set_string(&e,key,json_object_get_string(val));
-                        callback_function(&e);
-                    } else if (type == json_type_boolean) {
-                        json_jsonc_set_boolean(&e,json_object_get_boolean(val));
-                        callback_function(&e);
-                    }
-                }
-            }
-
-        } while (++i < end);
-    }
-}
-#else
-
-/**
- * Walk string
- *
- * Set JSON_ENTRY to string and map the values from jsmntok_t.
- *
- * @param js the original string
- * @param t the tokens
- * @param start the first position
- * @param e the output structure.
- *
- * @return It always return 1
- */
-size_t json_walk_string(char *js, jsmntok_t *t, size_t start, JSON_ENTRY *e)
-{
-    char old = js[t[start].end];
-    js[t[start].end] = '\0';
-    e->original_string = &js[t[start].start];
-
-    e->type = JSON_STRING;
-    e->data.string = e->original_string;
-    if(e->callback_function) e->callback_function(e);
-    js[t[start].end] = old;
-    return 1;
-}
-
-/**
- * Walk Primitive
- *
- * Define the data type of the string
- *
- * @param js the original string
- * @param t the tokens
- * @param start the first position
- * @param e the output structure.
- *
- * @return It always return 1
- */
-size_t json_walk_primitive(char *js, jsmntok_t *t, size_t start, JSON_ENTRY *e)
-{
-    char old = js[t[start].end];
-    js[t[start].end] = '\0';
-    e->original_string = &js[t[start].start];
-
-    switch(e->original_string[0]) {
-        case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
-        case '8': case '9': case '-': case '.':
-            e->type = JSON_NUMBER;
-            e->data.number = strtold(e->original_string, NULL);
-            break;
-
-        case 't': case 'T':
-            e->type = JSON_BOOLEAN;
-            e->data.boolean = 1;
-            break;
-
-        case 'f': case 'F':
-            e->type = JSON_BOOLEAN;
-            e->data.boolean = 0;
-            break;
-
-        case 'n': case 'N':
-        default:
-            e->type = JSON_NULL;
-            break;
-    }
-    if(e->callback_function) e->callback_function(e);
-    js[t[start].end] = old;
-    return 1;
-}
-
-/**
- * Array
- *
- * Measure the array length
- *
- * @param js the original string
- * @param t the tokens
- * @param nest the length of structure t
- * @param start the first position
- * @param e the output structure.
- *
- * @return It returns the array length
- */
-size_t json_walk_array(char *js, jsmntok_t *t, size_t nest, size_t start, JSON_ENTRY *e)
-{
-    JSON_ENTRY ne = {
-            .name = "",
-            .fullname = "",
-            .callback_data = NULL,
-            .callback_function = NULL
-    };
-
-    char old = js[t[start].end];
-    js[t[start].end] = '\0';
-    ne.original_string = &js[t[start].start];
-
-    memcpy(&ne, e, sizeof(JSON_ENTRY));
-    ne.type = JSON_ARRAY;
-    ne.data.items = t[start].size;
-    ne.callback_function = NULL;
-    ne.name[0]='\0';
-    ne.fullname[0]='\0';
-    if(e->callback_function) e->callback_function(&ne);
-    js[t[start].end] = old;
-
-    size_t i, init = start, size = t[start].size;
-
-    start++;
-    for(i = 0; i < size ; i++) {
-        ne.pos = i;
-        if (!e->name || !e->fullname || strlen(e->name) > JSON_NAME_LEN  - 24 || strlen(e->fullname) > JSON_FULLNAME_LEN -24) {
-            info("JSON: JSON walk_array ignoring element with name:%s fullname:%s",e->name, e->fullname);
-            continue;
-        }
-        sprintf(ne.name, "%s[%lu]", e->name, i);
-        sprintf(ne.fullname, "%s[%lu]", e->fullname, i);
-
-        switch(t[start].type) {
-            case JSMN_PRIMITIVE:
-                start += json_walk_primitive(js, t, start, &ne);
-                break;
-
-            case JSMN_OBJECT:
-                start += json_walk_object(js, t, nest + 1, start, &ne);
-                break;
-
-            case JSMN_ARRAY:
-                start += json_walk_array(js, t, nest + 1, start, &ne);
-                break;
-
-            case JSMN_STRING:
-                start += json_walk_string(js, t, start, &ne);
-                break;
-        }
-    }
-    return start - init;
-}
-
-/**
- * Object
- *
- * Measure the Object length
- *
- * @param js the original string
- * @param t the tokens
- * @param nest the length of structure t
- * @param start the first position
- * @param e the output structure.
- *
- * @return It returns the Object length
- */
-size_t json_walk_object(char *js, jsmntok_t *t, size_t nest, size_t start, JSON_ENTRY *e)
-{
-    JSON_ENTRY ne = {
-            .name = "",
-            .fullname = "",
-            .callback_data = NULL,
-            .callback_function = NULL
-    };
-
-    char old = js[t[start].end];
-    js[t[start].end] = '\0';
-    ne.original_string = &js[t[start].start];
-    memcpy(&ne, e, sizeof(JSON_ENTRY));
-    ne.type = JSON_OBJECT;
-    ne.callback_function = NULL;
-    if(e->callback_function) e->callback_function(&ne);
-    js[t[start].end] = old;
-
-    int key = 1;
-    size_t i, init = start, size = t[start].size;
-
-    start++;
-    for(i = 0; i < size ; i++) {
-        switch(t[start].type) {
-            case JSMN_PRIMITIVE:
-                start += json_walk_primitive(js, t, start, &ne);
-                key = 1;
-                break;
-
-            case JSMN_OBJECT:
-                start += json_walk_object(js, t, nest + 1, start, &ne);
-                key = 1;
-                break;
-
-            case JSMN_ARRAY:
-                start += json_walk_array(js, t, nest + 1, start, &ne);
-                key = 1;
-                break;
-
-            case JSMN_STRING:
-            default:
-                if(key) {
-                    int len = t[start].end - t[start].start;
-                    if (unlikely(len>JSON_NAME_LEN)) len=JSON_NAME_LEN;
-                    strncpy(ne.name, &js[t[start].start], len);
-                    ne.name[len] = '\0';
-                    len=strlen(e->fullname) + strlen(e->fullname[0]?".":"") + strlen(ne.name);
-                    char *c = mallocz((len+1)*sizeof(char));
-                    sprintf(c,"%s%s%s", e->fullname, e->fullname[0]?".":"", ne.name);
-                    if (unlikely(len>JSON_FULLNAME_LEN)) len=JSON_FULLNAME_LEN;
-                    strncpy(ne.fullname, c, len);
-                    freez(c);
-                    start++;
-                    key = 0;
-                }
-                else {
-                    start += json_walk_string(js, t, start, &ne);
-                    key = 1;
-                }
-                break;
-        }
-    }
-    return start - init;
-}
-#endif
-
-/**
- * Tree
- *
- * Call the correct walk function according its type.
- *
- * @param t the json object to work
- * @param callback_data additional data to be used together the callback function
- * @param callback_function function used to create a silencer.
- *
- * @return It always return 1
- */
-#ifdef ENABLE_JSONC
-size_t json_walk(json_object *t, void *callback_data, int (*callback_function)(struct json_entry *)) {
-    JSON_ENTRY e;
-
-    e.callback_data = callback_data;
-    enum json_type type;
-    json_object_object_foreach(t, key, val) {
-        type = json_object_get_type(val);
-        if (type == json_type_array) {
-            e.type = JSON_ARRAY;
-            json_jsonc_parse_array(val,NULL,health_silencers_json_read_callback);
-        } else if (type == json_type_object) {
-            e.type = JSON_OBJECT;
-        } else if (type == json_type_string) {
-            json_jsonc_set_string(&e,key,json_object_get_string(val));
-            callback_function(&e);
-        } else if (type == json_type_boolean) {
-            json_jsonc_set_boolean(&e,json_object_get_boolean(val));
-            callback_function(&e);
-        }
-    }
-
-    return 1;
-}
-#else
-/**
- * Tree
- *
- * Call the correct walk function according its type.
- *
- * @param js the original string
- * @param t the tokens
- * @param callback_data additional data to be used together the callback function
- * @param callback_function function used to create a silencer.
- *
- * @return It always return 1
- */
-size_t json_walk_tree(char *js, jsmntok_t *t, void *callback_data, int (*callback_function)(struct json_entry *))
-{
-    JSON_ENTRY e = {
-            .name = "",
-            .fullname = "",
-            .callback_data = callback_data,
-            .callback_function = callback_function
-    };
-
-    switch (t[0].type) {
-        case JSMN_OBJECT:
-            e.type = JSON_OBJECT;
-            json_walk_object(js, t, 0, 0, &e);
-            break;
-
-        case JSMN_ARRAY:
-            e.type = JSON_ARRAY;
-            json_walk_array(js, t, 0, 0, &e);
-            break;
-
-        case JSMN_PRIMITIVE:
-        case JSMN_STRING:
-            break;
-    }
-
-    return 1;
-}
-#endif
-
-/**
- * JSON Parse
- *
- * Parse the json message with the callback function
- *
- * @param js the string that the callback function will parse
- * @param callback_data additional data to be used together the callback function
- * @param callback_function function used to create a silencer.
- *
- * @return JSON_OK  case everything happend as expected, JSON_CANNOT_PARSE case there were errors in the
- * parsing procces and JSON_CANNOT_DOWNLOAD case the string given(js) is NULL.
- */
-int json_parse(char *js, void *callback_data, int (*callback_function)(JSON_ENTRY *))
-{
-    if(js) {
-#ifdef ENABLE_JSONC
-        json_object *tokens = json_tokenise(js);
-#else
-        size_t count;
-        jsmntok_t *tokens = json_tokenise(js, strlen(js), &count);
-#endif
-
-        if(tokens) {
-#ifdef ENABLE_JSONC
-            json_walk(tokens, callback_data, callback_function);
-            json_object_put(tokens);
-#else
-            json_walk_tree(js, tokens, callback_data, callback_function);
-            freez(tokens);
-#endif
-            return JSON_OK;
-        }
-
-        return JSON_CANNOT_PARSE;
-    }
-
-    return JSON_CANNOT_DOWNLOAD;
-}
-
-/*
-int json_test(char *str)
-{
-    return json_parse(str, NULL, json_callback_print);
-}
- */
\ No newline at end of file
diff --git a/libnetdata/json/json.h b/libnetdata/json/json.h
deleted file mode 100644
index 79b58b1704..0000000000
--- a/libnetdata/json/json.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef CHECKIN_JSON_H
-#define CHECKIN_JSON_H 1
-
-
-#if ENABLE_JSONC
-# include <json-c/json.h>
-#endif
-
-#include "jsmn.h"
-
-//https://www.ibm.com/support/knowledgecenter/en/SS9H2Y_7.6.0/com.ibm.dp.doc/json_parserlimits.html
-#define JSON_NAME_LEN 256
-#define JSON_FULLNAME_LEN 1024
-
-typedef enum {
-    JSON_OBJECT = 0,
-    JSON_ARRAY = 1,
-    JSON_STRING = 2,
-    JSON_NUMBER = 3,
-    JSON_BOOLEAN = 4,
-    JSON_NULL = 5,
-} JSON_ENTRY_TYPE;
-
-typedef struct json_entry {
-    JSON_ENTRY_TYPE type;
-    char name[JSON_NAME_LEN + 1];
-    char fullname[JSON_FULLNAME_LEN + 1];
-    union {
-        char *string;			// type == JSON_STRING
-        long double number;		// type == JSON_NUMBER
-        int boolean;			// type == JSON_BOOLEAN
-        size_t items;			// type == JSON_ARRAY
-    } data;
-    size_t pos;					// the position of this item in its parent
-
-    char *original_string;
-
-    void *callback_data;
-    int (*callback_function)(struct json_entry *);
-} JSON_ENTRY;
-
-// ----------------------------------------------------------------------------
-// public functions
-
-#define JSON_OK 				0
-#define JSON_CANNOT_DOWNLOAD 	1
-#define JSON_CANNOT_PARSE		2
-
-int json_parse(char *js, void *callback_data, int (*callback_function)(JSON_ENTRY *));
-
-
-// ----------------------------------------------------------------------------
-// private functions
-
-#ifdef ENABLE_JSONC
-json_object *json_tokenise(char *js);
-size_t json_walk(json_object *t, void *callback_data, int (*callback_function)(struct json_entry *));
-#else
-jsmntok_t *json_tokenise(char *js, size_t len, size_t *count);
-size_t json_walk_tree(char *js, jsmntok_t *t, void *callback_data, int (*callback_function)(struct json_entry *));
-#endif
-
-size_t json_walk_object(char *js, jsmntok_t *t, size_t nest, size_t start, JSON_ENTRY *e);
-size_t json_walk_array(char *js, jsmntok_t *t, size_t nest, size_t start, JSON_ENTRY *e);
-size_t json_walk_string(char *js, jsmntok_t *t, size_t start, JSON_ENTRY *e);
-size_t json_walk_primitive(char *js, jsmntok_t *t, size_t start, JSON_ENTRY *e);
-
-int json_callback_print(JSON_ENTRY *e);
-
-
-
-#endif
\ No newline at end of file
diff --git a/libnetdata/libnetdata.h b/libnetdata/libnetdata.h
index 43dc1e04dc..41642efd25 100644
--- a/libnetdata/libnetdata.h
+++ b/libnetdata/libnetdata.h
@@ -310,7 +310,5 @@ extern char *netdata_configured_host_prefix;
 #include "statistical/statistical.h"
 #include "adaptive_resortable_list/adaptive_resortable_list.h"
 #include "url/url.h"
-#include "json/json.h"
-#include "health/health.h"
 
 #endif // NETDATA_LIB_H
diff --git a/netdata-installer.sh b/netdata-installer.sh
index 9c4d8a76d7..a0c3f828a4 100755
--- a/netdata-installer.sh
+++ b/netdata-installer.sh
@@ -175,7 +175,6 @@ USAGE: ${PROGRAM} [options]
   --libs-are-really-here     If you get errors about missing zlib or libuuid but you know it is available, you might
                              have a broken pkg-config. Use this option to proceed without checking pkg-config.
   --disable-telemetry        Use this flag to opt-out from our anonymous telemetry progam.
-  --enable-json              Enable to use JSON-C library instead the internal Netdata library.
 
 Netdata will by default be compiled with gcc optimization -O2
 If you need to pass different CFLAGS, use something like this:
@@ -223,7 +222,6 @@ while [ -n "${1}" ]; do
 		"--disable-x86-sse") NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--disable-x86-sse/} --disable-x86-sse";;
 		"--disable-telemetry") NETDATA_DISABLE_TELEMETRY=1;;
 		"--disable-go") NETDATA_DISABLE_GO=1;;
-		"--enable-jsonc") NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--enable-jsonc/} --enable-jsonc";;
 		"--install")
 			NETDATA_PREFIX="${2}/netdata"
 			shift 1
diff --git a/tests/health_mgmtapi/expected_list/ALARM_CPU_IOWAIT-list.json b/tests/health_mgmtapi/expected_list/ALARM_CPU_IOWAIT-list.json
deleted file mode 100644
index 9f05efe70e..0000000000
--- a/tests/health_mgmtapi/expected_list/ALARM_CPU_IOWAIT-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "alarm": "*10min_cpu_iowait" }, { "alarm": "*10min_cpu_usage *load_trigger" } ] }
diff --git a/tests/health_mgmtapi/expected_list/ALARM_CPU_USAGE-list.json b/tests/health_mgmtapi/expected_list/ALARM_CPU_USAGE-list.json
deleted file mode 100644
index dbf8799252..0000000000
--- a/tests/health_mgmtapi/expected_list/ALARM_CPU_USAGE-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "alarm": "*10min_cpu_usage *load_trigger", "context": "system.cpu" }, { "alarm": "*10min_cpu_usage *load_trigger", "chart": "system.load" } ] }
diff --git a/tests/health_mgmtapi/expected_list/CONTEXT_SYSTEM_CPU-list.json b/tests/health_mgmtapi/expected_list/CONTEXT_SYSTEM_CPU-list.json
deleted file mode 100644
index a267cfd6fc..0000000000
--- a/tests/health_mgmtapi/expected_list/CONTEXT_SYSTEM_CPU-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "DISABLE", "silencers": [ { "context": "system.cpu" }, { "chart": "system.load" } ] }
diff --git a/tests/health_mgmtapi/expected_list/DISABLE-list.json b/tests/health_mgmtapi/expected_list/DISABLE-list.json
deleted file mode 100644
index c2c7781043..0000000000
--- a/tests/health_mgmtapi/expected_list/DISABLE-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "DISABLE", "silencers": [ { "alarm": "*10min_cpu_usage *load_trigger" } ] }
diff --git a/tests/health_mgmtapi/expected_list/DISABLE_ALL-list.json b/tests/health_mgmtapi/expected_list/DISABLE_ALL-list.json
deleted file mode 100644
index bbc3f4f0c9..0000000000
--- a/tests/health_mgmtapi/expected_list/DISABLE_ALL-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": true, "type": "DISABLE", "silencers": [] }
diff --git a/tests/health_mgmtapi/expected_list/DISABLE_ALL_ERROR-list.json b/tests/health_mgmtapi/expected_list/DISABLE_ALL_ERROR-list.json
deleted file mode 100644
index e8aee17953..0000000000
--- a/tests/health_mgmtapi/expected_list/DISABLE_ALL_ERROR-list.json
+++ /dev/null
@@ -1 +0,0 @@
-Auth Error
diff --git a/tests/health_mgmtapi/expected_list/DISABLE_SYSTEM_LOAD-list.json b/tests/health_mgmtapi/expected_list/DISABLE_SYSTEM_LOAD-list.json
deleted file mode 100644
index a7fc1cb8ac..0000000000
--- a/tests/health_mgmtapi/expected_list/DISABLE_SYSTEM_LOAD-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "DISABLE", "silencers": [ { "chart": "system.load" } ] }
diff --git a/tests/health_mgmtapi/expected_list/FAMILIES_LOAD-list.json b/tests/health_mgmtapi/expected_list/FAMILIES_LOAD-list.json
deleted file mode 100644
index 50119f79c3..0000000000
--- a/tests/health_mgmtapi/expected_list/FAMILIES_LOAD-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "None", "silencers": [ { "families": "load" } ] }
diff --git a/tests/health_mgmtapi/expected_list/HOSTS-list.json b/tests/health_mgmtapi/expected_list/HOSTS-list.json
deleted file mode 100644
index 9db21b6c34..0000000000
--- a/tests/health_mgmtapi/expected_list/HOSTS-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "hosts": "*" } ] }
diff --git a/tests/health_mgmtapi/expected_list/RESET-list.json b/tests/health_mgmtapi/expected_list/RESET-list.json
deleted file mode 100644
index 2d3f09d682..0000000000
--- a/tests/health_mgmtapi/expected_list/RESET-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "None", "silencers": [] }
diff --git a/tests/health_mgmtapi/expected_list/SILENCE-list.json b/tests/health_mgmtapi/expected_list/SILENCE-list.json
deleted file mode 100644
index d157f2d3af..0000000000
--- a/tests/health_mgmtapi/expected_list/SILENCE-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "alarm": "*10min_cpu_usage *load_trigger" } ] }
diff --git a/tests/health_mgmtapi/expected_list/SILENCE_2-list.json b/tests/health_mgmtapi/expected_list/SILENCE_2-list.json
deleted file mode 100644
index d5e6fa2d14..0000000000
--- a/tests/health_mgmtapi/expected_list/SILENCE_2-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "families": "load" } ] }
diff --git a/tests/health_mgmtapi/expected_list/SILENCE_3-list.json b/tests/health_mgmtapi/expected_list/SILENCE_3-list.json
deleted file mode 100644
index 69e98cc19b..0000000000
--- a/tests/health_mgmtapi/expected_list/SILENCE_3-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [] } WARNING: SILENCE or DISABLE command is ineffective without defining any alarm selectors.
diff --git a/tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE-list.json b/tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE-list.json
deleted file mode 100644
index dd789cd336..0000000000
--- a/tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "alarm": "*10min_cpu_usage *load_trigger", "chart": "system.load" } ] }
diff --git a/tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE_LOAD_TRIGGER-list.json b/tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE_LOAD_TRIGGER-list.json
deleted file mode 100644
index d157f2d3af..0000000000
--- a/tests/health_mgmtapi/expected_list/SILENCE_ALARM_CPU_USAGE_LOAD_TRIGGER-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": false, "type": "SILENCE", "silencers": [ { "alarm": "*10min_cpu_usage *load_trigger" } ] }
diff --git a/tests/health_mgmtapi/expected_list/SILENCE_ALL-list.json b/tests/health_mgmtapi/expected_list/SILENCE_ALL-list.json
deleted file mode 100644
index c88ef9fde9..0000000000
--- a/tests/health_mgmtapi/expected_list/SILENCE_ALL-list.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "all": true, "type": "SILENCE", "silencers": [] }
diff --git a/tests/health_mgmtapi/health-cmdapi-test.sh.in b/tests/health_mgmtapi/health-cmdapi-test.sh.in
index 5abf2b1704..26279cac97 100755
--- a/tests/health_mgmtapi/health-cmdapi-test.sh.in
+++ b/tests/health_mgmtapi/health-cmdapi-test.sh.in
@@ -27,7 +27,7 @@ check () {
 	elif [ "${r}" != "${2}" ] ; then
 		echo -e "  ${GRAY}WARNING: 'Got ${r}'. Expected '${2}'"
 		iter=$((iter+1))
-		if [ $iter -lt 10 ] ; then
+		if [ $iter -lt 10 ] ; then 
 			echo -e "  ${GRAY}Repeating test "
 			check "$1" "$2"
 		else
@@ -53,20 +53,6 @@ cmd () {
 	fi
 }
 
-check_list() {
-    RESPONSE=$(curl -s "http://$URL/api/v1/manage/health?cmd=LIST" -H "X-Auth-Token: $TOKEN" 2>&1)
-
-    NAME="$1-list.json"
-    echo $RESPONSE > $NAME
-    diff $NAME expected_list/$NAME 1>/dev/null 2>&1
-    if [ $? -eq 0 ]; then
-        echo -e "${GREEN}Success: The list command got the correct answer for $NAME!"
-    else
-        echo -e "${RED}ERROR: the files $NAME and expected_list/$NAME does not match."
-        exit 1
-    fi
-}
-
 WHITE='\033[0;37m'
 RED='\033[0;31m'
 GREEN='\033[0;32m'
@@ -104,13 +90,11 @@ err=0
 	# Test default state
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
 	check "Default State" "False False False False False False"
-	check_list "RESET"
 
 	# Test auth failure
 	TOKEN="Wrong token"
 	cmd "cmd=DISABLE ALL" "$HEALTH_CMDAPI_MSG_AUTHERROR"
 	check "Default State" "False False False False False False"
-	check_list "DISABLE_ALL_ERROR"
 
 	# Set correct token
 	TOKEN="${CORRECT_TOKEN}"
@@ -118,107 +102,87 @@ err=0
 	# Test disable
 	cmd "cmd=DISABLE ALL" "$HEALTH_CMDAPI_MSG_DISABLEALL"
 	check "All disabled" "True False True False True False"
-	check_list "DISABLE_ALL"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
 	check "Default State" "False False False False False False"
-	check_list "RESET"
 
 	# Test silence
 	cmd "cmd=SILENCE ALL" "$HEALTH_CMDAPI_MSG_SILENCEALL"
 	check "All silenced" "False True False True False True"
-	check_list "SILENCE_ALL"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
 	check "Default State" "False False False False False False"
-	check_list "RESET"
 
 	# Add silencer by name
 	printf -v resp "$HEALTH_CMDAPI_MSG_SILENCE\n$HEALTH_CMDAPI_MSG_ADDED"
 	cmd "cmd=SILENCE&alarm=*10min_cpu_usage *load_trigger" "${resp}"
 	check "Silence notifications for alarm1 and load_trigger" "False True False False False True"
-	check_list "SILENCE_ALARM_CPU_USAGE_LOAD_TRIGGER"
 
 	# Convert to disable health checks
 	cmd "cmd=DISABLE" "$HEALTH_CMDAPI_MSG_DISABLE"
 	check "Disable notifications for alarm1 and load_trigger" "True False False False True False"
-	check_list "DISABLE"
 
 	# Convert back to silence notifications
 	cmd "cmd=SILENCE" "$HEALTH_CMDAPI_MSG_SILENCE"
 	check "Silence notifications for alarm1 and load_trigger" "False True False False False True"
-	check_list "SILENCE"
 
 	# Add second silencer by name
 	cmd "alarm=*10min_cpu_iowait" "$HEALTH_CMDAPI_MSG_ADDED"
 	check "Silence notifications for alarm1,alarm2 and load_trigger" "False True False True False True"
-	check_list "ALARM_CPU_IOWAIT"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
-	check_list "RESET"
 
 	# Add silencer by chart
 	printf -v resp "$HEALTH_CMDAPI_MSG_DISABLE\n$HEALTH_CMDAPI_MSG_ADDED"
 	cmd "cmd=DISABLE&chart=system.load" "${resp}"
 	check "Default State" "False False False False True False"
-	check_list "DISABLE_SYSTEM_LOAD"
 
 	# Add silencer by context
 	cmd "context=system.cpu" "$HEALTH_CMDAPI_MSG_ADDED"
 	check "Default State" "True False True False True False"
-	check_list "CONTEXT_SYSTEM_CPU"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
-	check_list "RESET"
 
 	# Add second condition to a selector (AND)
 	printf -v resp "$HEALTH_CMDAPI_MSG_SILENCE\n$HEALTH_CMDAPI_MSG_ADDED"
 	cmd "cmd=SILENCE&alarm=*10min_cpu_usage *load_trigger&chart=system.load" "${resp}"
 	check "Silence notifications load_trigger" "False False False False False True"
-	check_list "SILENCE_ALARM_CPU_USAGE"
 
 	# Add second selector with two conditions
 	cmd "alarm=*10min_cpu_usage *load_trigger&context=system.cpu" "$HEALTH_CMDAPI_MSG_ADDED"
 	check "Silence notifications load_trigger" "False True False False False True"
-	check_list "ALARM_CPU_USAGE"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
-	check_list "RESET"
 
 	# Add silencer without a command to disable or silence alarms
 	printf -v resp "$HEALTH_CMDAPI_MSG_ADDED\n$HEALTH_CMDAPI_MSG_STYPEWARNING"
 	cmd "families=load" "${resp}"
 	check "Family selector with no command" "False False False False False False"
-	check_list "FAMILIES_LOAD"
 
 	# Add silence command
 	cmd "cmd=SILENCE" "$HEALTH_CMDAPI_MSG_SILENCE"
 	check "Silence family load" "False False False False False True"
-	check_list "SILENCE_2"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
-	check_list "RESET"
 
 	# Add command without silencers
 	printf -v resp "$HEALTH_CMDAPI_MSG_SILENCE\n$HEALTH_CMDAPI_MSG_NOSELECTORWARNING"
 	cmd "cmd=SILENCE" "${resp}"
 	check "Command with no selector" "False False False False False False"
-	check_list "SILENCE_3"
 
 	# Add hosts silencer
 	cmd "hosts=*" "$HEALTH_CMDAPI_MSG_ADDED"
 	check "Silence all hosts" "False True False True False True"
-	check_list "HOSTS"
 
 	# Reset
 	cmd "cmd=RESET" "$HEALTH_CMDAPI_MSG_RESET"
-	check_list "RESET"
+
 
 if [ $err -gt 0 ] ; then
 	echo "$err error(s) found"
diff --git a/web/api/health/README.md b/web/api/health/README.md
index cc66e82bda..2003a61e04 100644
--- a/web/api/health/README.md
+++ b/web/api/health/README.md
@@ -45,7 +45,6 @@ The following will return an SVG badge of the alarm named `NAME`, attached to th
 ## Health Management API
 
 Netdata v1.12 and beyond provides a command API to control health checks and notifications at runtime. The feature is especially useful for maintenance periods, during which you receive meaningless alarms.
-From Netdata v1.16.0 and beyond, the configuration controlled via the API commands is [persisted across netdata restarts](#persistence).
 
 Specifically, the API allows you to:
  - Disable health checks completely. Alarm conditions will not be evaluated at all and no entries will be added to the alarm log.
@@ -143,43 +142,6 @@ Example 2.2: Add one more selector, to also silence alarms for cpu1 and cpu2
 http://localhost/api/v1/manage/health?families=cpu1 cpu2
 ```
 
-### List silencers
-
-The command `LIST` was added in netdata v1.16.0 and returns a JSON with the current status of the silencers.
-
-```
- curl "http://myserver/api/v1/manage/health?cmd=LIST" -H "X-Auth-Token: Mytoken"
-```
-
-As an example, the following response shows that we have two silencers configured, one for an alarm called `samplealarm` and one for alarms with context `random` on host `myhost`
-```
-json
-{
-	"all": false,
-	"type": "SILENCE",
-	"silencers": [
-		{
-			"alarm": "samplealarm"
-		},
-		{
-			"context": "random",
-			"hosts": "myhost"
-		}
-	]
-}
-```
-
-The response below shows that we have disabled all health checks.
-
-```
-json
-{
-	"all": true,
-	"type": "DISABLE",
-	"silencers": []
-}
-```
-
 ### Responses
 
 - "Auth Error" : Token authentication failed
@@ -189,21 +151,10 @@ json
 - "Health checks disabled for alarms matching the selectors" : Added to the response for a cmd=DISABLE
 - "Alarm notifications silenced for alarms matching the selectors" : Added to the response for a cmd=SILENCE
 - "Alarm selector added" : Added to the response when a new selector is added
+- "Invalid key. Ignoring it." : Wrong name of a parameter. Added to the response and ignored.
 - "WARNING: Added alarm selector to silence/disable alarms without a SILENCE or DISABLE command." : Added to the response if a selector is added without a selector-specific command.
 - "WARNING: SILENCE or DISABLE command is ineffective without defining any alarm selectors." : Added to the response if a selector-specific command is issued without a selector.
 
-### Persistence
-
-From netdata v1.13.1 and beyond, the silencers configuration is persisted to disk and loaded when netdata starts.
-The JSON string returned by the [LIST command](#list-silencers) is automatically saved to the `silencers file`, every time a command alters the silencers configuration.
-The file's location is configurable in `netdata.conf`. The default is shown below:
-
-```
-[health]
-	# silencers file = /var/lib/netdata/health.silencers.json
-```
-
-
 ### Further reading
 
 The test script under [tests/health_mgmtapi](../../../tests/health_mgmtapi) contains a series of tests that you can either run or read through to understand the various calls and responses better.
diff --git a/web/api/health/health_cmdapi.c b/web/api/health/health_cmdapi.c
index 5fa0073808..ec177751b9 100644
--- a/web/api/health/health_cmdapi.c
+++ b/web/api/health/health_cmdapi.c
@@ -1,16 +1,17 @@
 //
-// Created by Christopher on 11/12/18.
+// Created by christopher on 11/12/18.
 //
 
 #include "health_cmdapi.h"
 
-/**
- * Free Silencers
- *
- * Clean the silencer structure
- *
- * @param t is the structure that will be cleaned.
- */
+
+static SILENCER *create_silencer(void) {
+    SILENCER *t = callocz(1, sizeof(SILENCER));
+    debug(D_HEALTH, "HEALTH command API: Created empty silencer");
+
+    return t;
+}
+
 void free_silencers(SILENCER *t) {
     if (!t) return;
     if (t->next) free_silencers(t->next);
@@ -30,104 +31,38 @@ void free_silencers(SILENCER *t) {
     return;
 }
 
-/**
- * Silencers to JSON Entry
- *
- * Fill the buffer with the other values given.
- *
- * @param wb a pointer to the output buffer
- * @param var the json variable
- * @param val the json value
- * @param hasprev has it a previous value?
- *
- * @return
- */
-int health_silencers2json_entry(BUFFER *wb, char* var, char* val, int hasprev) {
-    if (val) {
-        buffer_sprintf(wb, "%s\n\t\t\t\"%s\": \"%s\"", (hasprev)?",":"", var, val);
-        return 1;
-    } else {
-        return hasprev;
-    }
-}
 
-/**
- * Silencer to JSON
- *
- * Write the silencer values using JSON format inside a buffer.
- *
- * @param wb is the buffer to write the silencers.
- */
-void health_silencers2json(BUFFER *wb) {
-    buffer_sprintf(wb, "{\n\t\"all\": %s,"
-                       "\n\t\"type\": \"%s\","
-                       "\n\t\"silencers\": [",
-                   (silencers->all_alarms)?"true":"false",
-                   (silencers->stype == STYPE_NONE)?"None":((silencers->stype == STYPE_DISABLE_ALARMS)?"DISABLE":"SILENCE"));
 
-    SILENCER *silencer;
-    int i = 0, j = 0;
-    for(silencer = silencers->silencers; silencer ; silencer = silencer->next) {
-        if(likely(i)) buffer_strcat(wb, ",");
-        buffer_strcat(wb, "\n\t\t{");
-        j=health_silencers2json_entry(wb, HEALTH_ALARM_KEY, silencer->alarms, j);
-        j=health_silencers2json_entry(wb, HEALTH_CHART_KEY, silencer->charts, j);
-        j=health_silencers2json_entry(wb, HEALTH_CONTEXT_KEY, silencer->contexts, j);
-        j=health_silencers2json_entry(wb, HEALTH_HOST_KEY, silencer->hosts, j);
-        health_silencers2json_entry(wb, HEALTH_FAMILIES_KEY, silencer->families, j);
-        j=0;
-        buffer_strcat(wb, "\n\t\t}");
-        i++;
-    }
-    if(likely(i)) buffer_strcat(wb, "\n\t");
-    buffer_strcat(wb, "]\n}\n");
-}
-
-/**
- * Silencer to FILE
- *
- * Write the sliencer buffer to a file.
- * @param wb
- */
-void health_silencers2file(BUFFER *wb) {
-    if (wb->len == 0) return;
-
-    FILE *fd = fopen(silencers_filename, "wb");
-    if(fd) {
-        size_t written = (size_t)fprintf(fd, "%s", wb->buffer) ;
-        if (written == wb->len ) {
-            info("Silencer changes written to %s", silencers_filename);
-        }
-        fclose(fd);
-        return;
-    }
-    error("Silencer changes could not be written to %s. Error %s", silencers_filename, strerror(errno));
-}
-
-/**
- * Request V1 MGMT Health
- *
- * Function called by api to management the health.
- *
- * @param host main structure with client information!
- * @param w is the structure with all information of the client request.
- * @param url is the url that netdata is working
- *
- * @return It returns 200 on success and another code otherwise.
- */
 int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, char *url) {
     int ret = 400;
     (void) host;
 
+
+
     BUFFER *wb = w->response.data;
     buffer_flush(wb);
     wb->contenttype = CT_TEXT_PLAIN;
 
     buffer_flush(w->response.data);
 
-    //Local instance of the silencer
+    static uint32_t
+            hash_alarm = 0,
+            hash_template = 0,
+            hash_chart = 0,
+            hash_context = 0,
+            hash_host = 0,
+            hash_families = 0;
+
+    if (unlikely(!hash_alarm)) {
+        hash_alarm = simple_uhash(HEALTH_ALARM_KEY);
+        hash_template = simple_uhash(HEALTH_TEMPLATE_KEY);
+        hash_chart = simple_uhash(HEALTH_CHART_KEY);
+        hash_context = simple_uhash(HEALTH_CONTEXT_KEY);
+        hash_host = simple_uhash(HEALTH_HOST_KEY);
+        hash_families = simple_uhash(HEALTH_FAMILIES_KEY);
+    }
+
     SILENCER *silencer = NULL;
-    int config_changed = 1;
 
     if (!w->auth_bearer_token) {
         buffer_strcat(wb, HEALTH_CMDAPI_MSG_AUTHERROR);
@@ -150,7 +85,6 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c
 
                 // name and value are now the parameters
                 if (!strcmp(key, "cmd")) {
-                    //In this "if" we are working with the global silencers.
                     if (!strcmp(value, HEALTH_CMDAPI_CMD_SILENCEALL)) {
                         silencers->all_alarms = 1;
                         silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
@@ -171,19 +105,50 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c
                         free_silencers(silencers->silencers);
                         silencers->silencers = NULL;
                         buffer_strcat(wb, HEALTH_CMDAPI_MSG_RESET);
-                    } else if (!strcmp(value, HEALTH_CMDAPI_CMD_LIST)) {
-                        w->response.data->contenttype = CT_APPLICATION_JSON;
-                        health_silencers2json(wb);
-                        config_changed=0;
                     }
                 } else {
-                    //In this else we work with local silencer
-                    silencer = health_silencers_addparam(silencer,key,value);
-                }
-            }
+                    uint32_t hash = simple_uhash(key);
+                    if (unlikely(silencer == NULL)) {
+                        if (
+                                (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) ||
+                                (hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) ||
+                                (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) ||
+                                (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) ||
+                                (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) ||
+                                (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY))
+                                ) {
+                            silencer = create_silencer();
+                        }
+                    }
 
+                    if (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
+                        silencer->alarms = strdupz(value);
+                        silencer->alarms_pattern = simple_pattern_create(silencer->alarms, NULL, SIMPLE_PATTERN_EXACT);
+                    } else if (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) {
+                        silencer->charts = strdupz(value);
+                        silencer->charts_pattern = simple_pattern_create(silencer->charts, NULL, SIMPLE_PATTERN_EXACT);
+                    } else if (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) {
+                        silencer->contexts = strdupz(value);
+                        silencer->contexts_pattern = simple_pattern_create(silencer->contexts, NULL, SIMPLE_PATTERN_EXACT);
+                    } else if (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) {
+                        silencer->hosts = strdupz(value);
+                        silencer->hosts_pattern = simple_pattern_create(silencer->hosts, NULL, SIMPLE_PATTERN_EXACT);
+                    } else if (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) {
+                        silencer->families = strdupz(value);
+                        silencer->families_pattern = simple_pattern_create(silencer->families, NULL, SIMPLE_PATTERN_EXACT);
+                    } else {
+                        buffer_strcat(wb, HEALTH_CMDAPI_MSG_INVALID_KEY);
+                    }
+                }
+
+            }
             if (likely(silencer)) {
-                health_silencers_add(silencer);
+                // Add the created instance to the linked list in silencers
+                silencer->next = silencers->silencers;
+                silencers->silencers = silencer;
+                debug(D_HEALTH, "HEALTH command API: Added silencer %s:%s:%s:%s:%s", silencer->alarms,
+                      silencer->charts, silencer->contexts, silencer->hosts, silencer->families
+                );
                 buffer_strcat(wb, HEALTH_CMDAPI_MSG_ADDED);
                 if (silencers->stype == STYPE_NONE) {
                     buffer_strcat(wb, HEALTH_CMDAPI_MSG_STYPEWARNING);
@@ -197,10 +162,5 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c
     }
     w->response.data = wb;
     buffer_no_cacheable(w->response.data);
-    if (ret == 200 && config_changed) {
-        BUFFER *jsonb = buffer_create(200);
-        health_silencers2json(jsonb);
-        health_silencers2file(jsonb);
-    }
     return ret;
 }
diff --git a/web/api/health/health_cmdapi.h b/web/api/health/health_cmdapi.h
index d8ec6aaa02..d0f30401c9 100644
--- a/web/api/health/health_cmdapi.h
+++ b/web/api/health/health_cmdapi.h
@@ -12,7 +12,6 @@
 #define HEALTH_CMDAPI_CMD_SILENCE "SILENCE"
 #define HEALTH_CMDAPI_CMD_DISABLE "DISABLE"
 #define HEALTH_CMDAPI_CMD_RESET "RESET"
-#define HEALTH_CMDAPI_CMD_LIST "LIST"
 
 #define HEALTH_CMDAPI_MSG_AUTHERROR "Auth Error\n"
 #define HEALTH_CMDAPI_MSG_SILENCEALL "All alarm notifications are silenced\n"
@@ -21,6 +20,7 @@
 #define HEALTH_CMDAPI_MSG_DISABLE "Health checks disabled for alarms matching the selectors\n"
 #define HEALTH_CMDAPI_MSG_SILENCE "Alarm notifications silenced for alarms matching the selectors\n"
 #define HEALTH_CMDAPI_MSG_ADDED "Alarm selector added\n"
+#define HEALTH_CMDAPI_MSG_INVALID_KEY "Invalid key. Ignoring it.\n"
 #define HEALTH_CMDAPI_MSG_STYPEWARNING "WARNING: Added alarm selector to silence/disable alarms without a SILENCE or DISABLE command.\n"
 #define HEALTH_CMDAPI_MSG_NOSELECTORWARNING "WARNING: SILENCE or DISABLE command is ineffective without defining any alarm selectors.\n"
 
diff --git a/web/api/netdata-swagger.json b/web/api/netdata-swagger.json
index 70018730e0..6d28e840a2 100644
--- a/web/api/netdata-swagger.json
+++ b/web/api/netdata-swagger.json
@@ -664,7 +664,7 @@
           {
             "name": "cmd",
             "in": "query",
-            "description": "DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors. LIST: Show active configuration.",
+            "description": "DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors.",
             "required": false,
             "type": "string",
             "enum": [
@@ -672,8 +672,7 @@
               "SILENCE ALL",
               "DISABLE",
               "SILENCE",
-              "RESET",
-              "LIST"
+              "RESET"
             ]
           },
           {
diff --git a/web/api/netdata-swagger.yaml b/web/api/netdata-swagger.yaml
index 841648d631..9c5517d03a 100644
--- a/web/api/netdata-swagger.yaml
+++ b/web/api/netdata-swagger.yaml
@@ -437,10 +437,10 @@ paths:
       parameters:
         - name: cmd
           in: query
-          description: 'DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors. LIST: Show active configuration.'
+          description: 'DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors.'
           required: false
           type: string
-          enum: ['DISABLE ALL', 'SILENCE ALL', 'DISABLE', 'SILENCE', 'RESET', 'LIST']
+          enum: ['DISABLE ALL', 'SILENCE ALL', 'DISABLE', 'SILENCE', 'RESET']
         - name: alarm
           in: query
           description: 'The expression provided will match both `alarm` and `template` names.'