From 4a6338360fafcd1c8db1a1a50a502618977667d7 Mon Sep 17 00:00:00 2001 From: dormando Date: Mon, 22 Apr 2024 14:30:25 -0700 Subject: [PATCH] organize some stats into subtables 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. --- proxy_lua.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- t/proxyintstats.lua | 35 ++++++++++++++++++++++++++++++++--- t/proxyintstats.t | 4 ++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/proxy_lua.c b/proxy_lua.c index aa95f60118..801d16fa17 100644 --- a/proxy_lua.c +++ b/proxy_lua.c @@ -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", §ion, stat) == 2 + || sscanf(key, "%ld:%s", §ion, 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. diff --git a/t/proxyintstats.lua b/t/proxyintstats.lua index 16b224137c..42ee0c7073 100644 --- a/t/proxyintstats.lua +++ b/t/proxyintstats.lua @@ -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 diff --git a/t/proxyintstats.t b/t/proxyintstats.t index d496f2febe..319dc29c1a 100644 --- a/t/proxyintstats.t +++ b/t/proxyintstats.t @@ -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) {