diff --git a/kong-prometheus-plugin-1.0.0-1.rockspec b/kong-prometheus-plugin-1.0.0-1.rockspec index 92cb61d..0f0ce72 100644 --- a/kong-prometheus-plugin-1.0.0-1.rockspec +++ b/kong-prometheus-plugin-1.0.0-1.rockspec @@ -23,6 +23,7 @@ build = { ["kong.plugins.prometheus.api"] = "kong/plugins/prometheus/api.lua", ["kong.plugins.prometheus.status_api"] = "kong/plugins/prometheus/status_api.lua", ["kong.plugins.prometheus.exporter"] = "kong/plugins/prometheus/exporter.lua", + ["kong.plugins.prometheus.enterprise.exporter"] = "kong/plugins/prometheus/enterprise/exporter.lua", ["kong.plugins.prometheus.handler"] = "kong/plugins/prometheus/handler.lua", ["kong.plugins.prometheus.prometheus"] = "kong/plugins/prometheus/prometheus.lua", ["kong.plugins.prometheus.serve"] = "kong/plugins/prometheus/serve.lua", diff --git a/kong/plugins/prometheus/enterprise/exporter.lua b/kong/plugins/prometheus/enterprise/exporter.lua new file mode 100644 index 0000000..42e5ec0 --- /dev/null +++ b/kong/plugins/prometheus/enterprise/exporter.lua @@ -0,0 +1,94 @@ +local kong = kong +local sub = string.sub +local split = require('kong.tools.utils').split + +local metrics = {} + + +local function init(prometheus) + metrics.license_errors = prometheus:counter("enterprise_license_errors", + "Errors when collecting license info") + metrics.license_signature = prometheus:gauge("enterprise_license_signature", + "Last 32 bytes of the license signautre in number") + metrics.license_expiration = prometheus:gauge("enterprise_license_expiration", + "Unix epoch time when the license expires, " .. + "the timestamp is substracted by 24 hours ".. + "to avoid difference in timezone") + metrics.license_features = prometheus:gauge("enterprise_license_features", + "License features features", + { "feature" }) +end + +local function license_date_to_unix(yyyy_mm_dd) + local date_t = split(yyyy_mm_dd, "-") + + local ok, res = pcall(os.time, { + year = tonumber(date_t[1]), + month = tonumber(date_t[2]), + day = tonumber(date_t[3]) + }) + if ok then + return res + end + + return nil, res +end + +local function metric_data() + if not metrics then + kong.log.err("prometheus: plugin is not initialized, please make sure ", + " 'prometheus_metrics' shared dict is present in nginx template") + return kong.response.exit(500, { message = "An unexpected error occurred" }) + end + + if not kong.license or not kong.license.license then + metrics.license_errors:inc() + kong.log.err("cannot read kong.license when collecting license info") + return + end + + local lic = kong.license.license + + if lic.version ~= 1 then + metrics.license_errors:inc() + kong.log.err("enterprise license version (" .. (lic.version or "nil") .. ") unsupported") + return + end + + local sig = lic.signature + if not sig then + metrics.license_errors:inc() + kong.log.err("cannot read license signature when collecting license info") + return + end + -- last 32 bytes as an int32 + metrics.license_signature:set(tonumber("0x" .. sub(sig, #sig-33, #sig))) + + local expiration = lic.payload and lic.payload.license_expiration_date + if not expiration then + metrics.license_errors:inc() + kong.log.err("cannot read license expiration when collecting license info") + return + end + local tm, err = license_date_to_unix(expiration) + if not tm then + metrics.license_errors:inc() + kong.log.err("cannot parse license expiration when collecting license info ", err) + return + end + -- substract it by 24h so everyone one earth is happy monitoring it + metrics.license_expiration:set(tm - 86400) + + + metrics.license_features:set(kong.licensing:can("ee_plugins") and 1 or 0, + { "ee_plugins" }) + + metrics.license_features:set(kong.licensing:can("write_admin_api") and 1 or 0, + { "write_admin_api" }) +end + + +return { + init = init, + metric_data = metric_data, +} diff --git a/kong/plugins/prometheus/exporter.lua b/kong/plugins/prometheus/exporter.lua index 6152a2a..0194077 100644 --- a/kong/plugins/prometheus/exporter.lua +++ b/kong/plugins/prometheus/exporter.lua @@ -18,6 +18,12 @@ local prometheus -- use the same counter library shipped with Kong package.loaded['prometheus_resty_counter'] = require("resty.counter") +local enterprise +local pok = pcall(require, "kong.enterprise_edition.licensing") +if pok then + enterprise = require("kong.plugins.prometheus.enterprise.exporter") +end + local function init() local shm = "prometheus_metrics" @@ -73,6 +79,9 @@ local function init() "Total bandwidth in bytes " .. "consumed per service/route in Kong", {"service", "route", "type"}) + if enterprise then + enterprise.init(prometheus) + end end local function init_worker() @@ -295,6 +304,10 @@ local function metric_data() {res.workers_lua_vms[i].pid}) end + if enterprise then + enterprise.metric_data() + end + return prometheus:metric_data() end