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
});