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

Commit

Permalink
feat: Include tags in metrics labels
Browse files Browse the repository at this point in the history
  • Loading branch information
carnei-ro committed Aug 2, 2021
1 parent 70ef33f commit e4db818
Show file tree
Hide file tree
Showing 6 changed files with 834 additions and 31 deletions.
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

0 comments on commit e4db818

Please sign in to comment.