From aa16f87b87a71f6d70e8f43d62550913f18b64fa Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 2 Jul 2014 16:31:22 +0200 Subject: [PATCH] LATENCY GRAPH implemented. --- src/latency.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++- src/redis-cli.c | 5 ++-- src/sparkline.c | 3 +-- src/sparkline.h | 2 +- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/latency.c b/src/latency.c index af629bebd..e161a0705 100644 --- a/src/latency.c +++ b/src/latency.c @@ -140,6 +140,53 @@ void latencyCommandReplyWithLatestEvents(redisClient *c) { dictReleaseIterator(di); } +#define LATENCY_GRAPH_COLS 80 +sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { + int j; + struct sequence *seq = createSparklineSequence(); + sds graph = sdsempty(); + uint32_t min, max; + + for (j = 0; j < LATENCY_TS_LEN; j++) { + int i = (ts->idx + j) % LATENCY_TS_LEN; + int elapsed; + char *label; + char buf[64]; + + if (ts->samples[i].time == 0) continue; + /* Update min and max. */ + if (seq->length == 0) { + min = max = ts->samples[i].latency; + } else { + if (ts->samples[i].latency > max) max = ts->samples[i].latency; + if (ts->samples[i].latency < min) min = ts->samples[i].latency; + } + /* Use as label the number of seconds / minutes / hours / days + * ago the event happened. */ + elapsed = time(NULL) - ts->samples[i].time; + if (elapsed < 60) + snprintf(buf,sizeof(buf),"%ds",elapsed); + else if (elapsed < 3600) + snprintf(buf,sizeof(buf),"%dm",elapsed/60); + else if (elapsed < 3600*24) + snprintf(buf,sizeof(buf),"%dh",elapsed/3600); + else + snprintf(buf,sizeof(buf),"%dd",elapsed/(3600*24)); + label = zstrdup(buf); + sparklineSequenceAddSample(seq,ts->samples[i].latency,label); + } + + graph = sdscatprintf(graph, + "%s - high %lu ms, low %lu ms (all time high %lu ms)\n", event, + (unsigned long) max, (unsigned long) min, (unsigned long) ts->max); + for (j = 0; j < LATENCY_GRAPH_COLS; j++) + graph = sdscatlen(graph,"-",1); + graph = sdscatlen(graph,"\n",1); + graph = sparklineRender(graph,seq,LATENCY_GRAPH_COLS,4,SPARKLINE_NO_FLAGS); + freeSparklineSequence(seq); + return graph; +} + /* LATENCY command implementations. * * LATENCY SAMPLES: return time-latency samples for the specified event. @@ -155,12 +202,25 @@ void latencyCommand(redisClient *c) { ts = dictFetchValue(server.latency_events,c->argv[2]->ptr); if (ts == NULL) goto nodataerr; latencyCommandReplyWithSamples(c,ts); + } else if (!strcasecmp(c->argv[1]->ptr,"graph") && c->argc == 3) { + /* LATENCY GRAPH */ + sds graph; + dictEntry *de; + char *event; + + de = dictFind(server.latency_events,c->argv[2]->ptr); + if (de == NULL) goto nodataerr; + ts = dictGetVal(de); + event = dictGetKey(de); + + graph = latencyCommandGenSparkeline(event,ts); + addReplyBulkCString(c,graph); + sdsfree(graph); } else if (!strcasecmp(c->argv[1]->ptr,"latest") && c->argc == 2) { /* LATENCY LATEST */ latencyCommandReplyWithLatestEvents(c); } else { addReply(c,shared.syntaxerr); - return; } return; diff --git a/src/redis-cli.c b/src/redis-cli.c index cef86ef2d..782958b26 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -599,8 +599,9 @@ static int cliSendCommand(int argc, char **argv, int repeat) { (!strcasecmp(argv[1],"nodes") || !strcasecmp(argv[1],"info"))) || (argc == 2 && !strcasecmp(command,"client") && - !strcasecmp(argv[1],"list"))) - + !strcasecmp(argv[1],"list")) || + (argc == 3 && !strcasecmp(command,"latency") && + !strcasecmp(argv[1],"graph"))) { output_raw = 1; } diff --git a/src/sparkline.c b/src/sparkline.c index aeb8aa7da..900f26ab7 100644 --- a/src/sparkline.c +++ b/src/sparkline.c @@ -161,9 +161,8 @@ sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, } /* Turn a sequence into its ASCII representation */ -sds sparklineRender(struct sequence *seq, int columns, int rows, int flags) { +sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags) { int j; - sds output = sdsempty(); for (j = 0; j < seq->length; j += columns) { int sublen = (seq->length-j) < columns ? (seq->length-j) : columns; diff --git a/src/sparkline.h b/src/sparkline.h index 28fce1e4c..6025d2b98 100644 --- a/src/sparkline.h +++ b/src/sparkline.h @@ -51,6 +51,6 @@ struct sequence *createSparklineSequence(void); void sparklineSequenceAddSample(struct sequence *seq, double value, char *label); void freeSparklineSequence(struct sequence *seq); sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, int len, int flags); -sds sparklineRender(struct sequence *seq, int columns, int rows, int flags); +sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags); #endif /* __SPARKLINE_H */