Skip to content

Commit

Permalink
fix(admin-gui): add basic kong manager statistics to phone home loggi…
Browse files Browse the repository at this point in the history
…ng (#11260)

Add metrics `_admin_gui` and `km_visits` to phone home report.

`_admin_gui` will report the admin_gui_listeners status.

The counter will be increased when kong manager is visited,
but will not respond to the static assets request.

This fix KAG-2127

(cherry picked from commit e025bbd)
  • Loading branch information
nekolab authored and flrgh committed Jul 25, 2023
1 parent f59d23b commit 902635d
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 0 deletions.
8 changes: 8 additions & 0 deletions kong/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ local constants = require "kong.constants"
local get_ctx_table = require("resty.core.ctx").get_ctx_table
local admin_gui = require "kong.admin_gui"
local wasm = require "kong.runloop.wasm"
local reports = require "kong.reports"


local kong = kong
Expand Down Expand Up @@ -221,6 +222,7 @@ do
"events:requests:ws",
"events:requests:wss",
"events:requests:go_plugins",
"events:km:visit",
"events:streams",
"events:streams:tcp",
"events:streams:tls",
Expand Down Expand Up @@ -1695,6 +1697,12 @@ function Kong.admin_gui_kconfig_content()
end
end

function Kong.admin_gui_log()
if kong.configuration.anonymous_reports then
reports.admin_gui_log(ngx.ctx)
end
end

function Kong.status_content()
return serve_content("kong.status")
end
Expand Down
13 changes: 13 additions & 0 deletions kong/reports.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ local TLS_STREAM_COUNT_KEY = "events:streams:tls"
local UDP_STREAM_COUNT_KEY = "events:streams:udp"


local KM_VISIT_COUNT_KEY = "events:km:visit"


local GO_PLUGINS_REQUEST_COUNT_KEY = "events:requests:go_plugins"


Expand Down Expand Up @@ -336,6 +339,7 @@ local function send_ping(host, port)
_ping_infos.grpcs_reqs = get_counter(GRPCS_REQUEST_COUNT_KEY)
_ping_infos.ws_reqs = get_counter(WS_REQUEST_COUNT_KEY)
_ping_infos.wss_reqs = get_counter(WSS_REQUEST_COUNT_KEY)
_ping_infos.km_visits = get_counter(KM_VISIT_COUNT_KEY)
_ping_infos.go_plugin_reqs = get_counter(GO_PLUGINS_REQUEST_COUNT_KEY)

_ping_infos.request_route_cache_hit_pos = get_counter(REQUEST_ROUTE_CACHE_HITS_KEY_POS)
Expand All @@ -352,6 +356,7 @@ local function send_ping(host, port)
reset_counter(GRPCS_REQUEST_COUNT_KEY, _ping_infos.grpcs_reqs)
reset_counter(WS_REQUEST_COUNT_KEY, _ping_infos.ws_reqs)
reset_counter(WSS_REQUEST_COUNT_KEY, _ping_infos.wss_reqs)
reset_counter(KM_VISIT_COUNT_KEY, _ping_infos.km_visits)
reset_counter(GO_PLUGINS_REQUEST_COUNT_KEY, _ping_infos.go_plugin_reqs)
reset_counter(REQUEST_ROUTE_CACHE_HITS_KEY_POS, _ping_infos.request_route_cache_hit_pos)
reset_counter(REQUEST_ROUTE_CACHE_HITS_KEY_NEG, _ping_infos.request_route_cache_hit_neg)
Expand Down Expand Up @@ -398,6 +403,7 @@ local function configure_ping(kong_conf)
add_immutable_value("role", kong_conf.role)
add_immutable_value("kic", kong_conf.kic)
add_immutable_value("_admin", #kong_conf.admin_listeners > 0 and 1 or 0)
add_immutable_value("_admin_gui", #kong_conf.admin_gui_listeners > 0 and 1 or 0)
add_immutable_value("_proxy", #kong_conf.proxy_listeners > 0 and 1 or 0)
add_immutable_value("_stream", #kong_conf.stream_listeners > 0 and 1 or 0)
end
Expand Down Expand Up @@ -485,6 +491,13 @@ return {
incr_counter(count_key .. ":" .. ROUTE_CACHE_HITS_KEY .. ":" .. route_match_cached)
end
end,
admin_gui_log = function(ctx)
if not _enabled then
return
end

incr_counter(KM_VISIT_COUNT_KEY)
end,

-- custom methods
toggle = function(enable)
Expand Down
4 changes: 4 additions & 0 deletions kong/templates/nginx_kong_gui_include.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,9 @@ location ~* ^$(admin_gui_path_prefix)(?<path>/.*)?$ {
> end
sub_filter_once off;
sub_filter_types *;
log_by_lua_block {
Kong.admin_gui_log()
}
}
]]
28 changes: 28 additions & 0 deletions spec/01-unit/11-reports_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,34 @@ describe("reports", function()
end)
end)

describe("sends '_admin_gui' for 'admin_gui_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
admin_gui_listen = "off",
}))
reports.configure_ping(conf)

local thread = helpers.tcp_server(port, opts)
reports.send_ping("127.0.0.1", port)

local _, res = assert(thread:join())
assert.matches("_admin_gui=0", res, nil, true)
end)

it("on", function()
local conf = assert(conf_loader(nil, {
admin_gui_listen = "127.0.0.1:8001",
}))
reports.configure_ping(conf)

local thread = helpers.tcp_server(port, opts)
reports.send_ping("127.0.0.1", port)

local _, res = assert(thread:join())
assert.matches("_admin_gui=1", res, nil, true)
end)
end)

describe("sends '_proxy' for 'proxy_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
Expand Down
157 changes: 157 additions & 0 deletions spec/02-integration/17-admin_gui/03-reports_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
local cjson = require "cjson"
local lfs = require "lfs"
local pl_path = require "pl.path"

local helpers = require "spec.helpers"
local constants = require "kong.constants"

describe("anonymous reports for kong manager", function ()
local reports_send_ping = function()
ngx.sleep(0.2) -- hand over the CPU so other threads can do work (processing the sent data)
local admin_client = helpers.admin_client()
local res = admin_client:post("/reports/send-ping?port=" .. constants.REPORTS.STATS_TLS_PORT)
assert.response(res).has_status(200)
admin_client:close()
end

local assert_report = function (value)
local reports_server = helpers.tcp_server(constants.REPORTS.STATS_TLS_PORT, {tls=true})
reports_send_ping()
local _, reports_data = assert(reports_server:join())
reports_data = cjson.encode(reports_data)

assert.match(value, reports_data)
end

local prepare_gui_dir = function ()
local err, gui_dir_path
gui_dir_path = pl_path.join(helpers.test_conf.prefix, "gui")
os.execute("rm -rf " .. gui_dir_path)
err = select(2, lfs.mkdir(gui_dir_path))
assert.is_nil(err)
return gui_dir_path
end

local create_gui_file = function (path)
local fd = assert(io.open(path, "w"))
assert.is_not_nil(fd)
assert(fd:write("TEST"))
assert(fd:close())
end

local dns_hostsfile

lazy_setup(function ()
dns_hostsfile = assert(os.tmpname() .. ".hosts")
local fd = assert(io.open(dns_hostsfile, "w"))
assert(fd:write("127.0.0.1 " .. constants.REPORTS.ADDRESS))
assert(fd:close())

local bp = assert(helpers.get_db_utils(nil, {}, { "reports-api" }))

bp.plugins:insert({
name = "reports-api",
config = {}
})
end)

lazy_teardown(function ()
os.remove(dns_hostsfile)
end)

describe("availability status", function ()
it("should be correct when admin_gui_listen is set", function ()
assert(helpers.start_kong({
admin_gui_listen = "127.0.0.1:9012",
anonymous_reports = true,
plugins = "bundled,reports-api",
dns_hostsfile = dns_hostsfile,
}))

finally(function()
helpers.stop_kong()
end)

assert_report("_admin_gui=1")
end)

it("should be correct when admin_gui_listen is off", function ()
assert(helpers.start_kong({
admin_gui_listen = "off",
anonymous_reports = true,
plugins = "bundled,reports-api",
dns_hostsfile = dns_hostsfile,
}))

finally(function()
helpers.stop_kong()
end)

assert_report("_admin_gui=0")
end)
end)

describe("visit", function()
lazy_setup(function()
assert(helpers.start_kong({
admin_gui_listen = "127.0.0.1:9012",
anonymous_reports = true,
plugins = "bundled,reports-api",
dns_hostsfile = dns_hostsfile,
}))

local gui_dir_path = prepare_gui_dir()
create_gui_file(pl_path.join(gui_dir_path, "index.html"))
create_gui_file(pl_path.join(gui_dir_path, "robots.txt"))
create_gui_file(pl_path.join(gui_dir_path, "favicon.ico"))
create_gui_file(pl_path.join(gui_dir_path, "test.js"))
create_gui_file(pl_path.join(gui_dir_path, "test.css"))
create_gui_file(pl_path.join(gui_dir_path, "test.png"))
end)

lazy_teardown(function()
os.remove(dns_hostsfile)

helpers.stop_kong()
end)

it("should have value 0 when no kong mananger visit occurs", function ()
assert_report("km_visits=0")
end)

it("should increase counter by 1 for each kong mananger visit", function ()
local admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/services" }))
admin_gui_client:close()
assert_report("km_visits=2")
end)

it("should reset the counter after report", function ()
local admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
admin_gui_client:close()
assert_report("km_visits=1")

admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
assert_report("km_visits=2")
admin_gui_client:close()
end)

it("should not increase the counter for GUI assets", function ()
local admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/kconfig.js" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/robots.txt" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/favicon.ico" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/test.js" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/test.css" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/test.png" }))
assert.res_status(404, admin_gui_client:send({ method = "GET", path = "/not-exist.png" }))
admin_gui_client:close()

assert_report("km_visits=0")
end)
end)
end)
4 changes: 4 additions & 0 deletions spec/fixtures/custom_nginx.template
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,10 @@ server {
> end
sub_filter_once off;
sub_filter_types *;

log_by_lua_block {
Kong.admin_gui_log()
}
}
}
> end -- of (role == "control_plane" or role == "traditional") and #admin_listen > 0 and #admin_gui_listeners > 0
Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures/default_nginx.template
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ server {
> end
sub_filter_once off;
sub_filter_types *;

log_by_lua_block {
Kong.admin_gui_log()
}
}
}
> end -- of (role == "control_plane" or role == "traditional") and #admin_listen > 0 and #admin_gui_listeners > 0
Expand Down

0 comments on commit 902635d

Please sign in to comment.