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