Files
2026-07-13 12:32:21 +08:00

164 lines
4.6 KiB
Lua

local helpers = require "spec.helpers"
local UUID_PATTERN = "%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x"
local function get_metrics(client)
local res = assert(client:send {
method = "GET",
path = "/metrics",
})
return assert.res_status(200, res)
end
local function assert_normal_metrics(body)
-- normal fields
assert.matches('kong_memory_lua_shared_dict_bytes', body, nil, true)
local states = { "accepted", "active", "handled", "reading", "total", "waiting", "writing" }
for _, v in ipairs(states) do
assert.matches('kong_nginx_connections_total{node_id="' ..
UUID_PATTERN .. '",subsystem="' .. ngx.config.subsystem .. '",state="' .. v .. '"} %d+', body)
end
end
local high_cost_metrics = {
"kong_http_requests_total",
"kong_kong_latency_ms",
"kong_upstream_latency_ms",
"kong_request_latency_ms",
"kong_bandwidth_bytes",
}
for _, strategy in helpers.each_strategy() do
describe("Plugin: prometheus, on-demond export metrics #" .. strategy, function()
local http_client, status_client
local prometheus_id
local tcp_status_port
lazy_setup(function()
tcp_status_port = helpers.get_available_port()
end)
-- restart the kong every time or the test would be flaky
before_each(function()
-- remember to truncate the tables so it won't be flaky!
local bp = assert(helpers.get_db_utils(strategy, {
"upstreams",
"targets",
"services",
"routes",
"plugins",
}))
local upstream = bp.upstreams:insert({
name = "mock_upstream",
algorithm = "least-connections",
})
bp.targets:insert({
upstream = upstream,
target = helpers.mock_upstream_host .. ":" .. helpers.mock_upstream_port,
weight = 100,
})
local service = bp.services:insert {
host = "mock_upstream",
}
bp.routes:insert {
hosts = { "mock" },
protocols = { "http" },
service = service,
paths = { "/" },
}
prometheus_id = assert(bp.plugins:insert {
name = "prometheus",
config = {
status_code_metrics = true,
latency_metrics = true,
bandwidth_metrics = true,
upstream_health_metrics = true,
}
}).id
assert(helpers.start_kong {
nginx_conf = "spec/fixtures/custom_nginx.template",
plugins = "bundled",
database = strategy,
cluster_cert = "spec/fixtures/ocsp_certs/kong_clustering.crt",
cluster_cert_key = "spec/fixtures/ocsp_certs/kong_clustering.key",
status_listen = "0.0.0.0:" .. tcp_status_port,
proxy_listen = "0.0.0.0:8000",
db_cache_ttl = 100, -- so the cache won't expire while we wait for the admin API
})
http_client = helpers.http_client("127.0.0.1", 8000, 20000)
status_client = helpers.http_client("127.0.0.1", tcp_status_port, 20000)
-- C* is so slow we need to wait
helpers.pwait_until(function()
assert.res_status(200, http_client:send {
method = "GET",
path = "/",
headers = {
["Host"] = "mock"
}
})
end)
end)
after_each(function()
helpers.stop_kong()
if http_client then
http_client:close()
end
if status_client then
status_client:close()
end
end)
for _, method in ipairs { "disabling", "removing" } do
it("less metrics when " .. method .. " prometheus", function()
-- export normal metrics
local body = get_metrics(status_client)
assert_normal_metrics(body)
for _, v in ipairs(high_cost_metrics) do
assert.matches(v, body, nil, true)
end
-- disable or remove
local admin_client = helpers.admin_client()
if method == "disabling" then
assert.res_status(200, admin_client:send {
method = "PATCH",
path = "/plugins/" .. prometheus_id,
body = {
enabled = false,
},
headers = {
["Content-Type"] = "application/json"
}
})
else
assert.res_status(204, admin_client:send {
method = "DELETE",
path = "/plugins/" .. prometheus_id,
})
end
helpers.pwait_until(function()
body = get_metrics(status_client)
assert_normal_metrics(body)
for _, v in ipairs(high_cost_metrics) do
assert.not_matches(v, body, nil, true)
end
end, 5)
end)
end
end)
end