Skip to content
This repository has been archived by the owner on Aug 7, 2021. It is now read-only.

feat: Include tags in metrics labels #149

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
50 changes: 34 additions & 16 deletions kong/plugins/prometheus/exporter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,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"})

if enterprise then
enterprise.init(prometheus)
Expand Down Expand Up @@ -137,8 +137,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, 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" } },
{ value = 0, labels = { 0, 0, 0, "healthy" } },
Expand Down Expand Up @@ -168,22 +168,30 @@ if kong_subsystem == "http" then
return
end

local service_name
local service_name, service_tags
if message and message.service then
service_name = message.service.name or message.service.host
service_tags = ((message.service.tags) and (type(message.service.tags) == "table"))
and concat(message.service.tags, ",")
or ""
else
-- do not record any stats if the service is not present
return
end

local route_name
local route_name, route_tags
if message and message.route then
route_name = message.route.name or message.route.id
route_tags = ((message.route.tags) and (type(message.route.tags) == "table"))
and concat(message.route.tags, ",")
or ""
end

labels_table[1] = service_name
labels_table[2] = route_name
labels_table[3] = message.response.status
labels_table[4] = service_tags
labels_table[5] = route_tags
metrics.status:inc(1, labels_table)

local request_size = tonumber(message.request.size)
Expand Down Expand Up @@ -217,11 +225,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 All @@ -234,22 +244,30 @@ else
return
end

local service_name
local service_name, service_tags
if message and message.service then
service_name = message.service.name or message.service.host
service_tags = ((message.service.tags) and (type(message.service.tags) == "table"))
and concat(message.service.tags, ",")
or ""
else
-- do not record any stats if the service is not present
return
end

local route_name
local route_name, route_tags
if message and message.route then
route_name = message.route.name or message.route.id
route_tags = ((message.route.tags) and (type(message.route.tags) == "table"))
and concat(message.route.tags, ",")
or ""
end

labels_table[1] = service_name
labels_table[2] = route_name
labels_table[3] = message.session.status
labels_table[4] = service_tags
labels_table[5] = route_tags
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 = {}
end
if not conf.expose_routes_tags and message.route ~= nil then
message.route.tags = {}
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