Annotate

mod_prometheus/mod_prometheus.lua @ 4646:072d078be095

mod_storage_xmlarchive: Advertise capabilities (none atm) Both 'total' and 'quota' would be prohibitively expensive for the kind of archives this module targets as it would require counting items across the entire archive.
author Kim Alvefur <zash@zash.se>
date Fri, 13 Aug 2021 01:18:32 +0200
parent 4596:c406e4bf7ee5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3132
4ef28b6b4e87 mod_prometheus: Add my copyright.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 3131
diff changeset
1 -- Log statistics to Prometheus
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2 --
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 -- Copyright (C) 2014 Daurnimator
3132
4ef28b6b4e87 mod_prometheus: Add my copyright.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 3131
diff changeset
4 -- Copyright (C) 2018 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
4544
64fa2dd34d43 mod_prometheus: remove space between label k/v pairs
Jonas Schäfer <jonas@wielicki.name>
parents: 4542
diff changeset
5 -- Copyright (C) 2021 Jonas Schäfer <jonas@zombofant.net>
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 --
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 -- This module is MIT/X11 licensed.
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9 module:set_global();
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10
3128
a34e7bd87b39 mod_prometheus: Optimise global lookups.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 3127
diff changeset
11 local tostring = tostring;
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 local t_insert = table.insert;
3128
a34e7bd87b39 mod_prometheus: Optimise global lookups.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 3127
diff changeset
13 local t_concat = table.concat;
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14 local socket = require "socket";
4542
fb4a50bf60f1 mod_prometheus: Invoke stats collection if in 'manual' mode
Kim Alvefur <zash@zash.se>
parents: 3952
diff changeset
15 local statsman = require "core.statsmanager";
fb4a50bf60f1 mod_prometheus: Invoke stats collection if in 'manual' mode
Kim Alvefur <zash@zash.se>
parents: 3952
diff changeset
16 local get_stats = statsman.get_stats;
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
17 local get_metric_registry = statsman.get_metric_registry;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
18 local collect = statsman.collect;
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20 local function escape(text)
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 return text:gsub("\\", "\\\\"):gsub("\"", "\\\""):gsub("\n", "\\n");
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 local function escape_name(name)
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
25 return name:gsub("/", "__"):gsub("[^A-Za-z0-9_]", "_"):gsub("^[^A-Za-z_]", "_%1");
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 local function get_timestamp()
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29 -- Using LuaSocket for that because os.time() only has second precision.
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 return math.floor(socket.gettime() * 1000);
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
32
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 local function repr_help(metric, docstring)
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 docstring = docstring:gsub("\\", "\\\\"):gsub("\n", "\\n");
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 return "# HELP "..escape_name(metric).." "..docstring.."\n";
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
38 local function repr_unit(metric, unit)
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
39 if not unit then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
40 unit = ""
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
41 else
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
42 unit = unit:gsub("\\", "\\\\"):gsub("\n", "\\n");
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
43 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
44 return "# UNIT "..escape_name(metric).." "..unit.."\n";
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
45 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
46
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 -- local allowed_types = { counter = true, gauge = true, histogram = true, summary = true, untyped = true };
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 -- local allowed_types = { "counter", "gauge", "histogram", "summary", "untyped" };
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49 local function repr_type(metric, type_)
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 -- if not allowed_types:contains(type_) then
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51 -- return;
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52 -- end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
53 return "# TYPE "..escape_name(metric).." "..type_.."\n";
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
54 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
55
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
56 local function repr_label(key, value)
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
57 return key.."=\""..escape(value).."\"";
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
58 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
59
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
60 local function repr_labels(labelkeys, labelvalues, extra_labels)
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
61 local values = {}
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
62 if labelkeys then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
63 for i, key in ipairs(labelkeys) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
64 local value = labelvalues[i]
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
65 t_insert(values, repr_label(escape_name(key), escape(value)));
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
66 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
67 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
68 if extra_labels then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
69 for key, value in pairs(extra_labels) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
70 t_insert(values, repr_label(escape_name(key), escape(value)));
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
71 end
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
72 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
73 if #values == 0 then
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
74 return "";
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
75 end
4544
64fa2dd34d43 mod_prometheus: remove space between label k/v pairs
Jonas Schäfer <jonas@wielicki.name>
parents: 4542
diff changeset
76 return "{"..t_concat(values, ",").."}";
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
77 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
79 local function repr_sample(metric, labelkeys, labelvalues, extra_labels, value)
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
80 return escape_name(metric)..repr_labels(labelkeys, labelvalues, extra_labels).." "..string.format("%.17g", value).."\n";
3149
ccbfe7df02dc mod_prometheus: Expose min, max and average when available.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 3138
diff changeset
81 end
ccbfe7df02dc mod_prometheus: Expose min, max and average when available.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 3138
diff changeset
82
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
83 local get_metrics;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
84 if statsman.get_metric_registry then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
85 module:log("debug", "detected OpenMetrics statsmanager")
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
86 -- Prosody 0.12+ with OpenMetrics
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
87 function get_metrics(event)
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
88 local response = event.response;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
89 response.headers.content_type = "application/openmetrics-text; version=0.0.4";
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
90
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
91 if collect then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
92 -- Ensure to get up-to-date samples when running in manual mode
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
93 collect()
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
94 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
95
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
96 local registry = get_metric_registry()
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
97 if registry == nil then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
98 response.headers.content_type = "text/plain; charset=utf-8"
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
99 response.status_code = 404
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
100 return "No statistics provider configured\n"
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
101 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
102 local answer = {};
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
103 for metric_family_name, metric_family in pairs(registry:get_metric_families()) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
104 t_insert(answer, repr_help(metric_family_name, metric_family.description))
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
105 t_insert(answer, repr_unit(metric_family_name, metric_family.unit))
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
106 t_insert(answer, repr_type(metric_family_name, metric_family.type_))
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
107 for labelset, metric in metric_family:iter_metrics() do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
108 for suffix, extra_labels, value in metric:iter_samples() do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
109 t_insert(answer, repr_sample(metric_family_name..suffix, metric_family.label_keys, labelset, extra_labels, value))
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
110 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
111 end
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
112 end
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
113 t_insert(answer, "# EOF\n")
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
114 return t_concat(answer, "");
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
115 end
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
116 else
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
117 module:log("debug", "detected pre-OpenMetrics statsmanager")
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
118 -- Pre-OpenMetrics
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
119
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
120 local allowed_extras = { min = true, max = true, average = true };
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
121 local function insert_extras(data, key, name, timestamp, extra)
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
122 if not extra then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
123 return false;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
124 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
125 local has_extra = false;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
126 for extra_name in pairs(allowed_extras) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
127 if extra[extra_name] then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
128 local field = {
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
129 value = extra[extra_name],
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
130 labels = {
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
131 ["type"] = name,
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
132 field = extra_name,
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
133 },
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
134 typ = "gauge";
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
135 timestamp = timestamp,
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
136 };
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
137 t_insert(data[key], field);
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
138 has_extra = true;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
139 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
140 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
141 return has_extra;
4542
fb4a50bf60f1 mod_prometheus: Invoke stats collection if in 'manual' mode
Kim Alvefur <zash@zash.se>
parents: 3952
diff changeset
142 end
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
143
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
144 local function parse_stats()
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
145 local timestamp = tostring(get_timestamp());
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
146 local data = {};
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
147 local stats, changed_only, extras = get_stats();
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
148 for stat, value in pairs(stats) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
149 -- module:log("debug", "changed_stats[%q] = %s", stat, tostring(value));
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
150 local extra = extras[stat];
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
151 local host, sect, name, typ = stat:match("^/([^/]+)/([^/]+)/(.+):(%a+)$");
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
152 if host == nil then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
153 sect, name, typ = stat:match("^([^.]+)%.(.+):(%a+)$");
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
154 elseif host == "*" then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
155 host = nil;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
156 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
157 if sect:find("^mod_measure_.") then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
158 sect = sect:sub(13);
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
159 elseif sect:find("^mod_statistics_.") then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
160 sect = sect:sub(16);
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
161 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
162
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
163 local key = escape_name("prosody_"..sect);
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
164 local field = {
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
165 value = value,
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
166 labels = { ["type"] = name},
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
167 -- TODO: Use the other types where it makes sense.
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
168 typ = (typ == "rate" and "counter" or "gauge"),
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
169 timestamp = timestamp,
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
170 };
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
171 if host then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
172 field.labels.host = host;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
173 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
174 if data[key] == nil then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
175 data[key] = {};
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
176 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
177 if not insert_extras(data, key, name, timestamp, extra) then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
178 t_insert(data[key], field);
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
179 end
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
180 end
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
181 return data;
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
182 end
4555
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
183
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
184 function get_metrics(event)
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
185 local response = event.response;
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
186 response.headers.content_type = "text/plain; version=0.0.4";
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
187 if statsman.collect then
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
188 statsman.collect()
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
189 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
190
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
191 local answer = {};
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
192 for key, fields in pairs(parse_stats()) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
193 t_insert(answer, repr_help(key, ""));
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
194 t_insert(answer, repr_type(key, fields[1].typ));
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
195 for _, field in pairs(fields) do
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
196 t_insert(answer, repr_sample(key, nil, nil, field.labels, field.value, field.timestamp));
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
197 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
198 end
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
199 return t_concat(answer, "");
1e70538e4641 mod_prometheus: Port to new OpenMetrics based statistics module
Jonas Schäfer <jonas@wielicki.name>
parents: 4544
diff changeset
200 end
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
201 end
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
202
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
203 function module.add_host(module)
3952
343dc9dd70dd mod_prometheus: Ensure mod_http is loaded where the http interface is exposed (thanks Martin)
Kim Alvefur <zash@zash.se>
parents: 3149
diff changeset
204 module:depends "http";
3125
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
205 module:provides("http", {
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
206 default_path = "metrics";
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
207 route = {
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
208 GET = get_metrics;
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
209 };
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
210 });
07a2ba55de4d mod_prometheus: Add a new statistics export module, for Prometheus.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
211 end