[Tarantool-patches] [PATCH 1/2] feedback_daemon: add operation statistics reporting

Serge Petrenko sergepetrenko at tarantool.org
Thu Dec 24 16:34:50 MSK 2020


Report box.stat().*.total, box.stat.net().*.total and
box.stat.net().*.current via feedback daemon report.
Accompany this data with the time when report was generated so that it's
possible to calculate RPS from this data on the feedback server.

`box.stat().OP_NAME.total` reside in `feedback.stats.box.OP_NAME.total`, while
`box.stat.net().OP_NAME.total` reside in `feedback.stats.net.OP_NAME.total`
The time of report generation is located at `feedback.stats.time`

Closes #5589
---
 src/box/lua/feedback_daemon.lua       | 29 +++++++++++++++-
 test/box-tap/feedback_daemon.test.lua | 49 ++++++++++++++++++++++++++-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/src/box/lua/feedback_daemon.lua b/src/box/lua/feedback_daemon.lua
index 1d39012ed..1aac32bb3 100644
--- a/src/box/lua/feedback_daemon.lua
+++ b/src/box/lua/feedback_daemon.lua
@@ -284,12 +284,39 @@ local function fill_in_options(feedback)
     feedback.options = options
 end
 
+local function fill_in_stats(feedback)
+    local stats = {box={}, net={}}
+    local box_stat = box.stat()
+    local net_stat = box.stat.net()
+
+    stats.time = fiber.time64()
+    -- Send box.stat().*.total.
+    for op, tbl in pairs(box_stat) do
+        if type(tbl) == 'table' and tbl.total ~= nil then
+            stats.box[op] = {
+                total = tbl.total
+            }
+        end
+    end
+    -- Send box.stat.net().*.total and box.stat.net().*.current.
+    for val, tbl in pairs(net_stat) do
+        if type(tbl) == 'table' and (tbl.total ~= nil or tbl.current ~= nil) then
+                    stats.net[val] = {
+                        total = tbl.total,
+                        current = tbl.current
+                    }
+        end
+    end
+    feedback.stats = stats
+end
+
 local function fill_in_feedback(feedback)
     fill_in_base_info(feedback)
     fill_in_platform_info(feedback)
     fill_in_repo_url(feedback)
     fill_in_features(feedback)
     fill_in_options(feedback)
+    fill_in_stats(feedback)
 
     return feedback
 end
@@ -371,7 +398,7 @@ setmetatable(daemon, {
         end,
         -- this function is used in saving feedback in file
         generate_feedback = function()
-            return fill_in_feedback({ feedback_version = 4 })
+            return fill_in_feedback({ feedback_version = 5 })
         end,
         start = function()
             start(daemon)
diff --git a/test/box-tap/feedback_daemon.test.lua b/test/box-tap/feedback_daemon.test.lua
index 7ebc97587..1fcb4e5fa 100755
--- a/test/box-tap/feedback_daemon.test.lua
+++ b/test/box-tap/feedback_daemon.test.lua
@@ -20,6 +20,9 @@ local function feedback_reset()
 end
 
 local function http_handle(s)
+    -- When data is > 1024 bytes, curl sends "Expect: 100-continue" header,
+    -- and waits for this response before sending the actual data.
+    s:write("HTTP/1.1 100 Continue\r\n\r\n")
     s:write("HTTP/1.1 200 OK\r\n")
     s:write("Accept: */*\r\n")
     s:write("Connection: keep-alive\r\n")
@@ -67,7 +70,7 @@ if not ok then
     os.exit(0)
 end
 
-test:plan(23)
+test:plan(27)
 
 local function check(message)
     while feedback_count < 1 do
@@ -120,6 +123,9 @@ local fio = require("fio")
 local fh = fio.open("feedback.json")
 test:ok(fh, "file is created")
 local file_data = fh:read()
+-- Ignore the report time. The data should be equal other than that.
+feedback_save = string.gsub(feedback_save, 'time:(%d+)', 'time:0')
+file_data = string.gsub(feedback_save, 'time:(%d+)', 'time:0')
 test:is(file_data, feedback_save, "data is equal")
 fh:close()
 fio.unlink("feedback.json")
@@ -241,5 +247,46 @@ box.space.features_memtx_empty:drop()
 box.space.features_memtx:drop()
 box.space.features_sync:drop()
 
+function check_stats(stat)
+    local sub = test:test('feedback operation stats')
+    sub:plan(18)
+    local box_stat = box.stat()
+    local net_stat = box.stat.net()
+    for op, val in pairs(box_stat) do
+        sub:is(stat.box[op].total, val.total,
+               string.format('%s total is reported', op))
+    end
+    for op, val in pairs(net_stat) do
+        sub:is(stat.net[op].total, val.total,
+               string.format('%s total is reported', op))
+        if val.current ~= nil then
+            sub:is(stat.net[op].current, val.current,
+                   string.format('%s current is reported', op))
+        end
+    end
+    sub:check()
+end
+
+actual = daemon.generate_feedback()
+test:is(fiber.time64(), actual.stats.time, "Time of report generation is correct")
+
+-- Check that all the statistics are reported.
+check_stats(actual.stats)
+
+box.schema.space.create('test')
+box.space.test:create_index('pk')
+box.space.test:insert{1}
+box.space.test:select{}
+box.space.test:update({1}, {{'=', 2, 1}})
+box.space.test:replace{2}
+box.space.test:delete{1}
+box.space.test:drop()
+
+-- Check that all the statistics are updated.
+actual = daemon.generate_feedback()
+test:is(fiber.time64(), actual.stats.time, "Time of report generation is correct")
+
+check_stats(actual.stats)
+
 test:check()
 os.exit(0)
-- 
2.24.3 (Apple Git-128)



More information about the Tarantool-patches mailing list