| 532 | |
| 533 | #define LATENCY_GRAPH_COLS 80 |
| 534 | sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { |
| 535 | int j; |
| 536 | struct sequence *seq = createSparklineSequence(); |
| 537 | sds graph = sdsempty(); |
| 538 | uint32_t min = 0, max = 0; |
| 539 | |
| 540 | for (j = 0; j < LATENCY_TS_LEN; j++) { |
| 541 | int i = (ts->idx + j) % LATENCY_TS_LEN; |
| 542 | int elapsed; |
| 543 | char buf[64]; |
| 544 | |
| 545 | if (ts->samples[i].time == 0) continue; |
| 546 | /* Update min and max. */ |
| 547 | if (seq->length == 0) { |
| 548 | min = max = ts->samples[i].latency; |
| 549 | } else { |
| 550 | if (ts->samples[i].latency > max) max = ts->samples[i].latency; |
| 551 | if (ts->samples[i].latency < min) min = ts->samples[i].latency; |
| 552 | } |
| 553 | /* Use as label the number of seconds / minutes / hours / days |
| 554 | * ago the event happened. */ |
| 555 | elapsed = time(NULL) - ts->samples[i].time; |
| 556 | if (elapsed < 60) |
| 557 | snprintf(buf,sizeof(buf),"%ds",elapsed); |
| 558 | else if (elapsed < 3600) |
| 559 | snprintf(buf,sizeof(buf),"%dm",elapsed/60); |
| 560 | else if (elapsed < 3600*24) |
| 561 | snprintf(buf,sizeof(buf),"%dh",elapsed/3600); |
| 562 | else |
| 563 | snprintf(buf,sizeof(buf),"%dd",elapsed/(3600*24)); |
| 564 | sparklineSequenceAddSample(seq,ts->samples[i].latency,buf); |
| 565 | } |
| 566 | |
| 567 | graph = sdscatprintf(graph, |
| 568 | "%s - high %lu ms, low %lu ms (all time high %lu ms)\n", event, |
| 569 | (unsigned long) max, (unsigned long) min, (unsigned long) ts->max); |
| 570 | for (j = 0; j < LATENCY_GRAPH_COLS; j++) |
| 571 | graph = sdscatlen(graph,"-",1); |
| 572 | graph = sdscatlen(graph,"\n",1); |
| 573 | graph = sparklineRender(graph,seq,LATENCY_GRAPH_COLS,4,SPARKLINE_FILL); |
| 574 | freeSparklineSequence(seq); |
| 575 | return graph; |
| 576 | } |
| 577 | |
| 578 | /* LATENCY command implementations. |
| 579 | * |
no test coverage detected