fix for infinite loop
Costa Tsaousis (ktsaou) committed
Mar 23, 2014 at 05:06 UTC
00799ba6de99a5ebe24ec89321bc2c3aecf9f459
1 file changed
+31
-12
netdata.c
+31
-12
@@ -434,13 +434,26 @@ void rrd_stats_dimension_set(RRD_STATS *st, const char *dimension, void *data)
434
435
size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_show, size_t group_count, int group_method)
436
{
437
- size_t i = 0, c, t, lt, printed = 0, dimensions = 0, last_entry = st->last_entry;
438
- int pad = 0;
439
- long count = st->entries;
437
+ // check the options
438
+ if(entries_to_show <= 0) entries_to_show = 1;
439
+ if(group_count <= 0) group_count = 1;
440
+ if(group_count > st->entries / 20) group_count = st->entries / 20;
441
+
442
+ size_t i = 0; // the bytes of JSON output we have generated so far
443
+ size_t printed = 0; // the lines of JSON data we have generated so far
444
+
445
+ size_t last_entry = st->last_entry;
446
+ size_t t, lt; // t = the current entry, lt = the lest entry of data
447
+ long count = st->entries; // count down of the entries examined so far
448
+ int pad = 0; // align the entries when grouping values together
449
+
450
RRD_DIMENSION *rd;
441
- unsigned long long usec = 0;
442
- long long value;
443
- char dtm[1025];
451
+ size_t c = 0; // counter for dimension loops
452
+ size_t dimensions = 0; // the total number of dimensions present
453
+
454
+ unsigned long long usec = 0;// usec between the entries
455
+ long long value; // temp variable for storing data values
456
+ char dtm[201]; // temp variable for storing dates
457
458
// find how many dimensions we have
459
for( rd = st->dimensions ; rd ; rd = rd->next)
@@ -449,7 +462,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
462
if(!dimensions)
463
return sprintf(b, "No dimensions yet.");
464
452
- // keep track of group values and counts
465
+ // temporary storage to keep track of group values and counts
466
long long group_values[dimensions];
467
long long group_counts[dimensions];
468
for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++)
@@ -458,7 +471,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
471
i += sprintf(&b[i], "{\n \"cols\":\n [\n");
472
i += sprintf(&b[i], " {\"id\":\"\",\"label\":\"time\",\"pattern\":\"\",\"type\":\"timeofday\"},\n");
473
461
- for( rd = st->dimensions ; rd ; rd = rd->next)
474
+ for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++)
475
i += sprintf(&b[i], " {\"id\":\"\",\"label\":\"%s\",\"pattern\":\"\",\"type\":\"number\"}%s\n", rd->name, rd->next?",":"");
476
477
i += sprintf(&b[i], " ],\n \"rows\":\n [\n");
@@ -466,6 +479,9 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
479
// to allow grouping on the same values, we need a pad
480
pad = last_entry % group_count;
481
482
+ // make sure last_entry is within limits
483
+ if(last_entry < 0 || last_entry >= st->entries) last_entry = 0;
484
+
485
// find the old entry of the round-robin
486
t = last_entry + 1;
487
if(t >= st->entries) t = 0;
@@ -477,8 +493,8 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
493
494
// the loop in dimension data
495
count -= 2;
480
- for ( ; t != last_entry ; lt = t++, count--) {
481
- if(t >= st->entries) t = 0;
496
+ for ( ; t != last_entry && count >= 0 ; lt = t++, count--) {
497
+ if(t >= st->entries) t = 0;
498
499
// if the last is empty, loop again
500
if(!st->times[lt].tv_sec) continue;
@@ -486,9 +502,13 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
502
// check if we may exceed the buffer provided
503
if((length - i) < 1024) break;
504
505
+ // prefer the most recent last entries
506
if(((count-pad) / group_count) > entries_to_show) continue;
507
508
+
509
+ // ok. we will use this entry!
510
// find how much usec since the previous entry
511
+
512
usec = usecdiff(&st->times[t], &st->times[lt]);
513
514
if(((count-pad) % group_count) == 0) {
@@ -498,7 +518,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
518
struct tm *tm = localtime(&st->times[t].tv_sec);
519
if(!tm) { error("localtime() failed."); continue; }
520
501
- strftime(dtm, 1024, "[%H, %M, %S, 0]", tm);
521
+ strftime(dtm, 200, "[%H, %M, %S, 0]", tm);
522
i += sprintf(&b[i], "%s {\"c\":[{\"v\":%s},", printed?"]},\n":"", dtm);
523
524
printed++;
@@ -547,7 +567,6 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
567
if(printed) i += sprintf(&b[i], "]}");
568
i += sprintf(&b[i], "\n ]\n}\n");
569
550
- if(count != 0) error("RRD count should be zero, but found to be %d.", count);
570
return(i);
571
}
572