]> arthur.barton.de Git - netdata.git/commitdiff
added nfacct charts (disabled for the moment - they must be made an external plugin...
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 18 Mar 2015 23:54:54 +0000 (01:54 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 18 Mar 2015 23:54:54 +0000 (01:54 +0200)
src/Makefile
src/log.h
src/main.c
src/proc_net_stat_conntrack.c
src/rrd.c
src/rrd.h
src/storage_number.c
src/unit_test.c
src/web_buffer.c
web/netdata.js [changed mode: 0644->0755]

index e3c966f87c4975b06f281a54dfe0382c0e52b4c8..4809455bcb9bbcd27152f020e6def2e3cb5cac67 100755 (executable)
@@ -27,6 +27,15 @@ CC = gcc
 
 proc_sources = proc_net_dev.c proc_net_ip_vs_stats.c proc_diskstats.c proc_meminfo.c proc_net_netstat.c proc_net_snmp.c proc_net_stat_conntrack.c proc_stat.c proc_vmstat.c proc_net_rpc_nfsd.c
 sources = procfile.c common.c log.c popen.c url.c config.c web_buffer.c storage_number.c web_client.c global_statistics.c rrd.c rrd2json.c web_server.c plugins_d.c daemon.c plugin_tc.c plugin_checks.c plugin_idlejitter.c plugin_proc.c unit_test.c main.c
+libs    = -pthread -lz -lm
+
+# nfacct requires root access, so we prefer it as a plugin.d external plugin
+ifdef INTERNAL_PLUGIN_NFACCT
+CFLAGS += -DINTERNAL_PLUGIN_NFACCT=1
+sources += plugin_nfacct.c
+libs += -lmnl -lnetfilter_acct
+endif
+
 headers = $(patsubst %.c,%.h,$(sources))
 objects = $(patsubst %.c,%.o,$(sources) $(proc_sources))
 
@@ -38,7 +47,7 @@ all: options netdata plugins
 
 netdata: $(objects)
        @echo "    $(CC) netdata"
-       @$(CC) -o netdata $(objects) -pthread -lz
+       @$(CC) -o netdata $(objects) $(libs)
 
 .PHONY: plugins
 plugins:
index ac81c0b829036e5f374ea0415d749c01a7dc2e71..d7c900a31d376103d25323a0ac3898da3a0b8179 100755 (executable)
--- a/src/log.h
+++ b/src/log.h
@@ -19,6 +19,7 @@
 #define D_CHILDS            0x00001000
 #define D_EXIT              0x00002000
 #define D_CHECKS            0x00004000
+#define D_NFACCT_LOOP          0x00008000
 
 #define DEBUG (D_WEB_CLIENT_ACCESS|D_LISTENER|D_RRD_STATS)
 //#define DEBUG 0xffffffff
index 1a58400a12fd18913be06313835ded7aae46c4c5..646db19cbe0636e1e4d78539c4598076056d849e 100755 (executable)
@@ -25,6 +25,7 @@
 #include "plugin_tc.h"
 #include "plugin_checks.h"
 #include "plugin_proc.h"
+#include "plugin_nfacct.h"
 
 #include "main.h"
 
@@ -37,17 +38,26 @@ struct netdata_static_thread {
        int enabled;
 
        pthread_t *thread;
+
+       void (*init_routine) (void);
        void *(*start_routine) (void *);
 };
 
 struct netdata_static_thread static_threads[] = {
-       {"tc",                  "plugins",      "tc",                   1, NULL, tc_main},
-       {"idlejitter",  "plugins",      "idlejitter",   1, NULL, cpuidlejitter_main},
-       {"proc",                "plugins",      "proc",                 1, NULL, proc_main},
-       {"plugins.d",   NULL,           NULL,                   1, NULL, pluginsd_main},
-       {"check",               "plugins",      "checks",               0, NULL, checks_main},
-       {"web",                 NULL,           NULL,                   1, NULL, socket_listen_main},
-       {NULL,                  NULL,           NULL,                   0, NULL, NULL}
+       {"tc",                  "plugins",      "tc",                   1, NULL, NULL,  tc_main},
+       {"idlejitter",  "plugins",      "idlejitter",   1, NULL, NULL,  cpuidlejitter_main},
+       {"proc",                "plugins",      "proc",                 1, NULL, NULL,  proc_main},
+
+#ifdef INTERNAL_PLUGIN_NFACCT
+       // nfacct requires root access
+       // so, we build it as an external plugin with setuid to root
+       {"nfacct",              "plugins",      "nfacct",               1, NULL, NULL,  nfacct_main},
+#endif
+
+       {"plugins.d",   NULL,           NULL,                   1, NULL, NULL,  pluginsd_main},
+       {"check",               "plugins",      "checks",               0, NULL, NULL,  checks_main},
+       {"web",                 NULL,           NULL,                   1, NULL, NULL,  socket_listen_main},
+       {NULL,                  NULL,           NULL,                   0, NULL, NULL,  NULL}
 };
 
 void kill_childs()
@@ -231,6 +241,24 @@ int main(int argc, char **argv)
 
                // --------------------------------------------------------------------
 
+               update_every = config_get_number("global", "update every", UPDATE_EVERY);
+               if(update_every < 1 || update_every > 600) {
+                       fprintf(stderr, "Invalid update timer %d given. Defaulting to %d.\n", update_every, UPDATE_EVERY_MAX);
+                       update_every = UPDATE_EVERY;
+               }
+               else debug(D_OPTIONS, "update timer set to %d.", update_every);
+
+               // --------------------------------------------------------------------
+               
+               for (i = 0; static_threads[i].name != NULL ; i++) {
+                       struct netdata_static_thread *st = &static_threads[i];
+
+                       if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled);
+                       if(st->enabled && st->init_routine) st->init_routine();
+               }
+
+               // --------------------------------------------------------------------
+
                prepare_rundir();
                char *user = config_get("global", "run as user", (getuid() == 0)?"nobody":"");
                if(*user) {
@@ -243,15 +271,6 @@ int main(int argc, char **argv)
 
                // --------------------------------------------------------------------
 
-               update_every = config_get_number("global", "update every", UPDATE_EVERY);
-               if(update_every < 1 || update_every > 600) {
-                       fprintf(stderr, "Invalid update timer %d given. Defaulting to %d.\n", update_every, UPDATE_EVERY_MAX);
-                       update_every = UPDATE_EVERY;
-               }
-               else debug(D_OPTIONS, "update timer set to %d.", update_every);
-
-               // --------------------------------------------------------------------
-
                listen_port = config_get_number("global", "port", LISTEN_PORT);
                if(listen_port < 1 || listen_port > 65535) {
                        fprintf(stderr, "Invalid listen port %d given. Defaulting to %d.\n", listen_port, LISTEN_PORT);
@@ -285,8 +304,6 @@ int main(int argc, char **argv)
        for (i = 0; static_threads[i].name != NULL ; i++) {
                struct netdata_static_thread *st = &static_threads[i];
 
-               if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled);
-
                if(st->enabled) {
                        st->thread = malloc(sizeof(pthread_t));
 
index 86a8c0da68b6cf54cb1fc2e0c538cf346c5de917..7ccc86b1bfac137aec93067e3f083119c0852826 100755 (executable)
@@ -9,7 +9,7 @@
 #include "rrd.h"
 #include "plugin_proc.h"
 
-#define RRD_TYPE_NET_STAT_CONNTRACK    "conntrack"
+#define RRD_TYPE_NET_STAT_CONNTRACK    "netfilter"
 #define RRD_TYPE_NET_STAT_CONNTRACK_LEN        strlen(RRD_TYPE_NET_STAT_CONNTRACK)
 
 int do_proc_net_stat_conntrack(int update_every, unsigned long long dt) {
@@ -67,16 +67,16 @@ int do_proc_net_stat_conntrack(int update_every, unsigned long long dt) {
                if(!aentries) aentries =  tentries;
 
                // sum all the cpus together
-               asearched               += tsearched;           // conntrack.search
-               afound                  += tfound;              // conntrack.search
-               anew                    += tnew;                // conntrack.new
-               ainvalid                += tinvalid;            // conntrack.new
-               aignore                 += tignore;             // conntrack.new
-               adelete                 += tdelete;             // conntrack.changes
+               asearched                       += tsearched;           // conntrack.search
+               afound                          += tfound;                      // conntrack.search
+               anew                            += tnew;                        // conntrack.new
+               ainvalid                        += tinvalid;            // conntrack.new
+               aignore                         += tignore;                     // conntrack.new
+               adelete                         += tdelete;                     // conntrack.changes
                adelete_list            += tdelete_list;        // conntrack.changes
-               ainsert                 += tinsert;             // conntrack.changes
+               ainsert                         += tinsert;                     // conntrack.changes
                ainsert_failed          += tinsert_failed;      // conntrack.errors
-               adrop                   += tdrop;               // conntrack.errors
+               adrop                           += tdrop;                       // conntrack.errors
                aearly_drop             += tearly_drop;         // conntrack.errors
                aicmp_error             += ticmp_error;         // conntrack.errors
                aexpect_new             += texpect_new;         // conntrack.expect
index 53621fa230e34c0da938bdd5e75537b7d104c001..f890d92f3421158d79b14d4edd1545cd4bea2591 100755 (executable)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -582,7 +582,7 @@ void rrd_stats_dimension_set_by_pointer(RRD_STATS *st, RRD_DIMENSION *rd, collec
        rd->collected_value = value;
 }
 
-int rrd_stats_dimension_set(RRD_STATS *st, char *id, collected_number value)
+int rrd_stats_dimension_set(RRD_STATS *st, const char *id, collected_number value)
 {
        RRD_DIMENSION *rd = rrd_stats_dimension_find(st, id);
        if(!rd) {
index 3233a7e86e43502de814c8bec53e740c7d3073fb..c746c05c97dba0621ea051c82f9797fb58099993 100755 (executable)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -74,77 +74,77 @@ extern const char *algorithm_name(int chart_type);
 
 struct rrd_dimension {
        char magic[sizeof(RRD_DIMENSION_MAGIC) + 1];    // our magic
-       char id[RRD_STATS_NAME_MAX + 1];                // the id of this dimension (for internal identification)
-       char *name;                                     // the name of this dimension (as presented to user)
+       char id[RRD_STATS_NAME_MAX + 1];                                // the id of this dimension (for internal identification)
+       char *name;                                                                             // the name of this dimension (as presented to user)
        char cache_file[FILENAME_MAX+1];
        
-       unsigned long hash;                             // a simple hash on the id, to speed up searching
-                                                       // we first compare hashes, and only if the hashes are equal we do string comparisons
+       unsigned long hash;                                                             // a simple hash on the id, to speed up searching
+                                                                                                       // we first compare hashes, and only if the hashes are equal we do string comparisons
 
-       long entries;                                   // how many entries this dimension has
-                                                       // this should be the same to the entries of the data set
+       long entries;                                                                   // how many entries this dimension has
+                                                                                                       // this should be the same to the entries of the data set
 
-       long current_entry;                             // the entry that is currently being updated
-       int update_every;                               // every how many seconds is this updated?
+       long current_entry;                                                             // the entry that is currently being updated
+       int update_every;                                                               // every how many seconds is this updated?
 
-       int hidden;                                     // if set to non zero, this dimension will not be sent to the client
-       int mapped;                                     // 1 if the file is mapped
-       unsigned long memsize;                          // the memory allocated for this dimension
+       int hidden;                                                                             // if set to non zero, this dimension will not be sent to the client
+       int mapped;                                                                             // 1 if the file is mapped
+       unsigned long memsize;                                                  // the memory allocated for this dimension
 
        int algorithm;
        long multiplier;
        long divisor;
 
-       struct timeval last_collected_time;             // when was this dimension last updated
-                                                       // this is only used to detect un-updated dimensions
-                                                       // which are removed after some time
+       struct timeval last_collected_time;                             // when was this dimension last updated
+                                                                                                       // this is only used to detect un-updated dimensions
+                                                                                                       // which are removed after some time
 
        calculated_number calculated_value;
        calculated_number last_calculated_value;
 
-       collected_number collected_value;               // the value collected at this round
-       collected_number last_collected_value;          // the value that was collected at the last round
+       collected_number collected_value;                               // the value collected at this round
+       collected_number last_collected_value;                  // the value that was collected at the last round
 
-       struct rrd_dimension *next;                     // linking of dimensions within the same data set
+       struct rrd_dimension *next;                                             // linking of dimensions within the same data set
 
-       storage_number values[];                        // the array of values - THIS HAS TO BE THE LAST MEMBER
+       storage_number values[];                                                // the array of values - THIS HAS TO BE THE LAST MEMBER
 };
 typedef struct rrd_dimension RRD_DIMENSION;
 
 struct rrd_stats {
-       char magic[sizeof(RRD_STATS_MAGIC) + 1];        // our magic
+       char magic[sizeof(RRD_STATS_MAGIC) + 1];                // our magic
 
-       char id[RRD_STATS_NAME_MAX + 1];                // id of the data set
-       char *name;                                     // name of the data set
-       char *cache_dir;                                // the directory to store dimension maps
+       char id[RRD_STATS_NAME_MAX + 1];                                // id of the data set
+       char *name;                                                                             // name of the data set
+       char *cache_dir;                                                                // the directory to store dimension maps
        char cache_file[FILENAME_MAX+1];
 
-       char *type;                                     // the type of graph RRD_TYPE_* (a category, for determining graphing options)
-       char *family;                                   // the family of this data set (for grouping them together)
-       char *title;                                    // title shown to user
-       char *units;                                    // units of measurement
+       char *type;                                                                             // the type of graph RRD_TYPE_* (a category, for determining graphing options)
+       char *family;                                                                   // the family of this data set (for grouping them together)
+       char *title;                                                                    // title shown to user
+       char *units;                                                                    // units of measurement
 
        pthread_rwlock_t rwlock;
-       unsigned long counter;                          // the number of times we added values to this rrd
-       unsigned long counter_done;                     // the number of times we added values to this rrd
+       unsigned long counter;                                                  // the number of times we added values to this rrd
+       unsigned long counter_done;                                             // the number of times we added values to this rrd
 
-       int mapped;                                     // if set to 1, this is memory mapped
-       unsigned long memsize;                          // how much mem we have allocated for this (without dimensions)
+       int mapped;                                                                             // if set to 1, this is memory mapped
+       unsigned long memsize;                                                  // how much mem we have allocated for this (without dimensions)
 
-       unsigned long hash_name;                        // a simple hash on the name
-       unsigned long hash;                             // a simple hash on the id, to speed up searching
-                                                       // we first compare hashes, and only if the hashes are equal we do string comparisons
+       unsigned long hash_name;                                                // a simple hash on the name
+       unsigned long hash;                                                             // a simple hash on the id, to speed up searching
+                                                                                                       // we first compare hashes, and only if the hashes are equal we do string comparisons
 
        long priority;
 
-       long entries;                                   // total number of entries in the data set
-       long current_entry;                             // the entry that is currently being updated
-                                                       // it goes around in a round-robin fashion
+       long entries;                                                                   // total number of entries in the data set
+       long current_entry;                                                             // the entry that is currently being updated
+                                                                                                       // it goes around in a round-robin fashion
 
-       int update_every;                               // every how many seconds is this updated?
-       unsigned long long first_entry_t;               // the timestamp (in microseconds) of the oldest entry in the db
-       struct timeval last_updated;                    // when this data set was last updated (updated every time the rrd_stats_done() function)
-       struct timeval last_collected_time;             // 
+       int update_every;                                                               // every how many seconds is this updated?
+       unsigned long long first_entry_t;                               // the timestamp (in microseconds) of the oldest entry in the db
+       struct timeval last_updated;                                    // when this data set was last updated (updated every time the rrd_stats_done() function)
+       struct timeval last_collected_time;                             // 
        unsigned long long usec_since_last_update;
 
        total_number collected_total;
@@ -153,12 +153,12 @@ struct rrd_stats {
        int chart_type;
        int debug;
        int enabled;
-       int isdetail;                                   // if set, the data set should be considered as a detail of another
-                                                       // (the master data set should be the one that has the same family and is not detail)
+       int isdetail;                                                                   // if set, the data set should be considered as a detail of another
+                                                                                                       // (the master data set should be the one that has the same family and is not detail)
 
-       RRD_DIMENSION *dimensions;                      // the actual data for every dimension
+       RRD_DIMENSION *dimensions;                                              // the actual data for every dimension
 
-       struct rrd_stats *next;                         // linking of rrd stats
+       struct rrd_stats *next;                                                 // linking of rrd stats
 };
 typedef struct rrd_stats RRD_STATS;
 
@@ -191,7 +191,7 @@ extern RRD_DIMENSION *rrd_stats_dimension_find(RRD_STATS *st, const char *id);
 extern int rrd_stats_dimension_hide(RRD_STATS *st, const char *id);
 
 extern void rrd_stats_dimension_set_by_pointer(RRD_STATS *st, RRD_DIMENSION *rd, collected_number value);
-extern int rrd_stats_dimension_set(RRD_STATS *st, char *id, collected_number value);
+extern int rrd_stats_dimension_set(RRD_STATS *st, const char *id, collected_number value);
 
 extern void rrd_stats_next_usec(RRD_STATS *st, unsigned long long microseconds);
 extern void rrd_stats_next(RRD_STATS *st);
index dbbf7be32908a302dc65b8468884262e748d9537..fa18805fc76e122c9a4f8615917fe38548424f77 100755 (executable)
@@ -1,3 +1,4 @@
+#include <math.h>
 
 #include "log.h"
 #include "storage_number.h"
@@ -44,6 +45,10 @@ storage_number pack_storage_number(calculated_number value)
 
        mul = m;
 
+       // without this there are rounding problems
+       // example: 0.9 becomes 0.89
+       n = lrint(n);
+
        r = (sign << 31) + (exp << 30) + (mul << 27) + n;
        // fprintf(stderr, "PACK: %08X, sign = %d, exp = %d, mul = %d, n = " CALCULATED_NUMBER_FORMAT "\n", r, sign, exp, mul, n);
 
index 69612a9a67a25ba8de5d10e54243e9f7110c0015..26c0e973aaad198d9812caa105c7fd026202d9b0 100755 (executable)
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <stdlib.h>
 
 #include "storage_number.h"
 #include "rrd.h"
@@ -7,9 +8,9 @@
 
 int unit_test_storage()
 {
-       char buffer[100];
+       char buffer[100], *msg;
        storage_number s;
-       calculated_number c, a = 0, d, f;
+       calculated_number c, a = 0, d, ddiff, dcdiff, f, p, pdiff, pcdiff, maxddiff = 0, maxpdiff = 0;
        int i, j, g, r = 0, l;
 
        for(g = -1; g <= 1 ; g++) {
@@ -21,24 +22,50 @@ int unit_test_storage()
                        a += 0.0000001;
                        c = a * g;
                        for(i = 0; i < 21 ;i++, c *= 10) {
+                               if(c > 0 && c < 0.00001) continue;
+                               if(c < 0 && c > -0.00001) continue;
+
                                s = pack_storage_number(c);
                                d = unpack_storage_number(s);
 
+                               ddiff = d - c;
+                               dcdiff = ddiff * 100.0 / c;
+                               if(dcdiff < 0) dcdiff = -dcdiff;
+                               if(dcdiff > maxddiff) maxddiff = dcdiff;
+
                                f = d / c;
 
                                l = print_calculated_number(buffer, d);
+                               p = strtold(buffer, NULL);
+                               pdiff = c - p;
+                               pcdiff = pdiff * 100.0 / c;
+                               if(pcdiff < 0) pcdiff = -pcdiff;
+                               if(pcdiff > maxpdiff) maxpdiff = pcdiff;
 
                                if(f < 0.99999 || f > 1.00001) {
-                                       fprintf(stderr, "\nERROR\n" CALCULATED_NUMBER_FORMAT " original\n" CALCULATED_NUMBER_FORMAT " unpacked, (stored as 0x%08X)\n%s printed as %d bytes\n", c, d, s, buffer, l);
+                                       msg = "ERROR";
                                        r++;
                                }
-                               else {
-                                       fprintf(stderr, "\nOK\n" CALCULATED_NUMBER_FORMAT " original\n" CALCULATED_NUMBER_FORMAT " unpacked, (stored as 0x%08X)\n%s printed as %d bytes\n", c, d, s, buffer, l);
-                               }
+                               else msg = "OK";
+
+                               fprintf(stderr, "%s\n"
+                                       CALCULATED_NUMBER_FORMAT " original\n"
+                                       CALCULATED_NUMBER_FORMAT " unpacked, (stored as 0x%08X, diff " CALCULATED_NUMBER_FORMAT ", " CALCULATED_NUMBER_FORMAT "%%)\n"
+                                       "%s printed (%d bytes)\n"
+                                       CALCULATED_NUMBER_FORMAT " re-parsed with diff " CALCULATED_NUMBER_FORMAT ", " CALCULATED_NUMBER_FORMAT "%%\n\n",
+                                       msg,
+                                       c,
+                                       d, s, ddiff, dcdiff,
+                                       buffer,
+                                       l, p, pdiff, pcdiff
+                               );
                        }
                }
        }
 
+       fprintf(stderr, "Worst accuracy loss on unpacked numbers: " CALCULATED_NUMBER_FORMAT "%%\n", maxddiff);
+       fprintf(stderr, "Worst accuracy loss on printed numbers: " CALCULATED_NUMBER_FORMAT "%%\n", maxpdiff);
+
        return r;
 }
 
index 48f29a2926087bb5718f495b25215b807414a45c..c67e5b186d67d3e89bcf6f0a3b012400c08c4986 100755 (executable)
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <math.h>
 
 #include "web_buffer.h"
 
@@ -20,35 +21,50 @@ int print_calculated_number(char *str, calculated_number value)
 {
        char *wstr = str;
 
-       // make sure it is unsigned
-       unsigned long long uvalue = (unsigned long long)(((value < 0) ? -value : value) * (calculated_number)10000);
+       int sign = (value < 0) ? 1 : 0;
+       if(sign) value = -value;
+
+       // without llrint() there are rounding problems
+       // for example 0.9 becomes 0.89
+       unsigned long long uvalue = llrint(value * (calculated_number)100000);
 
        // print each digit
        do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
 
-       // make sure we have 8 bytes at least
-       while((wstr - str) < 5) *wstr++ = '0';
+       // make sure we have 6 bytes at least
+       while((wstr - str) < 6) *wstr++ = '0';
 
        // put the sign back
-       if (value < 0) *wstr++ = '-';
+       if(sign) *wstr++ = '-';
 
        // reverse it
        wstr--;
        strreverse(str, wstr);
 
+       // remove trailing zeros
+       int decimal = 5;
+       while(decimal > 0 && *wstr == '0') {
+               *wstr-- = '\0';
+               decimal--;
+       }
+
        // terminate it, one position to the right
        // to let space for a dot
        wstr[2] = '\0';
 
+       // make space for the dot
        int i;
-       for(i = 0; i < 4 ;i++) {
+       for(i = 0; i < decimal ;i++) {
                wstr[1] = wstr[0];
                wstr--;
        }
-       wstr[1] = '.';
+
+       // put the dot
+       if(wstr[2] == '\0') { wstr[1] = '\0'; decimal--; }
+       else wstr[1] = '.';
 
        // return the buffer length
-       return ( (wstr - str) + 6 );
+       return ( (wstr - str) + 2 + decimal );
 }
 
 void web_buffer_rrd_value(struct web_buffer *wb, calculated_number value)
old mode 100644 (file)
new mode 100755 (executable)
index 396c80c..6df3065
@@ -317,20 +317,20 @@ function loadCharts(base_url, doNext) {
                                        break;
 
                                case "tc":
-                                       json.charts[i].category = "QoS";
+                                       json.charts[i].category = "Quality of Service";
                                        json.charts[i].categoryPriority = 30;
                                        json.charts[i].glyphicon = "glyphicon-random";
                                        json.charts[i].group = 15;
                                        break;
 
                                case "ipvs":
-                                       json.charts[i].category = "IPVS";
+                                       json.charts[i].category = "IP Virtual Server";
                                        json.charts[i].categoryPriority = 40;
                                        json.charts[i].glyphicon = "glyphicon-sort";
                                        json.charts[i].group = 5;
                                        break;
 
-                               case "conntrack":
+                               case "netfilter":
                                        json.charts[i].category = "Netfilter";
                                        json.charts[i].categoryPriority = 50;
                                        json.charts[i].glyphicon = "glyphicon-cloud";
@@ -370,6 +370,20 @@ function loadCharts(base_url, doNext) {
                                        json.charts[i].group = 5;
                                        break;
 
+                               case "nfsd":
+                                       json.charts[i].category = "NFS Server";
+                                       json.charts[i].categoryPriority = 100;
+                                       json.charts[i].glyphicon = "glyphicon-hdd";
+                                       json.charts[i].group = 5;
+                                       break;
+
+                               case "nut":
+                                       json.charts[i].category = "UPS";
+                                       json.charts[i].categoryPriority = 110;
+                                       json.charts[i].glyphicon = "glyphicon-dashboard";
+                                       json.charts[i].group = 5;
+                                       break;
+
                                case "netdata":
                                        json.charts[i].category = "NetData";
                                        json.charts[i].categoryPriority = 3000;