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

217 lines
6.1 KiB
Lua

local helpers = require "spec.helpers" -- hard dependency
local ngx = ngx
local fixtures = {
dns_mock = helpers.dns_mock.new({
mocks_only = true
}),
http_mock = {},
stream_mock = {}
}
fixtures.dns_mock:A{
name = "mock.example.com",
address = "127.0.0.1"
}
fixtures.dns_mock:A{
name = "status.example.com",
address = "127.0.0.1"
}
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"
for _, strategy in helpers.each_strategy() do
describe("Plugin: prometheus (metrics) [#" .. strategy .. "]", function()
local bp
local admin_ssl_client -- admin_ssl_client (lua-resty-http) does not support h2
local proxy_ssl_client -- proxy_ssl_client (lua-resty-http) does not support h2
local status_api_port
setup(function()
status_api_port = helpers.get_available_port()
bp = helpers.get_db_utils(strategy, {"services", "routes", "plugins"})
local mock_ssl_service = bp.services:insert{
name = "mock-ssl-service",
host = helpers.mock_upstream_ssl_host,
port = helpers.mock_upstream_ssl_port,
protocol = helpers.mock_upstream_ssl_protocol
}
bp.routes:insert{
name = "mock-ssl-route",
protocols = {"https"},
hosts = {"mock.example.com"},
paths = {"/"},
service = {
id = mock_ssl_service.id
}
}
local status_api_ssl_service = bp.services:insert{
name = "status-api-ssl-service",
url = "https://127.0.0.1:" .. status_api_port .. "/metrics"
}
bp.routes:insert{
name = "status-api-ssl-route",
protocols = {"https"},
hosts = {"status.example.com"},
paths = {"/metrics"},
service = {
id = status_api_ssl_service.id
}
}
local route1 = bp.routes:insert{
name = "serverless",
protocols = {"https"},
hosts = {"status.example.com"},
paths = {"/serverless"},
no_service = true,
}
assert(bp.plugins:insert {
name = "request-termination",
route = { id = route1.id },
config = {
status_code = 200,
message = "request terminated by request-termination plugin",
echo = true,
},
})
bp.plugins:insert{
name = "prometheus", -- globally enabled
config = {
status_code_metrics = true,
latency_metrics = true,
bandwidth_metrics = true,
upstream_health_metrics = true,
},
}
assert(helpers.start_kong({
nginx_conf = "spec/fixtures/custom_nginx.template",
plugins = "bundled,prometheus",
status_listen = '127.0.0.1:' .. status_api_port .. ' ssl', -- status api does not support h2
status_access_log = "logs/status_access.log",
status_error_log = "logs/status_error.log"
}, nil, nil, fixtures))
end)
teardown(function()
if admin_ssl_client then
admin_ssl_client:close()
end
if proxy_ssl_client then
proxy_ssl_client:close()
end
helpers.stop_kong()
end)
before_each(function()
admin_ssl_client = helpers.admin_client()
proxy_ssl_client = helpers.proxy_ssl_client()
end)
after_each(function()
if admin_ssl_client then
admin_ssl_client:close()
end
if proxy_ssl_client then
proxy_ssl_client:close()
end
end)
it("expose Nginx connection metrics by admin API #a1.1", function()
local res = assert(admin_ssl_client:send{
method = "GET",
path = "/metrics"
})
local body = assert.res_status(200, res)
assert.matches('kong_nginx_metric_errors_total 0', body, nil, true)
assert.matches('kong_nginx_connections_total{node_id="' .. UUID_PATTERN .. '",subsystem="' .. ngx.config.subsystem .. '",state="%w+"} %d+', body)
end)
it("increments the count of proxied requests #p1.1", function()
local res = assert(proxy_ssl_client:send{
method = "GET",
path = "/status/400",
headers = {
["Host"] = "mock.example.com"
}
})
assert.res_status(400, res)
helpers.wait_until(function()
local res = assert(admin_ssl_client:send{
method = "GET",
path = "/metrics"
})
local body = assert.res_status(200, res)
assert.matches('kong_nginx_metric_errors_total 0', body, nil, true)
return body:find('http_requests_total{service="mock-ssl-service",route="mock-ssl-route",code="400",source="service",workspace="default",consumer=""} 1',
nil, true)
end)
end)
it("expose Nginx connection metrics by status API #s1.1", function()
local res = assert(proxy_ssl_client:send{
method = "GET",
path = "/metrics",
headers = {
["Host"] = "status.example.com"
}
})
local body = assert.res_status(200, res)
assert.matches('kong_nginx_metric_errors_total 0', body, nil, true)
assert.matches('kong_nginx_connections_total{node_id="' .. UUID_PATTERN .. '",subsystem="' .. ngx.config.subsystem .. '",state="%w+"} %d+', body)
end)
it("expose metrics in no service route", function()
local res = assert(proxy_ssl_client:send{
method = "GET",
path = "/serverless",
headers = {
["Host"] = "status.example.com"
}
})
assert.res_status(200, res)
local res = assert(proxy_ssl_client:send{
method = "GET",
path = "/metrics",
headers = {
["Host"] = "status.example.com"
}
})
assert.res_status(200, res)
helpers.wait_until(function()
local res = assert(admin_ssl_client:send{
method = "GET",
path = "/metrics"
})
local body = assert.res_status(200, res)
assert.matches('kong_nginx_metric_errors_total 0', body, nil, true)
return body:find('kong_http_requests_total{service="",route="serverless",code="200",source="kong",workspace="default",consumer=""} 1',
nil, true)
end)
end)
end)
end