@cryptotaxi247 / netdata-1 / commits / fcf0816c8

added ipv6 support; minor fixes

Costa Tsaousis (ktsaou) committed Mar 25, 2015 at 01:18 UTC fcf0816c853eddcfc7423b9663dce93ed9ed9b01
9 files changed +237 -112
src/config.c
+1 -1
@@ -362,7 +362,7 @@ void generate_config(struct web_buffer *wb, int only_changed)
362 case 0:
363 web_buffer_printf(wb,
364 "# NetData Configuration\n"
365 - "# You can uncomment and change any of the options bellow.\n"
365 + "# You can uncomment and change any of the options below.\n"
366 "# The value shown in the commented settings, is the default value.\n"
367 "\n# global netdata configuration\n");
368 break;
src/daemon.c
+3 -1
@@ -46,7 +46,9 @@ void sig_handler(int signo)
46 break;
47
48 case SIGPIPE:
49 - info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
49 + // this is received when web clients send a reset
50 + // no need to log it.
51 + // info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
52 break;
53
54
src/main.c
+18 -5
@@ -271,20 +271,33 @@ int main(int argc, char **argv)
271
272 // --------------------------------------------------------------------
273
274 + listen_backlog = config_get_number("global", "http port listen backlog", LISTEN_BACKLOG);
275 +
276 listen_port = config_get_number("global", "port", LISTEN_PORT);
277 if(listen_port < 1 || listen_port > 65535) {
278 fprintf(stderr, "Invalid listen port %d given. Defaulting to %d.\n", listen_port, LISTEN_PORT);
279 listen_port = LISTEN_PORT;
280 }
279 - else debug(D_OPTIONS, "listen port set to %d.", listen_port);
281 + else debug(D_OPTIONS, "Listen port set to %d.", listen_port);
282 +
283 + int ip = 0;
284 + char *ipv = config_get("global", "ip version", "any");
285 + if(!strcmp(ipv, "any") || !strcmp(ipv, "both") || !strcmp(ipv, "all")) ip = 0;
286 + else if(!strcmp(ipv, "ipv4") || !strcmp(ipv, "IPV4") || !strcmp(ipv, "IPv4") || !strcmp(ipv, "4")) ip = 4;
287 + else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6;
288 + else fprintf(stderr, "Cannot understand ip version '%s'. Assumming 'any'.", ipv);
289 +
290 + if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(listen_port, listen_backlog);
291 + if(listen_fd < 0) {
292 + listen_fd = create_listen_socket4(listen_port, listen_backlog);
293 + if(listen_fd >= 0 && ip != 4) fprintf(stderr, "Managed to open an IPv4 socket on port %d.", listen_port);
294 + }
295
281 - listen_fd = create_listen_socket(listen_port);
296 + if(listen_fd < 0) fatal("Cannot listen socket.");
297 }
298
299 // never become a problem
285 - if(nice(20) == -1) {
286 - fprintf(stderr, "Cannot lower my CPU priority. Error: %s.\n", strerror(errno));
287 - }
300 + if(nice(20) == -1) fprintf(stderr, "Cannot lower my CPU priority. Error: %s.\n", strerror(errno));
301
302 #ifndef NETDATA_NO_DAEMON
303 if(become_daemon(0, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) {
src/rrd.c
+2
@@ -17,6 +17,8 @@
17
18 #include "rrd.h"
19
20 +#define RRD_DEFAULT_GAP_INTERPOLATIONS 10
21 +
22 // ----------------------------------------------------------------------------
23 // globals
24
src/rrd.h
+111 -55
@@ -15,16 +15,14 @@ extern int rrd_update_every;
15 #define RRD_HISTORY_ENTRIES_MAX (86400*10)
16 extern int rrd_default_history_entries;
17
18 -#define RRD_DEFAULT_GAP_INTERPOLATIONS 10
18 +#define RRD_ID_LENGTH_MAX 1024
19 +
20 +#define RRDSET_MAGIC "NETDATA RRD SET FILE V012"
21 +#define RRDDIMENSION_MAGIC "NETDATA RRD DIMENSION FILE V012"
22
23 typedef long long total_number;
24 #define TOTAL_NUMBER_FORMAT "%lld"
25
23 -#define RRD_ID_LENGTH_MAX 1024
24 -
25 -#define RRDSET_MAGIC "NETDATA CACHE STATS FILE V011"
26 -#define RRDDIMENSION_MAGIC "NETDATA CACHE DIMENSION FILE V011"
27 -
26 // ----------------------------------------------------------------------------
27 // chart types
28
@@ -78,45 +76,73 @@ extern const char *rrddim_algorithm_name(int chart_type);
76 // RRD DIMENSION
77
78 struct rrddim {
81 - avl avl; // the index - this has to be first!
79 + // ------------------------------------------------------------------------
80 + // binary indexing structures
81 +
82 + avl avl; // the binary index - this has to be first member!
83 +
84 + // ------------------------------------------------------------------------
85 + // the dimension definition
86
83 - char magic[sizeof(RRDDIMENSION_MAGIC) + 1]; // our magic
87 char id[RRD_ID_LENGTH_MAX + 1]; // the id of this dimension (for internal identification)
88 +
89 const char *name; // the name of this dimension (as presented to user)
86 - char cache_filename[FILENAME_MAX+1];
90 + // this is a pointer to the config structure
91 + // since the config always has a higher priority
92 + // (the user overwrites the name of the charts)
93
88 - unsigned long hash; // a simple hash on the id, to speed up searching
89 - // we first compare hashes, and only if the hashes are equal we do string comparisons
94 + int algorithm; // the algorithm that is applied to add new collected values
95 + long multiplier; // the multiplier of the collected values
96 + long divisor; // the divider of the collected values
97
91 - long entries; // how many entries this dimension has
92 - // this should be the same to the entries of the data set
98 + int hidden; // if set to non zero, this dimension will not be offered to callers
99 + int mapped; // if set to non zero, this dimension is mapped to a file
100
94 - int update_every; // every how many seconds is this updated?
95 - int updated; // set to 0 after each calculation, to 1 after each collected value
101 + // ------------------------------------------------------------------------
102 + // members for temporary data we need for calculations
103
97 - int hidden; // if set to non zero, this dimension will not be sent to the client
98 - int mapped; // 1 if the file is mapped
99 - unsigned long memsize; // the memory allocated for this dimension
104 + unsigned long hash; // a simple hash of the id, to speed up searching / indexing
105 + // instead of strcmp() every item in the binary index
106 + // we first compare the hashes
107
101 - int algorithm;
102 - long multiplier;
103 - long divisor;
108 + char cache_filename[FILENAME_MAX+1]; // the filename we load/save from/to this set
109 +
110 + int updated; // set to 0 after each calculation, to 1 after each collected value
111 + // we use this to detect that a dimension is not updated
112
113 struct timeval last_collected_time; // when was this dimension last updated
114 // this is actual date time we updated the last_collected_value
115 // THIS IS DIFFERENT FROM THE SAME MEMBER OF RRD_STATS
116
109 - calculated_number calculated_value;
110 - calculated_number last_calculated_value;
117 + calculated_number calculated_value; // the current calculated value, after applying the algorithm
118 + calculated_number last_calculated_value; // the last calculated value
119
112 - collected_number collected_value; // the value collected at this round
113 - collected_number last_collected_value; // the value that was collected at the last round
120 + collected_number collected_value; // the current value, as collected
121 + collected_number last_collected_value; // the last value that was collected
122
115 - calculated_number collected_volume;
116 - calculated_number stored_volume;
123 + // the *_volume members are used to calculate the accuracy of the rounding done by the
124 + // storage number - they are printed to debug.log when debug is enabled for a set.
125 + calculated_number collected_volume; // the sum of all collected values so far
126 + calculated_number stored_volume; // the sum of all stored values so far
127
128 struct rrddim *next; // linking of dimensions within the same data set
129
130 + // ------------------------------------------------------------------------
131 + // members for checking the data when loading from disk
132 +
133 + long entries; // how many entries this dimension has in ram
134 + // this is the same to the entries of the data set
135 + // we set it here, to check the data when we load it from disk.
136 +
137 + int update_every; // every how many seconds is this updated
138 +
139 + unsigned long memsize; // the memory allocated for this dimension
140 +
141 + char magic[sizeof(RRDDIMENSION_MAGIC) + 1]; // a string to be saved, used to identify our data file
142 +
143 + // ------------------------------------------------------------------------
144 + // the values stored in this dimension, using our floating point numbers
145 +
146 storage_number values[]; // the array of values - THIS HAS TO BE THE LAST MEMBER
147 };
148 typedef struct rrddim RRDDIM;
@@ -126,60 +152,90 @@ typedef struct rrddim RRDDIM;
152 // RRDSET
153
154 struct rrdset {
155 + // ------------------------------------------------------------------------
156 + // binary indexing structures
157 +
158 avl avl; // the index, with key the id - this has to be first!
159 avl avlname; // the index, with key the name
160
132 - char magic[sizeof(RRDSET_MAGIC) + 1]; // our magic
161 + // ------------------------------------------------------------------------
162 + // the set configuration
163
164 char id[RRD_ID_LENGTH_MAX + 1]; // id of the data set
135 - const char *name; // name of the data set
136 - char *cache_dir; // the directory to store dimension maps
137 - char cache_filename[FILENAME_MAX+1];
165 +
166 + const char *name; // the name of this dimension (as presented to user)
167 + // this is a pointer to the config structure
168 + // since the config always has a higher priority
169 + // (the user overwrites the name of the charts)
170
171 char *type; // the type of graph RRD_TYPE_* (a category, for determining graphing options)
172 char *family; // the family of this data set (for grouping them together)
173 char *title; // title shown to user
174 char *units; // units of measurement
175
144 - pthread_rwlock_t rwlock;
145 - unsigned long counter; // the number of times we added values to this rrd
146 - unsigned long counter_done; // the number of times we added values to this rrd
176 + int chart_type;
177
148 - int mapped; // if set to 1, this is memory mapped
149 - unsigned long memsize; // how much mem we have allocated for this (without dimensions)
178 + int update_every; // every how many seconds is this updated?
179
151 - unsigned long hash_name; // a simple hash on the name
152 - unsigned long hash; // a simple hash on the id, to speed up searching
153 - // we first compare hashes, and only if the hashes are equal we do string comparisons
180 + long entries; // total number of entries in the data set
181 +
182 + long current_entry; // the entry that is currently being updated
183 + // it goes around in a round-robin fashion
184 +
185 + int enabled;
186
187 int gap_when_lost_iterations_above; // after how many lost iterations a gap should be stored
188 // netdata will interpolate values for gaps lower than this
189
190 long priority;
191
160 - long entries; // total number of entries in the data set
161 - long current_entry; // the entry that is currently being updated
162 - // it goes around in a round-robin fashion
192 + int isdetail; // if set, the data set should be considered as a detail of another
193 + // (the master data set should be the one that has the same family and is not detail)
194
164 - int update_every; // every how many seconds is this updated?
165 - unsigned long long first_entry_t; // the timestamp (in microseconds) of the oldest entry in the db
166 - struct timeval last_updated; // when this data set was last updated (updated every time the rrd_stats_done() function)
167 - struct timeval last_collected_time; //
168 - unsigned long long usec_since_last_update;
195 + // ------------------------------------------------------------------------
196 + // members for temporary data we need for calculations
197
170 - total_number collected_total;
171 - total_number last_collected_total;
198 + int mapped; // if set to 1, this is memory mapped
199
173 - int chart_type;
200 int debug;
175 - int enabled;
176 - int isdetail; // if set, the data set should be considered as a detail of another
177 - // (the master data set should be the one that has the same family and is not detail)
201
179 - RRDDIM *dimensions; // the actual data for every dimension
180 - avl_tree dimensions_index; // the root of the dimensions index
202 + char *cache_dir; // the directory to store dimensions
203 + char cache_filename[FILENAME_MAX+1]; // the filename to store this set
204 +
205 + pthread_rwlock_t rwlock;
206 +
207 + unsigned long counter; // the number of times we added values to this rrd
208 + unsigned long counter_done; // the number of times we added values to this rrd
209 +
210 + unsigned long long first_entry_t; // the timestamp (in microseconds) of the oldest entry in the db
211 +
212 + unsigned long hash; // a simple hash on the id, to speed up searching
213 + // we first compare hashes, and only if the hashes are equal we do string comparisons
214 +
215 + unsigned long hash_name; // a simple hash on the name
216 +
217 + unsigned long long usec_since_last_update; // the time in microseconds since the last collection of data
218 +
219 + struct timeval last_updated; // when this data set was last updated (updated every time the rrd_stats_done() function)
220 + struct timeval last_collected_time; // when did this data set last collected values
221 +
222 + total_number collected_total; // used internally to calculate percentages
223 + total_number last_collected_total; // used internally to calculate percentages
224
225 struct rrdset *next; // linking of rrdsets
226 +
227 + // ------------------------------------------------------------------------
228 + // members for checking the data when loading from disk
229 +
230 + unsigned long memsize; // how much mem we have allocated for this (without dimensions)
231 +
232 + char magic[sizeof(RRDSET_MAGIC) + 1]; // our magic
233 +
234 + // ------------------------------------------------------------------------
235 + // the dimensions
236 +
237 + avl_tree dimensions_index; // the root of the dimensions index
238 + RRDDIM *dimensions; // the actual data for every dimension
239 };
240 typedef struct rrdset RRDSET;
241
src/web_server.c
+90 -30
@@ -24,9 +24,15 @@
24 #include "rrd.h"
25 #include "rrd2json.h"
26
27 +int listen_backlog = LISTEN_BACKLOG;
28 +
29 int listen_fd = -1;
30 int listen_port = LISTEN_PORT;
31
32 +#define DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS 60
33 +
34 +int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
35 +
36 static void log_allocations(void)
37 {
38 static int mem = 0;
@@ -44,17 +50,19 @@ static void log_allocations(void)
50 }
51 }
52
47 -int create_listen_socket(int port)
53 +int create_listen_socket4(int port, int listen_backlog)
54 {
49 - int sock=-1;
50 - int sockopt=1;
55 + int sock = -1;
56 + int sockopt = 1;
57 struct sockaddr_in name;
58
53 - debug(D_LISTENER, "Creating new listening socket on port %d", port);
59 + debug(D_LISTENER, "IPv4 creating new listening socket on port %d", port);
60
61 sock = socket(AF_INET, SOCK_STREAM, 0);
56 - if (sock < 0)
57 - fatal("socket() failed, errno=%d", errno);
62 + if(sock < 0) {
63 + error("IPv4 socket() failed.");
64 + return -1;
65 + }
66
67 /* avoid "address already in use" */
68 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
@@ -63,13 +71,59 @@ int create_listen_socket(int port)
71 name.sin_family = AF_INET;
72 name.sin_port = htons (port);
73 name.sin_addr.s_addr = htonl (INADDR_ANY);
66 - if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
67 - fatal("bind() failed, errno=%d", errno);
74
69 - if (listen(sock, LISTEN_BACKLOG) < 0)
70 - fatal("listen() failed, errno=%d", errno);
75 + if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
76 + close(sock);
77 + error("IPv4 bind() failed.");
78 + return -1;
79 + }
80 +
81 + if(listen(sock, listen_backlog) < 0) {
82 + close(sock);
83 + fatal("IPv4 listen() failed.");
84 + return -1;
85 + }
86
72 - debug(D_LISTENER, "Listening Port %d created", port);
87 + debug(D_LISTENER, "IPv4 listening port %d created", port);
88 + return sock;
89 +}
90 +
91 +int create_listen_socket6(int port, int listen_backlog)
92 +{
93 + int sock = -1;
94 + int sockopt = 1;
95 + struct sockaddr_in6 name;
96 +
97 + debug(D_LISTENER, "IPv6 creating new listening socket on port %d", port);
98 +
99 + sock = socket(AF_INET6, SOCK_STREAM, 0);
100 + if (sock < 0) {
101 + error("IPv6 socket() failed.");
102 + return -1;
103 + }
104 +
105 + /* avoid "address already in use" */
106 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
107 +
108 + memset(&name, 0, sizeof(struct sockaddr_in6));
109 + name.sin6_family = AF_INET6;
110 + name.sin6_port = htons (port);
111 + name.sin6_addr = in6addr_any;
112 + name.sin6_scope_id = 0;
113 +
114 + if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
115 + close(sock);
116 + error("IPv6 bind() failed.");
117 + return -1;
118 + }
119 +
120 + if (listen(sock, listen_backlog) < 0) {
121 + close(sock);
122 + fatal("IPv6 listen() failed.");
123 + return -1;
124 + }
125 +
126 + debug(D_LISTENER, "IPv6 listening port %d created", port);
127 return sock;
128 }
129
@@ -275,8 +329,8 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
329 debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
330
331 // do we have such a data set?
278 - RRDSET *st = rrdset_find(tok);
279 - if(!st) st = rrdset_find_byname(tok);
332 + RRDSET *st = rrdset_find_byname(tok);
333 + if(!st) st = rrdset_find(tok);
334 if(!st) {
335 // we don't have it
336 // try to send a file with that name
@@ -490,8 +544,8 @@ void web_client_process(struct web_client *w)
544 debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
545
546 // do we have such a data set?
493 - RRDSET *st = rrdset_find(tok);
494 - if(!st) st = rrdset_find_byname(tok);
547 + RRDSET *st = rrdset_find_byname(tok);
548 + if(!st) st = rrdset_find(tok);
549 if(!st) {
550 // we don't have it
551 // try to send a file with that name
@@ -514,8 +568,8 @@ void web_client_process(struct web_client *w)
568 debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
569
570 // do we have such a data set?
517 - RRDSET *st = rrdset_find(tok);
518 - if(!st) st = rrdset_find_byname(tok);
571 + RRDSET *st = rrdset_find_byname(tok);
572 + if(!st) st = rrdset_find(tok);
573 if(!st) {
574 code = 404;
575 web_buffer_printf(w->data, "Chart %s is not found.\r\n", tok);
@@ -1092,24 +1146,28 @@ void *new_client(void *ptr)
1146 FD_ZERO (&efds);
1147
1148 FD_SET(w->ifd, &efds);
1095 - if(w->ifd != w->ofd) FD_SET(w->ofd, &efds);
1149 +
1150 + if(w->ifd != w->ofd)
1151 + FD_SET(w->ofd, &efds);
1152 +
1153 if (w->wait_receive) {
1154 FD_SET(w->ifd, &ifds);
1155 if(w->ifd > fdmax) fdmax = w->ifd;
1156 }
1157 +
1158 if (w->wait_send) {
1159 FD_SET(w->ofd, &ofds);
1160 if(w->ofd > fdmax) fdmax = w->ofd;
1161 }
1162
1105 - tv.tv_sec = 30;
1163 + tv.tv_sec = web_client_timeout;
1164 tv.tv_usec = 0;
1165
1166 debug(D_WEB_CLIENT, "%llu: Waiting socket async I/O for %s %s", w->id, w->wait_receive?"INPUT":"", w->wait_send?"OUTPUT":"");
1167 retval = select(fdmax+1, &ifds, &ofds, &efds, &tv);
1168
1169 if(retval == -1) {
1112 - error("%llu: LISTENER: select() failed.", w->id);
1170 + debug(D_WEB_CLIENT_ACCESS, "%llu: LISTENER: select() failed.", w->id);
1171 continue;
1172 }
1173 else if(!retval) {
@@ -1197,12 +1255,12 @@ void *socket_listen_main(void *ptr)
1255 if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
1256 error("Cannot set pthread cancel state to ENABLE.");
1257
1200 - // int listener = create_listen_socket(listen_port);
1201 - int listener = listen_fd;
1202 - if(listener == -1) fatal("LISTENER: Cannot create listening socket on port 19999.");
1258 + web_client_timeout = config_get_number("global", "disconnect idle web clients after seconds", DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS);
1259 +
1260 + if(listen_fd < 0) fatal("LISTENER: Listen socket is not ready.");
1261
1262 fd_set ifds, ofds, efds;
1205 - int fdmax = listener;
1263 + int fdmax = listen_fd;
1264
1265 FD_ZERO (&ifds);
1266 FD_ZERO (&ofds);
@@ -1212,8 +1270,10 @@ void *socket_listen_main(void *ptr)
1270 tv.tv_sec = 0;
1271 tv.tv_usec = 200000;
1272
1215 - FD_SET(listener, &ifds);
1216 - FD_SET(listener, &efds);
1273 + if(listen_fd >= 0) {
1274 + FD_SET(listen_fd, &ifds);
1275 + FD_SET(listen_fd, &efds);
1276 + }
1277
1278 // debug(D_WEB_CLIENT, "LISTENER: Waiting...");
1279 retval = select(fdmax+1, &ifds, &ofds, &efds, &tv);
@@ -1224,8 +1284,8 @@ void *socket_listen_main(void *ptr)
1284 }
1285 else if(retval) {
1286 // check for new incoming connections
1227 - if(FD_ISSET(listener, &ifds)) {
1228 - w = web_client_create(listener);
1287 + if(FD_ISSET(listen_fd, &ifds)) {
1288 + w = web_client_create(listen_fd);
1289
1290 if(pthread_create(&w->thread, NULL, new_client, w) != 0) {
1291 error("%llu: failed to create new thread for web client.");
@@ -1235,7 +1295,7 @@ void *socket_listen_main(void *ptr)
1295 error("%llu: Cannot request detach of newly created web client thread.", w->id);
1296 w->obsolete = 1;
1297 }
1238 -
1298 +
1299 log_access("%llu: %s connected", w->id, w->client_ip);
1300 }
1301 else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
@@ -1259,7 +1319,7 @@ void *socket_listen_main(void *ptr)
1319
1320 error("LISTENER: exit!");
1321
1262 - close(listener);
1322 + if(listen_fd >= 0) close(listen_fd);
1323 exit(2);
1324
1325 return NULL;
src/web_server.h
+3 -1
@@ -9,10 +9,12 @@
9 #define LISTEN_PORT 19999
10 #define LISTEN_BACKLOG 100
11
12 +extern int listen_backlog;
13 extern int listen_fd;
14 extern int listen_port;
15
15 -extern int create_listen_socket(int port);
16 +extern int create_listen_socket4(int port, int listen_backlog);
17 +extern int create_listen_socket6(int port, int listen_backlog);
18 extern void *socket_listen_main(void *ptr);
19
20 #endif /* NETDATA_WEB_SERVER_H */
web/index.js
+3 -3
@@ -13,12 +13,12 @@ var GROUPS_POINTS_DIVISOR = 4;
13 var GROUPS_STACKED_POINTS_DIVISOR = 10;
14
15 var MAINCHART_MAX_TIME_TO_SHOW = 600; // how much time the main chart will present by default?
16 -var MAINCHART_POINTS_DIVISOR = 10; // how much detailed will the main chart be by default? 1 = finest, higher is faster
17 -var MAINCHART_STACKED_POINTS_DIVISOR = 20; // how much detailed will the main chart be by default? 1 = finest, higher is faster
16 +var MAINCHART_POINTS_DIVISOR = 5; // how much detailed will the main chart be by default? 1 = finest, higher is faster
17 +var MAINCHART_STACKED_POINTS_DIVISOR = 10; // how much detailed will the main chart be by default? 1 = finest, higher is faster
18
19 var MAINCHART_CONTROL_HEIGHT = 75; // how tall the control chart will be
20 var MAINCHART_CONTROL_DIVISOR = 2; // how much detailed will the control chart be? 1 = finest, higher is faster
21 -var MAINCHART_INITIAL_SELECTOR= 40; // 1/20th of the width, this overrides MAINCHART_MAX_TIME_TO_SHOW
21 +var MAINCHART_INITIAL_SELECTOR= 20; // 1/20th of the width, this overrides MAINCHART_MAX_TIME_TO_SHOW
22
23 var CHARTS_REFRESH_IDLE = 100;
24 var CHARTS_CHECK_NO_FOCUS = 500;
web/netdata.js
+6 -16
@@ -261,6 +261,8 @@ function loadCharts(base_url, doNext) {
261
262 json.charts[i].chartOptions.vAxis.viewWindowMode = 'maximized';
263 json.charts[i].non_zero = 0;
264 +
265 + json.charts[i].group = 3;
266 break;
267
268 case "stacked":
@@ -274,6 +276,8 @@ function loadCharts(base_url, doNext) {
276 json.charts[i].chartOptions.vAxis.viewWindowMode = 'maximized';
277 json.charts[i].chartOptions.vAxis.minValue = null;
278 json.charts[i].chartOptions.vAxis.maxValue = null;
279 +
280 + json.charts[i].group = 10;
281 break;
282
283 default:
@@ -283,6 +287,8 @@ function loadCharts(base_url, doNext) {
287 json.charts[i].non_zero = 0;
288
289 json.charts[i].default_curveType = 'function';
290 +
291 + json.charts[i].group = 3;
292 break;
293 }
294
@@ -292,7 +298,6 @@ function loadCharts(base_url, doNext) {
298 json.charts[i].category = "System";
299 json.charts[i].categoryPriority = 10;
300 json.charts[i].glyphicon = "glyphicon-dashboard";
295 - json.charts[i].group = 5;
301
302 if(json.charts[i].id == "system.cpu" || json.charts[i].id == "system.ram") {
303 json.charts[i].chartOptions.vAxis.minValue = 0;
@@ -308,7 +313,6 @@ function loadCharts(base_url, doNext) {
313 json.charts[i].category = "Network";
314 json.charts[i].categoryPriority = 20;
315 json.charts[i].glyphicon = "glyphicon-transfer";
311 - json.charts[i].group = 5;
316
317 // disable IFB and net.lo devices by default
318 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) {
324 json.charts[i].category = "Quality of Service";
325 json.charts[i].categoryPriority = 30;
326 json.charts[i].glyphicon = "glyphicon-random";
323 - json.charts[i].group = 15;
327 break;
328
329 case "ipvs":
330 json.charts[i].category = "IP Virtual Server";
331 json.charts[i].categoryPriority = 40;
332 json.charts[i].glyphicon = "glyphicon-sort";
330 - json.charts[i].group = 5;
333 break;
334
335 case "netfilter":
336 json.charts[i].category = "Netfilter";
337 json.charts[i].categoryPriority = 50;
338 json.charts[i].glyphicon = "glyphicon-cloud";
337 - json.charts[i].group = 5;
339 break;
340
341 case "ipv4":
342 json.charts[i].category = "IPv4";
343 json.charts[i].categoryPriority = 60;
344 json.charts[i].glyphicon = "glyphicon-globe";
344 - json.charts[i].group = 5;
345 break;
346
347 case "mem":
348 json.charts[i].category = "Memory";
349 json.charts[i].categoryPriority = 70;
350 json.charts[i].glyphicon = "glyphicon-dashboard";
351 - json.charts[i].group = 5;
351 break;
352
353 case "cpu":
354 json.charts[i].category = "CPU";
355 json.charts[i].categoryPriority = 80;
356 json.charts[i].glyphicon = "glyphicon-dashboard";
358 - json.charts[i].group = 5;
357
358 if(json.charts[i].id.substring(0, 7) == "cpu.cpu") {
359 json.charts[i].chartOptions.vAxis.minValue = 0;
@@ -367,56 +365,48 @@ function loadCharts(base_url, doNext) {
365 json.charts[i].category = "Disks";
366 json.charts[i].categoryPriority = 90;
367 json.charts[i].glyphicon = "glyphicon-hdd";
370 - json.charts[i].group = 5;
368 break;
369
370 case "nfsd":
371 json.charts[i].category = "NFS Server";
372 json.charts[i].categoryPriority = 100;
373 json.charts[i].glyphicon = "glyphicon-hdd";
377 - json.charts[i].group = 5;
374 break;
375
376 case "nut":
377 json.charts[i].category = "UPS";
378 json.charts[i].categoryPriority = 110;
379 json.charts[i].glyphicon = "glyphicon-dashboard";
384 - json.charts[i].group = 5;
380 break;
381
382 case "netdata":
383 json.charts[i].category = "NetData";
384 json.charts[i].categoryPriority = 3000;
385 json.charts[i].glyphicon = "glyphicon-thumbs-up";
391 - json.charts[i].group = 5;
386 break;
387
388 case "apps":
389 json.charts[i].category = "Apps";
390 json.charts[i].categoryPriority = 4000;
391 json.charts[i].glyphicon = "glyphicon-tasks";
398 - json.charts[i].group = 5;
392 break;
393
394 case "squid":
395 json.charts[i].category = "Squid";
396 json.charts[i].categoryPriority = 5000;
397 json.charts[i].glyphicon = "glyphicon-link";
405 - json.charts[i].group = 5;
398 break;
399
400 case "example":
401 json.charts[i].category = "Examples";
402 json.charts[i].categoryPriority = 9000;
403 json.charts[i].glyphicon = "glyphicon-search";
412 - json.charts[i].group = 5;
404 break;
405
406 default:
407 json.charts[i].category = json.charts[i].type;
408 json.charts[i].categoryPriority = 1000;
409 json.charts[i].glyphicon = "glyphicon-search";
419 - json.charts[i].group = 5;
410 break;
411 }
412 });