more netdata resource charts
Costa Tsaousis (ktsaou) committed
May 10, 2014 at 01:55 UTC
eaaad1f6fabc5ecd7d8b010dfe9a5bacea999e57
1 file changed
+123
-26
netdata.c
+123
-26
@@ -141,6 +141,31 @@ int update_every = UPDATE_EVERY;
141
int listen_port = LISTEN_PORT;
142
143
144
+// ----------------------------------------------------------------------------
145
+// global statistics
146
+
147
+struct global_statistics {
148
+
149
+ unsigned long long connected_clients;
150
+
151
+ unsigned long long web_requests;
152
+
153
+ unsigned long long bytes_received;
154
+ unsigned long long bytes_sent;
155
+
156
+} global_statistics = { 0ULL };
157
+
158
+pthread_mutex_t global_statistics_mutex = PTHREAD_MUTEX_INITIALIZER;
159
+
160
+void global_statistics_lock(void)
161
+{
162
+ pthread_mutex_lock(&global_statistics_mutex);
163
+}
164
+void global_statistics_unlock(void)
165
+{
166
+ pthread_mutex_unlock(&global_statistics_mutex);
167
+}
168
+
169
// ----------------------------------------------------------------------------
170
// LOG
171
@@ -976,9 +1001,11 @@ char *rrd_stats_strncpy_name(char *to, const char *from, int length)
1001
1002
void rrd_stats_set_name(RRD_STATS *st, const char *name)
1003
{
979
- char b[CONFIG_MAX_VALUE+1];
1004
+ char b[CONFIG_MAX_VALUE + 1];
1005
+ char n[RRD_STATS_NAME_MAX + 1];
1006
981
- rrd_stats_strncpy_name(b, name, CONFIG_MAX_VALUE);
1007
+ snprintf(n, RRD_STATS_NAME_MAX, "%s.%s", st->type, name);
1008
+ rrd_stats_strncpy_name(b, n, CONFIG_MAX_VALUE);
1009
st->name = config_get(st->id, "name", b);
1010
st->hash_name = simple_hash(st->name);
1011
}
@@ -1003,8 +1030,13 @@ RRD_STATS *rrd_stats_create(const char *type, const char *id, const char *name,
1030
snprintf(st->id, RRD_STATS_NAME_MAX, "%s.%s", type, id);
1031
st->hash = simple_hash(st->id);
1032
1033
+ st->family = config_get(st->id, "family", family?family:st->id);
1034
+ st->units = config_get(st->id, "units", units?units:"");
1035
+ st->type = config_get(st->id, "type", type);
1036
+ st->chart_type = chart_type_id(config_get(st->id, "chart type", chart_type_name(chart_type)));
1037
+
1038
if(name && *name) rrd_stats_set_name(st, name);
1007
- else rrd_stats_set_name(st, st->id);
1039
+ else rrd_stats_set_name(st, id);
1040
1041
{
1042
char varvalue[CONFIG_MAX_VALUE + 1];
@@ -1012,11 +1044,6 @@ RRD_STATS *rrd_stats_create(const char *type, const char *id, const char *name,
1044
st->title = config_get(st->id, "title", varvalue);
1045
}
1046
1015
- st->family = config_get(st->id, "family", family?family:st->id);
1016
- st->units = config_get(st->id, "units", units?units:"");
1017
- st->type = config_get(st->id, "type", type);
1018
- st->chart_type = chart_type_id(config_get(st->id, "chart type", chart_type_name(chart_type)));
1019
-
1047
st->entries = config_get_number(st->id, "history", save_history);
1048
if(st->entries < 5) st->entries = config_set_number(st->id, "history", 5);
1049
if(st->entries > HISTORY_MAX) st->entries = config_set_number(st->id, "history", HISTORY_MAX);
@@ -1684,6 +1711,8 @@ struct web_client *web_client_create(int listener)
1711
w->next = web_clients;
1712
web_clients = w;
1713
1714
+ global_statistics.connected_clients++;
1715
+
1716
return(w);
1717
}
1718
@@ -1703,6 +1732,8 @@ struct web_client *web_client_free(struct web_client *w)
1732
if(w->ofd != w->ifd) close(w->ofd);
1733
free(w);
1734
1735
+ global_statistics.connected_clients--;
1736
+
1737
return(n);
1738
}
1739
@@ -2536,6 +2567,10 @@ void web_client_process(struct web_client *w)
2567
2568
// check if we have an empty line (end of HTTP header)
2569
if(strstr(w->data->buffer, "\r\n\r\n")) {
2570
+ global_statistics_lock();
2571
+ global_statistics.web_requests++;
2572
+ global_statistics_unlock();
2573
+
2574
gettimeofday(&w->tv_in, NULL);
2575
debug(D_WEB_DATA, "%llu: Processing data buffer of %d bytes: '%s'.", w->id, w->data->bytes, w->data->buffer);
2576
@@ -2886,6 +2921,11 @@ void web_client_process(struct web_client *w)
2921
bytes = send(w->ofd, w->response_header, headerlen, 0);
2922
if(bytes != headerlen)
2923
error("%llu: HTTP Header failed to be sent (I sent %d bytes but the system sent %d bytes).", w->id, headerlen, bytes);
2924
+ else {
2925
+ global_statistics_lock();
2926
+ global_statistics.bytes_sent += bytes;
2927
+ global_statistics_unlock();
2928
+ }
2929
2930
// enable TCP_NODELAY, to send all data immediately at the next send()
2931
flag = 1;
@@ -2927,7 +2967,7 @@ void web_client_process(struct web_client *w)
2967
}
2968
}
2969
2930
-void web_client_send_chunk_header(struct web_client *w, int len)
2970
+long web_client_send_chunk_header(struct web_client *w, int len)
2971
{
2972
debug(D_DEFLATE, "%llu: OPEN CHUNK of %d bytes (hex: %x).", w->id, len, len);
2973
char buf[1024];
@@ -2937,9 +2977,11 @@ void web_client_send_chunk_header(struct web_client *w, int len)
2977
if(bytes > 0) debug(D_DEFLATE, "%llu: Sent chunk header %d bytes.", w->id, bytes);
2978
else if(bytes == 0) debug(D_DEFLATE, "%llu: Did not send chunk header to the client.", w->id);
2979
else debug(D_DEFLATE, "%llu: Failed to send chunk header to client. Reason: %s", w->id, strerror(errno));
2980
+
2981
+ return bytes;
2982
}
2983
2942
-void web_client_send_chunk_close(struct web_client *w)
2984
+long web_client_send_chunk_close(struct web_client *w)
2985
{
2986
//debug(D_DEFLATE, "%llu: CLOSE CHUNK.", w->id);
2987
@@ -2948,9 +2990,11 @@ void web_client_send_chunk_close(struct web_client *w)
2990
if(bytes > 0) debug(D_DEFLATE, "%llu: Sent chunk suffix %d bytes.", w->id, bytes);
2991
else if(bytes == 0) debug(D_DEFLATE, "%llu: Did not send chunk suffix to the client.", w->id);
2992
else debug(D_DEFLATE, "%llu: Failed to send chunk suffix to client. Reason: %s", w->id, strerror(errno));
2993
+
2994
+ return bytes;
2995
}
2996
2953
-void web_client_send_chunk_finalize(struct web_client *w)
2997
+long web_client_send_chunk_finalize(struct web_client *w)
2998
{
2999
//debug(D_DEFLATE, "%llu: FINALIZE CHUNK.", w->id);
3000
@@ -2959,11 +3003,13 @@ void web_client_send_chunk_finalize(struct web_client *w)
3003
if(bytes > 0) debug(D_DEFLATE, "%llu: Sent chunk suffix %d bytes.", w->id, bytes);
3004
else if(bytes == 0) debug(D_DEFLATE, "%llu: Did not send chunk suffix to the client.", w->id);
3005
else debug(D_DEFLATE, "%llu: Failed to send chunk suffix to client. Reason: %s", w->id, strerror(errno));
3006
+
3007
+ return bytes;
3008
}
3009
3010
long web_client_send_deflate(struct web_client *w)
3011
{
2966
- long bytes;
3012
+ long bytes = 0, t = 0;
3013
3014
// when using compression,
3015
// w->data->sent is the amount of bytes passed through compression
@@ -2977,7 +3023,7 @@ long web_client_send_deflate(struct web_client *w)
3023
3024
// finalize the chunk
3025
if(w->data->sent != 0)
2980
- web_client_send_chunk_finalize(w);
3026
+ t += web_client_send_chunk_finalize(w);
3027
3028
// there can be two cases for this
3029
// A. we have done everything
@@ -3006,7 +3052,7 @@ long web_client_send_deflate(struct web_client *w)
3052
// compress more input data
3053
3054
// close the previous open chunk
3009
- if(w->data->sent != 0) web_client_send_chunk_close(w);
3055
+ if(w->data->sent != 0) t += web_client_send_chunk_close(w);
3056
3057
debug(D_DEFLATE, "%llu: Compressing %d bytes starting from %d.", w->id, (w->data->bytes - w->data->sent), w->data->sent);
3058
@@ -3047,12 +3093,13 @@ long web_client_send_deflate(struct web_client *w)
3093
debug(D_DEFLATE, "%llu: Compression produced %d bytes.", w->id, w->zhave);
3094
3095
// open a new chunk
3050
- web_client_send_chunk_header(w, w->zhave);
3096
+ t += web_client_send_chunk_header(w, w->zhave);
3097
}
3098
3099
bytes = send(w->ofd, &w->zbuffer[w->zsent], w->zhave - w->zsent, MSG_DONTWAIT);
3100
if(bytes > 0) {
3101
w->zsent += bytes;
3102
+ if(t > 0) bytes += t;
3103
debug(D_WEB_CLIENT, "%llu: Sent %d bytes.", w->id, bytes);
3104
}
3105
else if(bytes == 0) debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client.", w->id);
@@ -3219,23 +3266,37 @@ void *new_client(void *ptr)
3266
}
3267
3268
if(w->wait_send && FD_ISSET(w->ofd, &ofds)) {
3222
- if(web_client_send(w) < 0) {
3269
+ long bytes;
3270
+ if((bytes = web_client_send(w)) < 0) {
3271
debug(D_WEB_CLIENT, "%llu: Closing client (input: %s).", w->id, strerror(errno));
3272
web_client_reset(w);
3273
w->obsolete = 1;
3274
errno = 0;
3275
return NULL;
3276
}
3277
+ else {
3278
+ global_statistics_lock();
3279
+ global_statistics.bytes_sent += bytes;
3280
+ global_statistics_unlock();
3281
+ }
3282
}
3283
3284
if(w->wait_receive && FD_ISSET(w->ifd, &ifds)) {
3232
- if(web_client_receive(w) < 0) {
3285
+ long bytes;
3286
+ if((bytes = web_client_receive(w)) < 0) {
3287
debug(D_WEB_CLIENT, "%llu: Closing client (output: %s).", w->id, strerror(errno));
3288
web_client_reset(w);
3289
w->obsolete = 1;
3290
errno = 0;
3291
return NULL;
3292
}
3293
+ else {
3294
+ if(w->mode != WEB_CLIENT_MODE_FILECOPY) {
3295
+ global_statistics_lock();
3296
+ global_statistics.bytes_received += bytes;
3297
+ global_statistics_unlock();
3298
+ }
3299
+ }
3300
3301
if(w->mode == WEB_CLIENT_MODE_NORMAL) web_client_process(w);
3302
}
@@ -5214,9 +5275,9 @@ void *proc_main(void *ptr)
5275
int vdo_proc_stat = !config_get_boolean("plugin:proc", "/proc/stat", 1);
5276
int vdo_proc_meminfo = !config_get_boolean("plugin:proc", "/proc/meminfo", 1);
5277
int vdo_proc_vmstat = !config_get_boolean("plugin:proc", "/proc/vmstat", 1);
5217
- int vdo_cpu_netdata = !config_get_boolean("plugin:proc", "netdata cpu", 1);
5278
+ int vdo_cpu_netdata = !config_get_boolean("plugin:proc", "netdata server resources", 1);
5279
5219
- RRD_STATS *stcpu = NULL;
5280
+ RRD_STATS *stcpu = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL;
5281
5282
gettimeofday(&last, NULL);
5283
getrusage(RUSAGE_SELF, &me_last);
@@ -5254,7 +5315,7 @@ void *proc_main(void *ptr)
5315
unsigned long long cpuuser = me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec;
5316
unsigned long long cpusyst = me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec;
5317
5257
- if(!stcpu) stcpu = rrd_stats_find("cpu.netdata");
5318
+ if(!stcpu) stcpu = rrd_stats_find("netdata.server_cpu");
5319
if(!stcpu) {
5320
stcpu = rrd_stats_create("netdata", "server_cpu", NULL, "netdata", "NetData CPU usage", "milliseconds/s", 9999, update_every, CHART_TYPE_STACKED);
5321
@@ -5268,6 +5329,47 @@ void *proc_main(void *ptr)
5329
rrd_stats_done(stcpu);
5330
5331
bcopy(&me, &me_last, sizeof(struct rusage));
5332
+
5333
+ // ----------------------------------------------------------------
5334
+
5335
+ if(!stclients) stclients = rrd_stats_find("netdata.clients");
5336
+ if(!stclients) {
5337
+ stclients = rrd_stats_create("netdata", "clients", NULL, "netdata", "NetData Web Clients", "clients", 11000, update_every, CHART_TYPE_LINE);
5338
+
5339
+ rrd_stats_dimension_add(stclients, "clients", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE);
5340
+ }
5341
+ else rrd_stats_next(stclients);
5342
+
5343
+ rrd_stats_dimension_set(stclients, "clients", global_statistics.connected_clients);
5344
+ rrd_stats_done(stclients);
5345
+
5346
+ // ----------------------------------------------------------------
5347
+
5348
+ if(!streqs) streqs = rrd_stats_find("netdata.requests");
5349
+ if(!streqs) {
5350
+ streqs = rrd_stats_create("netdata", "requests", NULL, "netdata", "NetData Web Requests", "requests", 12000, update_every, CHART_TYPE_LINE);
5351
+
5352
+ rrd_stats_dimension_add(streqs, "requests", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5353
+ }
5354
+ else rrd_stats_next(streqs);
5355
+
5356
+ rrd_stats_dimension_set(streqs, "requests", global_statistics.web_requests);
5357
+ rrd_stats_done(streqs);
5358
+
5359
+ // ----------------------------------------------------------------
5360
+
5361
+ if(!stbytes) stbytes = rrd_stats_find("netdata.net");
5362
+ if(!stbytes) {
5363
+ stbytes = rrd_stats_create("netdata", "net", NULL, "netdata", "NetData Network Traffic", "kilobits/s", 13000, update_every, CHART_TYPE_AREA);
5364
+
5365
+ rrd_stats_dimension_add(stbytes, "in", NULL, 8, 1024, RRD_DIMENSION_INCREMENTAL);
5366
+ rrd_stats_dimension_add(stbytes, "out", NULL, -8, 1024, RRD_DIMENSION_INCREMENTAL);
5367
+ }
5368
+ else rrd_stats_next(stbytes);
5369
+
5370
+ rrd_stats_dimension_set(stbytes, "in", global_statistics.bytes_received);
5371
+ rrd_stats_dimension_set(stbytes, "out", global_statistics.bytes_sent);
5372
+ rrd_stats_done(stbytes);
5373
}
5374
5375
usleep(susec);
@@ -5362,12 +5464,7 @@ void tc_device_commit(struct tc_device *d)
5464
else {
5465
rrd_stats_next(st);
5466
5365
- if(strcmp(d->id, d->name) != 0) {
5366
- // update the device name with the new one
5367
- char buf[RRD_STATS_NAME_MAX + 1];
5368
- snprintf(buf, RRD_STATS_NAME_MAX, "%s.%s", st->type, d->name);
5369
- rrd_stats_set_name(st, buf);
5370
- }
5467
+ if(strcmp(d->id, d->name) != 0) rrd_stats_set_name(st, d->name);
5468
}
5469
5470
for ( c = d->classes ; c ; c = c->next) {