Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prometheus): Include tags in metrics labels #7812

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions kong/plugins/prometheus/exporter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local ngx = ngx
local find = string.find
local lower = string.lower
local concat = table.concat
local sort = table.sort
local select = select
local balancer = require("kong.runloop.balancer")
local get_all_upstreams = balancer.get_all_upstreams
Expand Down Expand Up @@ -82,25 +83,25 @@ local function init()
if kong_subsystem == "http" then
metrics.status = prometheus:counter("http_status",
"HTTP status codes per service/route in Kong",
{"service", "route", "code"})
{"service", "route", "code", "service_tags", "route_tags"})
else
metrics.status = prometheus:counter("stream_status",
"Stream status codes per service/route in Kong",
{"service", "route", "code"})
{"service", "route", "code", "service_tags", "route_tags"})
end
metrics.latency = prometheus:histogram("latency",
"Latency added by Kong, total " ..
"request time and upstream latency " ..
"for each service/route in Kong",
{"service", "route", "type"},
{"service", "route", "type", "service_tags", "route_tags"},
DEFAULT_BUCKETS) -- TODO make this configurable
metrics.bandwidth = prometheus:counter("bandwidth",
"Total bandwidth in bytes " ..
"consumed per service/route in Kong",
{"service", "route", "type"})
{"service", "route", "type", "service_tags", "route_tags"})
metrics.consumer_status = prometheus:counter("http_consumer_status",
"HTTP status codes for customer per service/route in Kong",
{"service", "route", "code", "consumer"})
{"service", "route", "code", "consumer", "service_tags", "route_tags"})


-- Hybrid mode status
Expand Down Expand Up @@ -144,8 +145,8 @@ end

-- Since in the prometheus library we create a new table for each diverged label
-- so putting the "more dynamic" label at the end will save us some memory
local labels_table = {0, 0, 0}
local labels_table4 = {0, 0, 0, 0}
local labels_table = {0, 0, 0, '', ''}
local labels_table6 = {0, 0, 0, 0, 0, 0}
local upstream_target_addr_health_table = {
{ value = 0, labels = { 0, 0, 0, "healthchecks_off", ngx.config.subsystem } },
{ value = 0, labels = { 0, 0, 0, "healthy", ngx.config.subsystem } },
Expand Down Expand Up @@ -191,6 +192,12 @@ if kong_subsystem == "http" then
labels_table[1] = service_name
labels_table[2] = route_name
labels_table[3] = message.response.status
if message.service.tags then
labels_table[4] = concat(sort(message.service.tags), ",")
end
if message.route.tags then
labels_table[5] = concat(sort(message.route.tags), ",")
end
metrics.status:inc(1, labels_table)

local request_size = tonumber(message.request.size)
Expand Down Expand Up @@ -224,11 +231,13 @@ if kong_subsystem == "http" then
end

if serialized.consumer ~= nil then
labels_table4[1] = labels_table[1]
labels_table4[2] = labels_table[2]
labels_table4[3] = message.response.status
labels_table4[4] = serialized.consumer
metrics.consumer_status:inc(1, labels_table4)
labels_table6[1] = labels_table[1]
labels_table6[2] = labels_table[2]
labels_table6[3] = message.response.status
labels_table6[4] = serialized.consumer
labels_table6[5] = labels_table[4]
labels_table6[6] = labels_table[5]
metrics.consumer_status:inc(1, labels_table6)
end
end

Expand Down Expand Up @@ -257,6 +266,12 @@ else
labels_table[1] = service_name
labels_table[2] = route_name
labels_table[3] = message.session.status
if message.service.tags then
labels_table[4] = concat(sort(message.service.tags), ",")
end
if message.route.tags then
labels_table[5] = concat(sort(message.route.tags), ",")
end
metrics.status:inc(1, labels_table)

local ingress_size = tonumber(message.session.received)
Expand Down
6 changes: 6 additions & 0 deletions kong/plugins/prometheus/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ function PrometheusHandler.log(self, conf)
if conf.per_consumer and message.consumer ~= nil then
serialized.consumer = message.consumer.username
end
if not conf.expose_services_tags and message.service ~= nil then
message.service.tags = nil
end
if not conf.expose_routes_tags and message.route ~= nil then
message.route.tags = nil
end

prometheus.log(message, serialized)
end
Expand Down
2 changes: 2 additions & 0 deletions kong/plugins/prometheus/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ return {
type = "record",
fields = {
{ per_consumer = { type = "boolean", default = false }, },
{ expose_services_tags = { type = "boolean", default = false }, },
{ expose_routes_tags = { type = "boolean", default = false }, },
},
custom_validator = validate_shared_dict,
}, },
Expand Down
Loading