]> arthur.barton.de Git - netdata.git/commitdiff
added ipv6 support; minor fixes
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Tue, 24 Mar 2015 23:18:18 +0000 (01:18 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Tue, 24 Mar 2015 23:18:18 +0000 (01:18 +0200)
src/config.c
src/daemon.c
src/main.c
src/rrd.c
src/rrd.h
src/web_server.c
src/web_server.h
web/index.js
web/netdata.js

index d8e53d919769d46dd840847665732ea368412865..7cc066da107f65e529d603d0da147a6cbff12092 100755 (executable)
@@ -362,7 +362,7 @@ void generate_config(struct web_buffer *wb, int only_changed)
                        case 0:
                                web_buffer_printf(wb, 
                                        "# NetData Configuration\n"
-                                       "# You can uncomment and change any of the options bellow.\n"
+                                       "# You can uncomment and change any of the options below.\n"
                                        "# The value shown in the commented settings, is the default value.\n"
                                        "\n# global netdata configuration\n");
                                break;
index d772743fbb5a7b23c11650c1bb99fe5ddddcab25..1b6dc0c137ac965246348309e5f3645fc82afc3f 100755 (executable)
@@ -46,7 +46,9 @@ void sig_handler(int signo)
                        break;
 
                case SIGPIPE:
-                       info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
+                       // this is received when web clients send a reset
+                       // no need to log it.
+                       // info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
                        break;
 
 
index b05eceae63198c7df6ddfc80b3a95d66a6117527..1257753ee3c8d0db53768372151915aa09f468fa 100755 (executable)
@@ -271,20 +271,33 @@ int main(int argc, char **argv)
 
                // --------------------------------------------------------------------
 
+               listen_backlog = config_get_number("global", "http port listen backlog", LISTEN_BACKLOG);
+
                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);
                        listen_port = LISTEN_PORT;
                }
-               else debug(D_OPTIONS, "listen port set to %d.", listen_port);
+               else debug(D_OPTIONS, "Listen port set to %d.", listen_port);
+
+               int ip = 0;
+               char *ipv = config_get("global", "ip version", "any");
+               if(!strcmp(ipv, "any") || !strcmp(ipv, "both") || !strcmp(ipv, "all")) ip = 0;
+               else if(!strcmp(ipv, "ipv4") || !strcmp(ipv, "IPV4") || !strcmp(ipv, "IPv4") || !strcmp(ipv, "4")) ip = 4;
+               else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6;
+               else fprintf(stderr, "Cannot understand ip version '%s'. Assumming 'any'.", ipv);
+
+               if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(listen_port, listen_backlog);
+               if(listen_fd < 0) {
+                       listen_fd = create_listen_socket4(listen_port, listen_backlog);
+                       if(listen_fd >= 0 && ip != 4) fprintf(stderr, "Managed to open an IPv4 socket on port %d.", listen_port);
+               }
 
-               listen_fd = create_listen_socket(listen_port);
+               if(listen_fd < 0) fatal("Cannot listen socket.");
        }
 
        // never become a problem
-       if(nice(20) == -1) {
-               fprintf(stderr, "Cannot lower my CPU priority. Error: %s.\n", strerror(errno));
-       }
+       if(nice(20) == -1) fprintf(stderr, "Cannot lower my CPU priority. Error: %s.\n", strerror(errno));
 
 #ifndef NETDATA_NO_DAEMON
        if(become_daemon(0, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) {
index 10999e82dac3806e14836f634c8723537e13672b..c6eb742572e5483623a8fd137325781ca0f568de 100755 (executable)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -17,6 +17,8 @@
 
 #include "rrd.h"
 
+#define RRD_DEFAULT_GAP_INTERPOLATIONS 10
+
 // ----------------------------------------------------------------------------
 // globals
 
index 6db79f6d40542471852788f260cdc79483058044..a3e0177229ada50f2d205c2113ef082afd4a3672 100755 (executable)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -15,16 +15,14 @@ extern int rrd_update_every;
 #define RRD_HISTORY_ENTRIES_MAX (86400*10)
 extern int rrd_default_history_entries;
 
-#define RRD_DEFAULT_GAP_INTERPOLATIONS 10
+#define RRD_ID_LENGTH_MAX 1024
+
+#define RRDSET_MAGIC           "NETDATA RRD SET FILE V012"
+#define RRDDIMENSION_MAGIC     "NETDATA RRD DIMENSION FILE V012"
 
 typedef long long total_number;
 #define TOTAL_NUMBER_FORMAT "%lld"
 
-#define RRD_ID_LENGTH_MAX 1024
-
-#define RRDSET_MAGIC           "NETDATA CACHE STATS FILE V011"
-#define RRDDIMENSION_MAGIC     "NETDATA CACHE DIMENSION FILE V011"
-
 // ----------------------------------------------------------------------------
 // chart types
 
@@ -78,45 +76,73 @@ extern const char *rrddim_algorithm_name(int chart_type);
 // RRD DIMENSION
 
 struct rrddim {
-       avl avl;                                                                                // the index - this has to be first!
+       // ------------------------------------------------------------------------
+       // binary indexing structures
+
+       avl avl;                                                                                // the binary index - this has to be first member!
+
+       // ------------------------------------------------------------------------
+       // the dimension definition
 
-       char magic[sizeof(RRDDIMENSION_MAGIC) + 1];             // our magic
        char id[RRD_ID_LENGTH_MAX + 1];                                 // the id of this dimension (for internal identification)
+
        const char *name;                                                               // the name of this dimension (as presented to user)
-       char cache_filename[FILENAME_MAX+1];
+                                                                                                       // this is a pointer to the config structure
+                                                                                                       // since the config always has a higher priority
+                                                                                                       // (the user overwrites the name of the charts)
        
-       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
+       int algorithm;                                                                  // the algorithm that is applied to add new collected values
+       long multiplier;                                                                // the multiplier of the collected values
+       long divisor;                                                                   // the divider of the collected values
 
-       long entries;                                                                   // how many entries this dimension has
-                                                                                                       // this should be the same to the entries of the data set
+       int hidden;                                                                             // if set to non zero, this dimension will not be offered to callers
+       int mapped;                                                                             // if set to non zero, this dimension is mapped to a file
 
-       int update_every;                                                               // every how many seconds is this updated?
-       int updated;                                                                    // set to 0 after each calculation, to 1 after each collected value
+       // ------------------------------------------------------------------------
+       // members for temporary data we need for calculations
 
-       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
+       unsigned long hash;                                                             // a simple hash of the id, to speed up searching / indexing
+                                                                                                       // instead of strcmp() every item in the binary index
+                                                                                                       // we first compare the hashes
 
-       int algorithm;
-       long multiplier;
-       long divisor;
+       char cache_filename[FILENAME_MAX+1];                    // the filename we load/save from/to this set
+
+       int updated;                                                                    // set to 0 after each calculation, to 1 after each collected value
+                                                                                                       // we use this to detect that a dimension is not updated
 
        struct timeval last_collected_time;                             // when was this dimension last updated
                                                                                                        // this is actual date time we updated the last_collected_value
                                                                                                        // THIS IS DIFFERENT FROM THE SAME MEMBER OF RRD_STATS
 
-       calculated_number calculated_value;
-       calculated_number last_calculated_value;
+       calculated_number calculated_value;                             // the current calculated value, after applying the algorithm
+       calculated_number last_calculated_value;                // the 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 current value, as collected
+       collected_number last_collected_value;                  // the last value that was collected
 
-       calculated_number collected_volume;
-       calculated_number stored_volume;
+       // the *_volume members are used to calculate the accuracy of the rounding done by the
+       // storage number - they are printed to debug.log when debug is enabled for a set.
+       calculated_number collected_volume;                             // the sum of all collected values so far
+       calculated_number stored_volume;                                // the sum of all stored values so far
 
        struct rrddim *next;                                                    // linking of dimensions within the same data set
 
+       // ------------------------------------------------------------------------
+       // members for checking the data when loading from disk
+
+       long entries;                                                                   // how many entries this dimension has in ram
+                                                                                                       // this is the same to the entries of the data set
+                                                                                                       // we set it here, to check the data when we load it from disk.
+
+       int update_every;                                                               // every how many seconds is this updated
+
+       unsigned long memsize;                                                  // the memory allocated for this dimension
+
+       char magic[sizeof(RRDDIMENSION_MAGIC) + 1];             // a string to be saved, used to identify our data file
+
+       // ------------------------------------------------------------------------
+       // the values stored in this dimension, using our floating point numbers
+
        storage_number values[];                                                // the array of values - THIS HAS TO BE THE LAST MEMBER
 };
 typedef struct rrddim RRDDIM;
@@ -126,60 +152,90 @@ typedef struct rrddim RRDDIM;
 // RRDSET
 
 struct rrdset {
+       // ------------------------------------------------------------------------
+       // binary indexing structures
+
        avl avl;                                                                                // the index, with key the id - this has to be first!
        avl avlname;                                                                    // the index, with key the name
 
-       char magic[sizeof(RRDSET_MAGIC) + 1];                   // our magic
+       // ------------------------------------------------------------------------
+       // the set configuration
 
        char id[RRD_ID_LENGTH_MAX + 1];                                 // id of the data set
-       const char *name;                                                               // name of the data set
-       char *cache_dir;                                                                // the directory to store dimension maps
-       char cache_filename[FILENAME_MAX+1];
+
+       const char *name;                                                               // the name of this dimension (as presented to user)
+                                                                                                       // this is a pointer to the config structure
+                                                                                                       // since the config always has a higher priority
+                                                                                                       // (the user overwrites the name of the charts)
 
        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
+       int chart_type;
 
-       int mapped;                                                                             // if set to 1, this is memory mapped
-       unsigned long memsize;                                                  // how much mem we have allocated for this (without dimensions)
+       int update_every;                                                               // every how many seconds is this updated?
 
-       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 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 enabled;
 
        int gap_when_lost_iterations_above;                             // after how many lost iterations a gap should be stored
                                                                                                        // netdata will interpolate values for gaps lower than this
 
        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
+       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 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;
+       // ------------------------------------------------------------------------
+       // members for temporary data we need for calculations
 
-       total_number collected_total;
-       total_number last_collected_total;
+       int mapped;                                                                             // if set to 1, this is memory mapped
 
-       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)
 
-       RRDDIM *dimensions;                                                             // the actual data for every dimension
-       avl_tree dimensions_index;                                              // the root of the dimensions index
+       char *cache_dir;                                                                // the directory to store dimensions
+       char cache_filename[FILENAME_MAX+1];                    // the filename to store this set
+
+       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 long first_entry_t;                               // the timestamp (in microseconds) of the oldest entry in the db
+
+       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 long usec_since_last_update;              // the time in microseconds since the last collection of data
+
+       struct timeval last_updated;                                    // when this data set was last updated (updated every time the rrd_stats_done() function)
+       struct timeval last_collected_time;                             // when did this data set last collected values
+
+       total_number collected_total;                                   // used internally to calculate percentages
+       total_number last_collected_total;                              // used internally to calculate percentages
 
        struct rrdset *next;                                                    // linking of rrdsets
+
+       // ------------------------------------------------------------------------
+       // members for checking the data when loading from disk
+
+       unsigned long memsize;                                                  // how much mem we have allocated for this (without dimensions)
+
+       char magic[sizeof(RRDSET_MAGIC) + 1];                   // our magic
+
+       // ------------------------------------------------------------------------
+       // the dimensions
+
+       avl_tree dimensions_index;                                              // the root of the dimensions index
+       RRDDIM *dimensions;                                                             // the actual data for every dimension
 };
 typedef struct rrdset RRDSET;
 
index e25644e9370c94be88493678655c706bad28ef1e..084d652e24659bd76042ec6d200488d2e96865f3 100755 (executable)
 #include "rrd.h"
 #include "rrd2json.h"
 
+int listen_backlog = LISTEN_BACKLOG;
+
 int listen_fd = -1;
 int listen_port = LISTEN_PORT;
 
+#define DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS 60
+
+int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
+
 static void log_allocations(void)
 {
        static int mem = 0;
@@ -44,17 +50,19 @@ static void log_allocations(void)
        }
 }
 
-int create_listen_socket(int port)
+int create_listen_socket4(int port, int listen_backlog)
 {
-               int sock=-1;
-               int sockopt=1;
+               int sock = -1;
+               int sockopt = 1;
                struct sockaddr_in name;
 
-               debug(D_LISTENER, "Creating new listening socket on port %d", port);
+               debug(D_LISTENER, "IPv4 creating new listening socket on port %d", port);
 
                sock = socket(AF_INET, SOCK_STREAM, 0);
-               if (sock < 0)
-                               fatal("socket() failed, errno=%d", errno);
+               if(sock < 0) {
+                       error("IPv4 socket() failed.");
+                       return -1;
+               }
 
                /* avoid "address already in use" */
                setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
@@ -63,13 +71,59 @@ int create_listen_socket(int port)
                name.sin_family = AF_INET;
                name.sin_port = htons (port);
                name.sin_addr.s_addr = htonl (INADDR_ANY);
-               if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
-                       fatal("bind() failed, errno=%d", errno);
 
-               if (listen(sock, LISTEN_BACKLOG) < 0)
-                       fatal("listen() failed, errno=%d", errno);
+               if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
+                       close(sock);
+                       error("IPv4 bind() failed.");
+                       return -1;
+               }
+
+               if(listen(sock, listen_backlog) < 0) {
+                       close(sock);
+                       fatal("IPv4 listen() failed.");
+                       return -1;
+               }
 
-               debug(D_LISTENER, "Listening Port %d created", port);
+               debug(D_LISTENER, "IPv4 listening port %d created", port);
+               return sock;
+}
+
+int create_listen_socket6(int port, int listen_backlog)
+{
+               int sock = -1;
+               int sockopt = 1;
+               struct sockaddr_in6 name;
+
+               debug(D_LISTENER, "IPv6 creating new listening socket on port %d", port);
+
+               sock = socket(AF_INET6, SOCK_STREAM, 0);
+               if (sock < 0) {
+                       error("IPv6 socket() failed.");
+                       return -1;
+               }
+
+               /* avoid "address already in use" */
+               setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
+
+               memset(&name, 0, sizeof(struct sockaddr_in6));
+               name.sin6_family = AF_INET6;
+               name.sin6_port = htons (port);
+               name.sin6_addr = in6addr_any;
+               name.sin6_scope_id = 0;
+
+               if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
+                       close(sock);
+                       error("IPv6 bind() failed.");
+                       return -1;
+               }
+
+               if (listen(sock, listen_backlog) < 0) {
+                       close(sock);
+                       fatal("IPv6 listen() failed.");
+                       return -1;
+               }
+
+               debug(D_LISTENER, "IPv6 listening port %d created", port);
                return sock;
 }
 
@@ -275,8 +329,8 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
        debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
 
        // do we have such a data set?
-       RRDSET *st = rrdset_find(tok);
-       if(!st) st = rrdset_find_byname(tok);
+       RRDSET *st = rrdset_find_byname(tok);
+       if(!st) st = rrdset_find(tok);
        if(!st) {
                // we don't have it
                // try to send a file with that name
@@ -490,8 +544,8 @@ void web_client_process(struct web_client *w)
                                debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
 
                                // do we have such a data set?
-                               RRDSET *st = rrdset_find(tok);
-                               if(!st) st = rrdset_find_byname(tok);
+                               RRDSET *st = rrdset_find_byname(tok);
+                               if(!st) st = rrdset_find(tok);
                                if(!st) {
                                        // we don't have it
                                        // try to send a file with that name
@@ -514,8 +568,8 @@ void web_client_process(struct web_client *w)
                                debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
 
                                // do we have such a data set?
-                               RRDSET *st = rrdset_find(tok);
-                               if(!st) st = rrdset_find_byname(tok);
+                               RRDSET *st = rrdset_find_byname(tok);
+                               if(!st) st = rrdset_find(tok);
                                if(!st) {
                                        code = 404;
                                        web_buffer_printf(w->data, "Chart %s is not found.\r\n", tok);
@@ -1092,24 +1146,28 @@ void *new_client(void *ptr)
                FD_ZERO (&efds);
 
                FD_SET(w->ifd, &efds);
-               if(w->ifd != w->ofd)    FD_SET(w->ofd, &efds);
+
+               if(w->ifd != w->ofd)
+                       FD_SET(w->ofd, &efds);
+
                if (w->wait_receive) {
                        FD_SET(w->ifd, &ifds);
                        if(w->ifd > fdmax) fdmax = w->ifd;
                }
+
                if (w->wait_send) {
                        FD_SET(w->ofd, &ofds);
                        if(w->ofd > fdmax) fdmax = w->ofd;
                }
 
-               tv.tv_sec = 30;
+               tv.tv_sec = web_client_timeout;
                tv.tv_usec = 0;
 
                debug(D_WEB_CLIENT, "%llu: Waiting socket async I/O for %s %s", w->id, w->wait_receive?"INPUT":"", w->wait_send?"OUTPUT":"");
                retval = select(fdmax+1, &ifds, &ofds, &efds, &tv);
 
                if(retval == -1) {
-                       error("%llu: LISTENER: select() failed.", w->id);
+                       debug(D_WEB_CLIENT_ACCESS, "%llu: LISTENER: select() failed.", w->id);
                        continue;
                }
                else if(!retval) {
@@ -1197,12 +1255,12 @@ void *socket_listen_main(void *ptr)
        if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
                error("Cannot set pthread cancel state to ENABLE.");
 
-       // int listener = create_listen_socket(listen_port);
-       int listener = listen_fd;
-       if(listener == -1) fatal("LISTENER: Cannot create listening socket on port 19999.");
+       web_client_timeout = config_get_number("global", "disconnect idle web clients after seconds", DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS);
+
+       if(listen_fd < 0) fatal("LISTENER: Listen socket is not ready.");
 
        fd_set ifds, ofds, efds;
-       int fdmax = listener;
+       int fdmax = listen_fd;
 
        FD_ZERO (&ifds);
        FD_ZERO (&ofds);
@@ -1212,8 +1270,10 @@ void *socket_listen_main(void *ptr)
                tv.tv_sec = 0;
                tv.tv_usec = 200000;
 
-               FD_SET(listener, &ifds);
-               FD_SET(listener, &efds);
+               if(listen_fd >= 0) {
+                       FD_SET(listen_fd, &ifds);
+                       FD_SET(listen_fd, &efds);
+               }
 
                // debug(D_WEB_CLIENT, "LISTENER: Waiting...");
                retval = select(fdmax+1, &ifds, &ofds, &efds, &tv);
@@ -1224,8 +1284,8 @@ void *socket_listen_main(void *ptr)
                }
                else if(retval) {
                        // check for new incoming connections
-                       if(FD_ISSET(listener, &ifds)) {
-                               w = web_client_create(listener);
+                       if(FD_ISSET(listen_fd, &ifds)) {
+                               w = web_client_create(listen_fd);
 
                                if(pthread_create(&w->thread, NULL, new_client, w) != 0) {
                                        error("%llu: failed to create new thread for web client.");
@@ -1235,7 +1295,7 @@ void *socket_listen_main(void *ptr)
                                        error("%llu: Cannot request detach of newly created web client thread.", w->id);
                                        w->obsolete = 1;
                                }
-                               
+
                                log_access("%llu: %s connected", w->id, w->client_ip);
                        }
                        else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
@@ -1259,7 +1319,7 @@ void *socket_listen_main(void *ptr)
 
        error("LISTENER: exit!");
 
-       close(listener);
+       if(listen_fd >= 0) close(listen_fd);
        exit(2);
 
        return NULL;
index 7ad39a07864217f5e42aca9ceee2ae592cc21fb8..0d1e2da9253277091db43dcb4e2a70862dbc86fb 100755 (executable)
@@ -9,10 +9,12 @@
 #define LISTEN_PORT 19999
 #define LISTEN_BACKLOG 100
 
+extern int listen_backlog;
 extern int listen_fd;
 extern int listen_port;
 
-extern int create_listen_socket(int port);
+extern int create_listen_socket4(int port, int listen_backlog);
+extern int create_listen_socket6(int port, int listen_backlog);
 extern void *socket_listen_main(void *ptr);
 
 #endif /* NETDATA_WEB_SERVER_H */
index 4ae604e635a1050b428407a1baf3bbc2930c336e..fc376e5396ccf3c837435665dbde5ae5313eb170 100755 (executable)
@@ -13,12 +13,12 @@ var GROUPS_POINTS_DIVISOR = 4;
 var GROUPS_STACKED_POINTS_DIVISOR = 10;
 
 var MAINCHART_MAX_TIME_TO_SHOW = 600;  // how much time the main chart will present by default?
-var MAINCHART_POINTS_DIVISOR = 10;             // how much detailed will the main chart be by default? 1 = finest, higher is faster
-var MAINCHART_STACKED_POINTS_DIVISOR = 20;             // how much detailed will the main chart be by default? 1 = finest, higher is faster
+var MAINCHART_POINTS_DIVISOR = 5;              // how much detailed will the main chart be by default? 1 = finest, higher is faster
+var MAINCHART_STACKED_POINTS_DIVISOR = 10;             // how much detailed will the main chart be by default? 1 = finest, higher is faster
 
 var MAINCHART_CONTROL_HEIGHT = 75;             // how tall the control chart will be
 var MAINCHART_CONTROL_DIVISOR = 2;             // how much detailed will the control chart be? 1 = finest, higher is faster
-var MAINCHART_INITIAL_SELECTOR= 40;            // 1/20th of the width, this overrides MAINCHART_MAX_TIME_TO_SHOW
+var MAINCHART_INITIAL_SELECTOR= 20;            // 1/20th of the width, this overrides MAINCHART_MAX_TIME_TO_SHOW
 
 var CHARTS_REFRESH_IDLE = 100;
 var CHARTS_CHECK_NO_FOCUS = 500;
index 6df3065477e7af902f0d4a008db18274cb26c613..a79c4ad9fce785e8cfb4d35650435a880bd4804a 100755 (executable)
@@ -261,6 +261,8 @@ function loadCharts(base_url, doNext) {
                                        
                                        json.charts[i].chartOptions.vAxis.viewWindowMode = 'maximized';
                                        json.charts[i].non_zero = 0;
+                                       
+                                       json.charts[i].group = 3;
                                        break;
 
                                case "stacked":
@@ -274,6 +276,8 @@ function loadCharts(base_url, doNext) {
                                        json.charts[i].chartOptions.vAxis.viewWindowMode = 'maximized';
                                        json.charts[i].chartOptions.vAxis.minValue = null;
                                        json.charts[i].chartOptions.vAxis.maxValue = null;
+
+                                       json.charts[i].group = 10;
                                        break;
 
                                default:
@@ -283,6 +287,8 @@ function loadCharts(base_url, doNext) {
                                        json.charts[i].non_zero = 0;
 
                                        json.charts[i].default_curveType = 'function';
+                                       
+                                       json.charts[i].group = 3;
                                        break;
                        }
 
@@ -292,7 +298,6 @@ function loadCharts(base_url, doNext) {
                                        json.charts[i].category = "System";
                                        json.charts[i].categoryPriority = 10;
                                        json.charts[i].glyphicon = "glyphicon-dashboard";
-                                       json.charts[i].group = 5;
 
                                        if(json.charts[i].id == "system.cpu" || json.charts[i].id == "system.ram") {
                                                json.charts[i].chartOptions.vAxis.minValue = 0;
@@ -308,7 +313,6 @@ function loadCharts(base_url, doNext) {
                                        json.charts[i].category = "Network";
                                        json.charts[i].categoryPriority = 20;
                                        json.charts[i].glyphicon = "glyphicon-transfer";
-                                       json.charts[i].group = 5;
 
                                        // disable IFB and net.lo devices by default
                                        if((json.charts[i].id.substring(json.charts[i].id.length - 4, json.charts[i].id.length) == "-ifb")
@@ -320,42 +324,36 @@ function loadCharts(base_url, doNext) {
                                        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 = "IP Virtual Server";
                                        json.charts[i].categoryPriority = 40;
                                        json.charts[i].glyphicon = "glyphicon-sort";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "netfilter":
                                        json.charts[i].category = "Netfilter";
                                        json.charts[i].categoryPriority = 50;
                                        json.charts[i].glyphicon = "glyphicon-cloud";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "ipv4":
                                        json.charts[i].category = "IPv4";
                                        json.charts[i].categoryPriority = 60;
                                        json.charts[i].glyphicon = "glyphicon-globe";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "mem":
                                        json.charts[i].category = "Memory";
                                        json.charts[i].categoryPriority = 70;
                                        json.charts[i].glyphicon = "glyphicon-dashboard";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "cpu":
                                        json.charts[i].category = "CPU";
                                        json.charts[i].categoryPriority = 80;
                                        json.charts[i].glyphicon = "glyphicon-dashboard";
-                                       json.charts[i].group = 5;
 
                                        if(json.charts[i].id.substring(0, 7) == "cpu.cpu") {
                                                json.charts[i].chartOptions.vAxis.minValue = 0;
@@ -367,56 +365,48 @@ function loadCharts(base_url, doNext) {
                                        json.charts[i].category = "Disks";
                                        json.charts[i].categoryPriority = 90;
                                        json.charts[i].glyphicon = "glyphicon-hdd";
-                                       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;
                                        json.charts[i].glyphicon = "glyphicon-thumbs-up";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "apps":
                                        json.charts[i].category = "Apps";
                                        json.charts[i].categoryPriority = 4000;
                                        json.charts[i].glyphicon = "glyphicon-tasks";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "squid":
                                        json.charts[i].category = "Squid";
                                        json.charts[i].categoryPriority = 5000;
                                        json.charts[i].glyphicon = "glyphicon-link";
-                                       json.charts[i].group = 5;
                                        break;
 
                                case "example":
                                        json.charts[i].category = "Examples";
                                        json.charts[i].categoryPriority = 9000;
                                        json.charts[i].glyphicon = "glyphicon-search";
-                                       json.charts[i].group = 5;
                                        break;
 
                                default:
                                        json.charts[i].category = json.charts[i].type;
                                        json.charts[i].categoryPriority = 1000;
                                        json.charts[i].glyphicon = "glyphicon-search";
-                                       json.charts[i].group = 5;
                                        break;
                        }
                });