[PATCH] Improve box.stat.net output

Vladimir Davydov vdavydov.dev at gmail.com
Fri Apr 12 21:17:29 MSK 2019


 - Add REQUESTS.current to report the number of requests currently in
   flight, because it's useful for understanding whether we need to
   increase box.cfg.net_msg_max.
 - Add REQUESTS.{rps,total}, because knowing the number of requests
   processed per second can come in handy for performance analysis.
 - Add CONNECTIONS.{rps,total} that show the number of connections
   opened per second and total. Those are not really necessary, but
   without them the output looks kinda lopsided.

Now the output looks like this:

 | ---
 | - SENT:
 |     total: 5344924
 |     rps: 840212
 |   CONNECTIONS:
 |     current: 60
 |     rps: 148
 |     total: 949
 |   REQUESTS:
 |     current: 17
 |     rps: 1936
 |     total: 12139
 |   RECEIVED:
 |     total: 240882
 |     rps: 38428
 | ...

Closes #4150
---
https://github.com/tarantool/tarantool/issues/4150
https://github.com/tarantool/tarantool/commits/dv/gh-4150-improve-net-stat

 src/box/iproto.cc          | 17 ++++++++-
 src/box/iproto.h           |  6 +++
 src/box/lua/stat.c         | 33 +++++++++++-----
 test/box/stat_net.result   | 95 ++++++++++++++++++++++++++++++++++++++++++++--
 test/box/stat_net.test.lua | 29 ++++++++++++--
 5 files changed, 163 insertions(+), 17 deletions(-)

diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 6967f28e..10b6a679 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -268,10 +268,17 @@ struct rmean *rmean_net;
 enum rmean_net_name {
 	IPROTO_SENT,
 	IPROTO_RECEIVED,
+	IPROTO_CONNECTIONS,
+	IPROTO_REQUESTS,
 	IPROTO_LAST,
 };
 
-const char *rmean_net_strings[IPROTO_LAST] = { "SENT", "RECEIVED" };
+const char *rmean_net_strings[IPROTO_LAST] = {
+	"SENT",
+	"RECEIVED",
+	"CONNECTIONS",
+	"REQUESTS",
+};
 
 static void
 tx_process_destroy(struct cmsg *m);
@@ -506,6 +513,7 @@ iproto_msg_new(struct iproto_connection *con)
 		return NULL;
 	}
 	msg->connection = con;
+	rmean_collect(rmean_net, IPROTO_REQUESTS, 1);
 	return msg;
 }
 
@@ -1042,6 +1050,7 @@ iproto_connection_new(int fd)
 	con->is_destroy_sent = false;
 	con->tx.is_push_pending = false;
 	con->tx.is_push_sent = false;
+	rmean_collect(rmean_net, IPROTO_CONNECTIONS, 1);
 	return con;
 }
 
@@ -2144,6 +2153,12 @@ iproto_connection_count(void)
 	return mempool_count(&iproto_connection_pool);
 }
 
+size_t
+iproto_request_count(void)
+{
+	return mempool_count(&iproto_msg_pool);
+}
+
 void
 iproto_reset_stat(void)
 {
diff --git a/src/box/iproto.h b/src/box/iproto.h
index 7916705e..edb24a7e 100644
--- a/src/box/iproto.h
+++ b/src/box/iproto.h
@@ -69,6 +69,12 @@ size_t
 iproto_connection_count(void);
 
 /**
+ * Return the number of iproto requests in flight.
+ */
+size_t
+iproto_request_count(void);
+
+/**
  * Reset network statistics.
  */
 void
diff --git a/src/box/lua/stat.c b/src/box/lua/stat.c
index 18b81a1b..eee2b104 100644
--- a/src/box/lua/stat.c
+++ b/src/box/lua/stat.c
@@ -148,14 +148,20 @@ lbox_stat_reset(struct lua_State *L)
 static int
 lbox_stat_net_index(struct lua_State *L)
 {
-	luaL_checkstring(L, -1);
-	if (strcmp("CONNECTIONS", lua_tostring(L, -1)) == 0) {
-		lua_newtable(L);
+	const char *key = luaL_checkstring(L, -1);
+	if (rmean_foreach(rmean_net, seek_stat_item, L) == 0)
+		return 0;
+
+	if (strcmp(key, "CONNECTIONS") == 0) {
+		lua_pushstring(L, "current");
 		lua_pushnumber(L, iproto_connection_count());
-		lua_setfield(L, -2, "current");
-		return 1;
+		lua_rawset(L, -3);
+	} else if (strcmp(key, "REQUESTS") == 0) {
+		lua_pushstring(L, "current");
+		lua_pushnumber(L, iproto_request_count());
+		lua_rawset(L, -3);
 	}
-	return rmean_foreach(rmean_net, seek_stat_item, L);
+	return 1;
 }
 
 /**
@@ -180,10 +186,19 @@ lbox_stat_net_call(struct lua_State *L)
 	lua_newtable(L);
 	rmean_foreach(rmean_net, set_stat_item, L);
 
-	lua_newtable(L); /* box.stat.net().CONNECTIONS */
+	lua_pushstring(L, "CONNECTIONS");
+	lua_rawget(L, -2);
+	lua_pushstring(L, "current");
 	lua_pushnumber(L, iproto_connection_count());
-	lua_setfield(L, -2, "current");
-	lua_setfield(L, -2, "CONNECTIONS");
+	lua_rawset(L, -3);
+	lua_pop(L, 1);
+
+	lua_pushstring(L, "REQUESTS");
+	lua_rawget(L, -2);
+	lua_pushstring(L, "current");
+	lua_pushnumber(L, iproto_request_count());
+	lua_rawset(L, -3);
+	lua_pop(L, 1);
 
 	return 1;
 }
diff --git a/test/box/stat_net.result b/test/box/stat_net.result
index 36a78a8a..92f6d581 100644
--- a/test/box/stat_net.result
+++ b/test/box/stat_net.result
@@ -16,6 +16,18 @@ box.stat.net.RECEIVED -- zero
 - total: 0
   rps: 0
 ...
+box.stat.net.CONNECTIONS -- zero
+---
+- current: 0
+  rps: 0
+  total: 0
+...
+box.stat.net.REQUESTS -- zero
+---
+- current: 0
+  rps: 0
+  total: 0
+...
 space = box.schema.space.create('tweedledum')
 ---
 ...
@@ -25,6 +37,18 @@ box.schema.user.grant('guest', 'read', 'space', 'tweedledum')
 index = space:create_index('primary', { type = 'hash' })
 ---
 ...
+ch = require('fiber').channel(1)
+---
+...
+function tweedledee() ch:get() end
+---
+...
+box.schema.func.create('tweedledee')
+---
+...
+box.schema.user.grant('guest', 'execute', 'function', 'tweedledee')
+---
+...
 remote = require 'net.box'
 ---
 ...
@@ -55,12 +79,22 @@ box.stat.net.RECEIVED.total > 0
 ---
 - true
 ...
-box.stat.net.CONNECTIONS.current == 4
+box.stat.net.CONNECTIONS.total
 ---
-- true
+- 4
+...
+box.stat.net.REQUESTS.total
+---
+- 13
+...
+box.stat.net.CONNECTIONS.current
+---
+- 4
+...
+box.stat.net.REQUESTS.current
+---
+- 0
 ...
--- box.stat.net.EVENTS.total > 0
--- box.stat.net.LOCKS.total > 0
 WAIT_COND_TIMEOUT = 10
 ---
 ...
@@ -81,6 +115,44 @@ test_run:wait_cond(function() return box.stat.net.CONNECTIONS.current == 1 end,
 ---
 - true
 ...
+future1 = cn:call('tweedledee', {}, {is_async = true})
+---
+...
+test_run:wait_cond(function() return box.stat.net.REQUESTS.current == 1 end, WAIT_COND_TIMEOUT)
+---
+- true
+...
+future2 = cn:call('tweedledee', {}, {is_async = true})
+---
+...
+test_run:wait_cond(function() return box.stat.net.REQUESTS.current == 2 end, WAIT_COND_TIMEOUT)
+---
+- true
+...
+ch:put(true)
+---
+- true
+...
+ch:put(true)
+---
+- true
+...
+future1:wait_result()
+---
+- []
+...
+future2:wait_result()
+---
+- []
+...
+test_run:wait_cond(function() return box.stat.net.REQUESTS.current == 0 end, WAIT_COND_TIMEOUT)
+---
+- true
+...
+box.stat.net.REQUESTS.total
+---
+- 15
+...
 -- reset
 box.stat.reset()
 ---
@@ -93,10 +165,25 @@ box.stat.net.RECEIVED.total
 ---
 - 0
 ...
+box.stat.net.CONNECTIONS.total
+---
+- 0
+...
+box.stat.net.REQUESTS.total
+---
+- 0
+...
 box.stat.net.CONNECTIONS.current
 ---
 - 1
 ...
+box.stat.net.REQUESTS.current
+---
+- 0
+...
+box.schema.func.drop('tweedledee')
+---
+...
 space:drop() -- tweedledum
 ---
 ...
diff --git a/test/box/stat_net.test.lua b/test/box/stat_net.test.lua
index 24ecf138..830deb36 100644
--- a/test/box/stat_net.test.lua
+++ b/test/box/stat_net.test.lua
@@ -5,10 +5,17 @@ test_run:cmd('restart server default')
 
 box.stat.net.SENT -- zero
 box.stat.net.RECEIVED -- zero
+box.stat.net.CONNECTIONS -- zero
+box.stat.net.REQUESTS -- zero
 
 space = box.schema.space.create('tweedledum')
 box.schema.user.grant('guest', 'read', 'space', 'tweedledum')
 index = space:create_index('primary', { type = 'hash' })
+
+ch = require('fiber').channel(1)
+function tweedledee() ch:get() end
+box.schema.func.create('tweedledee')
+box.schema.user.grant('guest', 'execute', 'function', 'tweedledee')
 remote = require 'net.box'
 
 LISTEN = require('uri').parse(box.cfg.listen)
@@ -21,9 +28,10 @@ cn.space.tweedledum:select() --small request
 
 box.stat.net.SENT.total > 0
 box.stat.net.RECEIVED.total > 0
-box.stat.net.CONNECTIONS.current == 4
--- box.stat.net.EVENTS.total > 0
--- box.stat.net.LOCKS.total > 0
+box.stat.net.CONNECTIONS.total
+box.stat.net.REQUESTS.total
+box.stat.net.CONNECTIONS.current
+box.stat.net.REQUESTS.current
 
 WAIT_COND_TIMEOUT = 10
 
@@ -33,11 +41,26 @@ test_run:wait_cond(function() return box.stat.net.CONNECTIONS.current == 2 end,
 cn3:close()
 test_run:wait_cond(function() return box.stat.net.CONNECTIONS.current == 1 end, WAIT_COND_TIMEOUT)
 
+future1 = cn:call('tweedledee', {}, {is_async = true})
+test_run:wait_cond(function() return box.stat.net.REQUESTS.current == 1 end, WAIT_COND_TIMEOUT)
+future2 = cn:call('tweedledee', {}, {is_async = true})
+test_run:wait_cond(function() return box.stat.net.REQUESTS.current == 2 end, WAIT_COND_TIMEOUT)
+ch:put(true)
+ch:put(true)
+future1:wait_result()
+future2:wait_result()
+test_run:wait_cond(function() return box.stat.net.REQUESTS.current == 0 end, WAIT_COND_TIMEOUT)
+box.stat.net.REQUESTS.total
+
 -- reset
 box.stat.reset()
 box.stat.net.SENT.total
 box.stat.net.RECEIVED.total
+box.stat.net.CONNECTIONS.total
+box.stat.net.REQUESTS.total
 box.stat.net.CONNECTIONS.current
+box.stat.net.REQUESTS.current
 
+box.schema.func.drop('tweedledee')
 space:drop() -- tweedledum
 cn:close()
-- 
2.11.0




More information about the Tarantool-patches mailing list