Files
kong--kong/kong/plugins/datadog/handler.lua
T
2026-07-13 12:32:21 +08:00

122 lines
3.3 KiB
Lua

local Queue = require "kong.tools.queue"
local statsd_logger = require "kong.plugins.datadog.statsd_logger"
local kong_meta = require "kong.meta"
local replace_dashes = require("kong.tools.string").replace_dashes
local kong = kong
local ngx = ngx
local null = ngx.null
local insert = table.insert
local gsub = string.gsub
local pairs = pairs
local ipairs = ipairs
local get_consumer_id = {
consumer_id = function(consumer)
return consumer and replace_dashes(consumer.id)
end,
custom_id = function(consumer)
return consumer and consumer.custom_id
end,
username = function(consumer)
return consumer and consumer.username
end
}
local function compose_tags(service_name, status, consumer_id, tags, conf)
local result = {
(conf.service_name_tag or "name") .. ":" .. service_name,
(conf.status_tag or "status") .. ":" .. status
}
if consumer_id ~= nil then
insert(result, (conf.consumer_tag or "consumer") .. ":" .. consumer_id)
end
if tags ~= nil then
for _, v in pairs(tags) do
insert(result, v)
end
end
return result
end
local function send_entries_to_datadog(conf, messages)
local logger, err = statsd_logger:new(conf)
if err then
kong.log.err("failed to create Statsd logger: ", err)
return false, err
end
for _, message in ipairs(messages) do
local stat_name = {
request_size = "request.size",
response_size = "response.size",
latency = "latency",
upstream_latency = "upstream_latency",
kong_latency = "kong_latency",
request_count = "request.count",
}
local stat_value = {
request_size = message.request and message.request.size,
response_size = message.response and message.response.size,
latency = message.latencies.request,
upstream_latency = message.latencies.proxy,
kong_latency = message.latencies.kong,
request_count = 1,
}
for _, metric_config in pairs(conf.metrics) do
local stat_name = stat_name[metric_config.name]
if stat_name == nil then
goto continue
end
local stat_value = stat_value[metric_config.name]
local get_consumer_id = get_consumer_id[metric_config.consumer_identifier]
local consumer_id = get_consumer_id and get_consumer_id(message.consumer) or nil
local tags = compose_tags(
message.service and gsub(message.service.name ~= null and
message.service.name or message.service.host, "%.", "_") or "",
message.response and message.response.status or "-",
consumer_id, metric_config.tags, conf)
logger:send_statsd(stat_name, stat_value,
logger.stat_types[metric_config.stat_type],
metric_config.sample_rate, tags)
::continue::
end
end
logger:close_socket()
return true
end
local DatadogHandler = {
PRIORITY = 10,
VERSION = kong_meta.version,
}
function DatadogHandler:log(conf)
local ok, err = Queue.enqueue(
Queue.get_plugin_params("datadog", conf),
send_entries_to_datadog,
conf,
kong.log.serialize()
)
if not ok then
kong.log.err("failed to enqueue log entry to Datadog: ", err)
end
end
return DatadogHandler