Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input output traffic stats and command process count for each client. #327

Merged
merged 8 commits into from May 6, 2024
1 change: 1 addition & 0 deletions src/blocked.c
Expand Up @@ -107,6 +107,7 @@ void updateStatsOnUnblock(client *c, long blocked_us, long reply_us, int had_err
const ustime_t total_cmd_duration = c->duration + blocked_us + reply_us;
c->lastcmd->microseconds += total_cmd_duration;
c->lastcmd->calls++;
c->commands_processed++;
server.stat_numcommands++;
if (had_errors)
c->lastcmd->failed_calls++;
Expand Down
10 changes: 9 additions & 1 deletion src/networking.c
Expand Up @@ -214,6 +214,9 @@ client *createClient(connection *conn) {
c->mem_usage_bucket_node = NULL;
if (conn) linkClient(c);
initClientMultiState(c);
c->net_input_bytes = 0;
c->net_output_bytes = 0;
c->commands_processed = 0;
return c;
}

Expand Down Expand Up @@ -1989,6 +1992,7 @@ int writeToClient(client *c, int handler_installed) {
if (getClientType(c) == CLIENT_TYPE_SLAVE) {
atomicIncr(server.stat_net_repl_output_bytes, totwritten);
} else {
c->net_output_bytes += totwritten;
atomicIncr(server.stat_net_output_bytes, totwritten);
}

Expand Down Expand Up @@ -2716,6 +2720,7 @@ void readQueryFromClient(connection *conn) {
c->read_reploff += nread;
atomicIncr(server.stat_net_repl_input_bytes, nread);
} else {
c->net_input_bytes += nread;
madolson marked this conversation as resolved.
Show resolved Hide resolved
atomicIncr(server.stat_net_input_bytes, nread);
}

Expand Down Expand Up @@ -2874,7 +2879,10 @@ sds catClientInfoString(sds s, client *client) {
" redir=%I", (client->flags & CLIENT_TRACKING) ? (long long) client->client_tracking_redirection : -1,
" resp=%i", client->resp,
" lib-name=%s", client->lib_name ? (char*)client->lib_name->ptr : "",
" lib-ver=%s", client->lib_ver ? (char*)client->lib_ver->ptr : ""));
" lib-ver=%s", client->lib_ver ? (char*)client->lib_ver->ptr : "",
" tot-input=%U", client->net_input_bytes,
" tot-output=%U", client->net_output_bytes,
enjoy-binbin marked this conversation as resolved.
Show resolved Hide resolved
" tot-cmds=%U", client->commands_processed));
return ret;
}

Expand Down
4 changes: 3 additions & 1 deletion src/server.c
Expand Up @@ -3716,8 +3716,10 @@ void call(client *c, int flags) {
}
}

if (!(c->flags & CLIENT_BLOCKED))
if (!(c->flags & CLIENT_BLOCKED)) {
c->commands_processed++;
madolson marked this conversation as resolved.
Show resolved Hide resolved
server.stat_numcommands++;
}

/* Record peak memory after each command and before the eviction that runs
* before the next command. */
Expand Down
3 changes: 3 additions & 0 deletions src/server.h
Expand Up @@ -1282,6 +1282,9 @@ typedef struct client {
#ifdef LOG_REQ_RES
clientReqResInfo reqres;
#endif
unsigned long long net_input_bytes;
unsigned long long net_output_bytes;
unsigned long long commands_processed;
enjoy-binbin marked this conversation as resolved.
Show resolved Hide resolved
} client;

/* ACL information */
Expand Down
30 changes: 28 additions & 2 deletions tests/unit/introspection.tcl
Expand Up @@ -7,7 +7,7 @@ start_server {tags {"introspection"}} {

test {CLIENT LIST} {
r client list
} {id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 watch=0 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|list user=* redir=-1 resp=*}
} {id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 watch=0 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|list user=* redir=-1 resp=* tot-input=* tot-output=* tot-cmds=*}

test {CLIENT LIST with IDs} {
set myid [r client id]
Expand All @@ -17,7 +17,33 @@ start_server {tags {"introspection"}} {

test {CLIENT INFO} {
r client info
} {id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 watch=0 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|info user=* redir=-1 resp=*}
} {id=* addr=*:* laddr=*:* fd=* name=* age=* idle=* flags=N db=* sub=0 psub=0 ssub=0 multi=-1 watch=0 qbuf=26 qbuf-free=* argv-mem=* multi-mem=0 rbs=* rbp=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client|info user=* redir=-1 resp=* tot-input=* tot-output=* tot-cmds=*}

proc get_field_in_client_info {info field} {
set info [string trim $info]
foreach item [split $info " "] {
set kv [split $item "="]
set k [lindex $kv 0]
if {[string match $field $k]} {
return [lindex $kv 1]
}
}
return ""
}

test {client input output and command process statistics} {
madolson marked this conversation as resolved.
Show resolved Hide resolved
set info1 [r client info]
set input1 [get_field_in_client_info $info1 "tot-input"]
set output1 [get_field_in_client_info $info1 "tot-output"]
set cmd1 [get_field_in_client_info $info1 "tot-cmds"]
set info2 [r client info]
set input2 [get_field_in_client_info $info2 "tot-input"]
set output2 [get_field_in_client_info $info2 "tot-output"]
set cmd2 [get_field_in_client_info $info2 "tot-cmds"]
assert_equal [expr $input1+26] $input2
assert {[expr $output1+300] < $output2}
assert_equal [expr $cmd1+1] $cmd2
}

test {CLIENT KILL with illegal arguments} {
assert_error "ERR wrong number of arguments for 'client|kill' command" {r client kill}
Expand Down