Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
organize some stats into subtables
Browse files Browse the repository at this point in the history
stats conns, items, slabs return data like "id:stat val" - this change
pre-parses those values into sub-tables to make it easier to find and
iterate through related data.
dormando committed Apr 22, 2024
1 parent 645a69f commit 4a63383
Showing 3 changed files with 79 additions and 5 deletions.
45 changes: 43 additions & 2 deletions proxy_lua.c
Original file line number Diff line number Diff line change
@@ -32,6 +32,47 @@ static void _mcplib_append_stats(const char *key, const uint16_t klen,
lua_rawset(L, -3);
}

static void _mcplib_append_section_stats(const char *key, const uint16_t klen,
const char *val, const uint32_t vlen,
const void *cookie) {
char stat[STAT_KEY_LEN];
long section = 0;
if (klen == 0 && vlen > 0) {
return;
}
if (klen == 0 && vlen == 0) {
return;
}

const struct _mcplib_statctx_s *c = cookie;
lua_State *L = c->L;
// table must be at the top when this function is called.
int tidx = lua_absindex(L, -1);

if (sscanf(key, "items:%ld:%s", &section, stat) == 2
|| sscanf(key, "%ld:%s", &section, stat) == 2) {
// stats [items, slabs, conns]
if (lua_rawgeti(L, tidx, section) == LUA_TNIL) {
lua_pop(L, 1); // drop the nil
// no sub-section table yet, create one.
lua_newtable(L);
lua_pushvalue(L, -1); // copy the table
lua_rawseti(L, tidx, section); // remember the table
// now top of stack is the table.
}

lua_pushstring(L, stat);
lua_pushlstring(L, val, vlen);
lua_rawset(L, -3); // put key/val into sub-table
lua_pop(L, 1); // pop sub-table.
} else {
// normal stat counter.
lua_pushlstring(L, key, klen);
lua_pushlstring(L, val, vlen);
lua_rawset(L, tidx);
}
}

// reimplementation of proto_text.c:process_stat()
static int mcplib_server_stats(lua_State *L) {
int argc = lua_gettop(L);
@@ -49,7 +90,7 @@ static int mcplib_server_stats(lua_State *L) {
if (strcmp(cmd, "settings") == 0) {
process_stat_settings(&_mcplib_append_stats, &c);
} else if (strcmp(cmd, "conns") == 0) {
process_stats_conns(&_mcplib_append_stats, &c);
process_stats_conns(&_mcplib_append_section_stats, &c);
#ifdef EXTSTORE
} else if (strcmp(cmd, "extstore") == 0) {
process_extstore_stats(&_mcplib_append_stats, &c);
@@ -61,7 +102,7 @@ static int mcplib_server_stats(lua_State *L) {
} else if (strcmp(cmd, "proxybe") == 0) {
process_proxy_bestats(ctx, &_mcplib_append_stats, &c);
} else {
if (get_stats(cmd, strlen(cmd), &_mcplib_append_stats, &c)) {
if (get_stats(cmd, strlen(cmd), &_mcplib_append_section_stats, &c)) {
// all good.
} else {
// unknown command.
35 changes: 32 additions & 3 deletions t/proxyintstats.lua
Original file line number Diff line number Diff line change
@@ -19,19 +19,48 @@ function check_stats(cmd, min)
end
end

function check_stats_sections(cmd, minsec, minval)
local s = mcp.server_stats(cmd)

local sec = 0
local val = 0
for k, v in pairs(s) do
if type(k) == "number" then
sec = sec + 1
for sk, sv in pairs(v) do
val = val + 1
end
else
-- not a section.
end
end

if minsec and sec < minsec then
mcp.log("ERROR: ["..cmd.."] section count too low: " .. count)
return
end

if minval and val < minval then
mcp.log("ERROR: ["..cmd.."] value count too low: " .. count)
return
end

mcp.log("SUCCESS: " .. cmd)
end

function mcp_config_pools()
-- delay the stats run by a few seconds since some counters are weird
-- until initialization completes.
mcp.register_cron("stats", { every = 2, rerun = false, func = function()
check_stats(nil, 10)
check_stats("settings", 10)
check_stats("conns")
check_stats_sections("conns", 1, 2)
check_stats("extstore")
check_stats("proxy", 1)
check_stats("proxyfuncs", 1)
check_stats("proxybe")
check_stats("items")
check_stats("slabs", 1)
check_stats_sections("items", 1, 5)
check_stats_sections("slabs", 1, 5)
end })
end

4 changes: 4 additions & 0 deletions t/proxyintstats.t
Original file line number Diff line number Diff line change
@@ -24,6 +24,10 @@ my $w = $p_srv->new_sock;
print $w "watch proxyuser\n";
is(<$w>, "OK\r\n", "watcher enabled");

# store one value so items/slabs has data.
print $ps "set foo 0 0 2\r\nhi\r\n";
is(scalar <$ps>, "STORED\r\n", "test value stored");

my @stats = qw/basic settings conns extstore proxy proxyfuncs proxybe items slabs/;

for my $st (@stats) {

0 comments on commit 4a63383

Please sign in to comment.