mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
show subcommands latencystats (#10103)
since `info commandstats` already shows sub-commands, we should do the same in `info latencystats`. similarly, the LATENCY HISTOGRAM command now shows sub-commands (with their full name) when: * asking for all commands * asking for a specific container command * asking for a specific sub-command) Co-authored-by: Oran Agra <oran@redislabs.com>
This commit is contained in:
parent
26ef5132a6
commit
90916f16a5
@ -530,11 +530,22 @@ void latencyAllCommandsFillCDF(client *c) {
|
|||||||
int command_with_data = 0;
|
int command_with_data = 0;
|
||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
cmd = (struct redisCommand *) dictGetVal(de);
|
cmd = (struct redisCommand *) dictGetVal(de);
|
||||||
if (!cmd->latency_histogram)
|
if (cmd->latency_histogram) {
|
||||||
continue;
|
addReplyBulkCString(c,cmd->name);
|
||||||
addReplyBulkCString(c,cmd->name);
|
fillCommandCDF(c, cmd->latency_histogram);
|
||||||
fillCommandCDF(c, cmd->latency_histogram);
|
command_with_data++;
|
||||||
command_with_data++;
|
}
|
||||||
|
|
||||||
|
if (cmd->subcommands) {
|
||||||
|
for (int j = 0; cmd->subcommands[j].name; j++) {
|
||||||
|
struct redisCommand *sub = cmd->subcommands+j;
|
||||||
|
if (sub->latency_histogram) {
|
||||||
|
addReplyBulkSds(c,getFullCommandName(sub));
|
||||||
|
fillCommandCDF(c, sub->latency_histogram);
|
||||||
|
command_with_data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
setDeferredMapLen(c,replylen,command_with_data);
|
setDeferredMapLen(c,replylen,command_with_data);
|
||||||
@ -546,18 +557,28 @@ void latencySpecificCommandsFillCDF(client *c) {
|
|||||||
void *replylen = addReplyDeferredLen(c);
|
void *replylen = addReplyDeferredLen(c);
|
||||||
int command_with_data = 0;
|
int command_with_data = 0;
|
||||||
for (int j = 2; j < c->argc; j++){
|
for (int j = 2; j < c->argc; j++){
|
||||||
struct redisCommand *cmd = dictFetchValue(server.commands, c->argv[j]->ptr);
|
struct redisCommand *cmd = lookupCommandBySds(c->argv[j]->ptr);
|
||||||
/* If the command does not exist we skip the reply */
|
/* If the command does not exist we skip the reply */
|
||||||
if (cmd == NULL) {
|
if (cmd == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* If no latency info we reply with the same format as non empty histograms */
|
|
||||||
if (!cmd->latency_histogram) {
|
if (cmd->latency_histogram) {
|
||||||
continue;
|
addReplyBulkSds(c,getFullCommandName(cmd));
|
||||||
|
fillCommandCDF(c, cmd->latency_histogram);
|
||||||
|
command_with_data++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->subcommands) {
|
||||||
|
for (int j = 0; cmd->subcommands[j].name; j++) {
|
||||||
|
struct redisCommand *sub = cmd->subcommands+j;
|
||||||
|
if (sub->latency_histogram) {
|
||||||
|
addReplyBulkSds(c,getFullCommandName(sub));
|
||||||
|
fillCommandCDF(c, sub->latency_histogram);
|
||||||
|
command_with_data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addReplyBulkCString(c,c->argv[j]->ptr);
|
|
||||||
fillCommandCDF(c, cmd->latency_histogram);
|
|
||||||
command_with_data++;
|
|
||||||
}
|
}
|
||||||
setDeferredMapLen(c,replylen,command_with_data);
|
setDeferredMapLen(c,replylen,command_with_data);
|
||||||
}
|
}
|
||||||
|
40
src/server.c
40
src/server.c
@ -4808,6 +4808,32 @@ sds genRedisInfoStringCommandStats(sds info, dict *commands) {
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sds genRedisInfoStringLatencyStats(sds info, dict *commands) {
|
||||||
|
struct redisCommand *c;
|
||||||
|
dictEntry *de;
|
||||||
|
dictIterator *di;
|
||||||
|
di = dictGetSafeIterator(commands);
|
||||||
|
while((de = dictNext(di)) != NULL) {
|
||||||
|
char *tmpsafe;
|
||||||
|
c = (struct redisCommand *) dictGetVal(de);
|
||||||
|
if (c->latency_histogram) {
|
||||||
|
sds cmdnamesds = getFullCommandName(c);
|
||||||
|
|
||||||
|
info = fillPercentileDistributionLatencies(info,
|
||||||
|
getSafeInfoString(cmdnamesds, sdslen(cmdnamesds), &tmpsafe),
|
||||||
|
c->latency_histogram);
|
||||||
|
if (tmpsafe != NULL) zfree(tmpsafe);
|
||||||
|
sdsfree(cmdnamesds);
|
||||||
|
}
|
||||||
|
if (c->subcommands_dict) {
|
||||||
|
info = genRedisInfoStringLatencyStats(info, c->subcommands_dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dictReleaseIterator(di);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the string returned by the INFO command. This is decoupled
|
/* Create the string returned by the INFO command. This is decoupled
|
||||||
* by the INFO command itself as we need to report the same information
|
* by the INFO command itself as we need to report the same information
|
||||||
* on memory corruption problems. */
|
* on memory corruption problems. */
|
||||||
@ -5518,19 +5544,7 @@ sds genRedisInfoString(const char *section) {
|
|||||||
if (sections++) info = sdscat(info,"\r\n");
|
if (sections++) info = sdscat(info,"\r\n");
|
||||||
info = sdscatprintf(info, "# Latencystats\r\n");
|
info = sdscatprintf(info, "# Latencystats\r\n");
|
||||||
if (server.latency_tracking_enabled) {
|
if (server.latency_tracking_enabled) {
|
||||||
struct redisCommand *c;
|
info = genRedisInfoStringLatencyStats(info, server.commands);
|
||||||
dictEntry *de;
|
|
||||||
dictIterator *di;
|
|
||||||
di = dictGetSafeIterator(server.commands);
|
|
||||||
while((de = dictNext(di)) != NULL) {
|
|
||||||
char *tmpsafe;
|
|
||||||
c = (struct redisCommand *) dictGetVal(de);
|
|
||||||
if (!c->latency_histogram)
|
|
||||||
continue;
|
|
||||||
info = fillPercentileDistributionLatencies(info,getSafeInfoString(c->name, strlen(c->name), &tmpsafe),c->latency_histogram);
|
|
||||||
if (tmpsafe != NULL) zfree(tmpsafe);
|
|
||||||
}
|
|
||||||
dictReleaseIterator(di);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,16 @@ start_server {tags {"info" "external:skip"}} {
|
|||||||
$rd close
|
$rd close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {latencystats: subcommands} {
|
||||||
|
r config resetstat
|
||||||
|
r CONFIG SET latency-tracking yes
|
||||||
|
r CONFIG SET latency-tracking-info-percentiles "50.0 99.0 99.9"
|
||||||
|
r client id
|
||||||
|
|
||||||
|
assert_match {*p50=*,p99=*,p99.9=*} [latency_percentiles_usec client\\|id]
|
||||||
|
assert_match {*p50=*,p99=*,p99.9=*} [latency_percentiles_usec config\\|set]
|
||||||
|
}
|
||||||
|
|
||||||
test {latencystats: measure latency} {
|
test {latencystats: measure latency} {
|
||||||
r config resetstat
|
r config resetstat
|
||||||
r CONFIG SET latency-tracking yes
|
r CONFIG SET latency-tracking yes
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
proc latency_histogram {cmd} {
|
|
||||||
return [lindex [r latency histogram $cmd] 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
start_server {tags {"latency-monitor needs:latency"}} {
|
start_server {tags {"latency-monitor needs:latency"}} {
|
||||||
# Set a threshold high enough to avoid spurious latency events.
|
# Set a threshold high enough to avoid spurious latency events.
|
||||||
r config set latency-monitor-threshold 200
|
r config set latency-monitor-threshold 200
|
||||||
@ -9,15 +5,34 @@ start_server {tags {"latency-monitor needs:latency"}} {
|
|||||||
|
|
||||||
test {LATENCY HISTOGRAM with empty histogram} {
|
test {LATENCY HISTOGRAM with empty histogram} {
|
||||||
r config resetstat
|
r config resetstat
|
||||||
assert_match {} [latency_histogram set]
|
set histo [dict create {*}[r latency histogram]]
|
||||||
assert {[llength [r latency histogram]] == 0}
|
# Config resetstat is recorded
|
||||||
|
assert_equal [dict size $histo] 1
|
||||||
}
|
}
|
||||||
|
|
||||||
test {LATENCY HISTOGRAM all commands} {
|
test {LATENCY HISTOGRAM all commands} {
|
||||||
r config resetstat
|
r config resetstat
|
||||||
r set a b
|
r set a b
|
||||||
r set c d
|
r set c d
|
||||||
assert_match {calls 2 histogram_usec *} [latency_histogram set]
|
set histo [dict create {*}[r latency histogram]]
|
||||||
|
assert_match {calls 2 histogram_usec *} [dict get $histo set]
|
||||||
|
assert_match {calls 1 histogram_usec *} [dict get $histo "config|resetstat"]
|
||||||
|
}
|
||||||
|
|
||||||
|
test {LATENCY HISTOGRAM sub commands} {
|
||||||
|
r config resetstat
|
||||||
|
r client id
|
||||||
|
r client list
|
||||||
|
# parent command reply with its sub commands
|
||||||
|
set histo [dict create {*}[r latency histogram client]]
|
||||||
|
assert {[dict size $histo] == 2}
|
||||||
|
assert_match {calls 1 histogram_usec *} [dict get $histo "client|id"]
|
||||||
|
assert_match {calls 1 histogram_usec *} [dict get $histo "client|list"]
|
||||||
|
|
||||||
|
# explicitly ask for one sub-command
|
||||||
|
set histo [dict create {*}[r latency histogram "client|id"]]
|
||||||
|
assert {[dict size $histo] == 1}
|
||||||
|
assert_match {calls 1 histogram_usec *} [dict get $histo "client|id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
test {LATENCY HISTOGRAM with a subset of commands} {
|
test {LATENCY HISTOGRAM with a subset of commands} {
|
||||||
@ -27,19 +42,20 @@ start_server {tags {"latency-monitor needs:latency"}} {
|
|||||||
r get a
|
r get a
|
||||||
r hset f k v
|
r hset f k v
|
||||||
r hgetall f
|
r hgetall f
|
||||||
assert_match {calls 2 histogram_usec *} [latency_histogram set]
|
set histo [dict create {*}[r latency histogram set hset]]
|
||||||
assert_match {calls 1 histogram_usec *} [latency_histogram hset]
|
assert_match {calls 2 histogram_usec *} [dict get $histo set]
|
||||||
assert_match {calls 1 histogram_usec *} [latency_histogram hgetall]
|
assert_match {calls 1 histogram_usec *} [dict get $histo hset]
|
||||||
assert_match {calls 1 histogram_usec *} [latency_histogram get]
|
assert_equal [dict size $histo] 2
|
||||||
assert {[llength [r latency histogram]] == 8}
|
set histo [dict create {*}[r latency histogram hgetall get zadd]]
|
||||||
assert {[llength [r latency histogram set get]] == 4}
|
assert_match {calls 1 histogram_usec *} [dict get $histo hgetall]
|
||||||
|
assert_match {calls 1 histogram_usec *} [dict get $histo get]
|
||||||
|
assert_equal [dict size $histo] 2
|
||||||
}
|
}
|
||||||
|
|
||||||
test {LATENCY HISTOGRAM command} {
|
test {LATENCY HISTOGRAM command} {
|
||||||
r config resetstat
|
r config resetstat
|
||||||
r set a b
|
r set a b
|
||||||
r get a
|
r get a
|
||||||
assert {[llength [r latency histogram]] == 4}
|
|
||||||
assert {[llength [r latency histogram set get]] == 4}
|
assert {[llength [r latency histogram set get]] == 4}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user