summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2014-07-02 16:31:22 +0200
committerantirez <antirez@gmail.com>2014-07-02 16:31:22 +0200
commitaa16f87b87a71f6d70e8f43d62550913f18b64fa (patch)
tree84f16e00e39728ea62143858d4bfaf93a16a10e9
parent6f20482a8695d8f8313caea11927a39ce1c5fdb7 (diff)
downloadredis-aa16f87b87a71f6d70e8f43d62550913f18b64fa.tar.gz
LATENCY GRAPH implemented.
-rw-r--r--src/latency.c62
-rw-r--r--src/redis-cli.c5
-rw-r--r--src/sparkline.c3
-rw-r--r--src/sparkline.h2
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 <event> */
+ 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 */