Mercurial > prosody-modules
comparison mod_prometheus/mod_prometheus.lua @ 3131:ddd39ca7b953
mod_prometheus: Change the storage model for one which matches Prometheus better.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 22 Jun 2018 00:31:54 +0200 |
parents | a34e7bd87b39 |
children | 4ef28b6b4e87 |
comparison
equal
deleted
inserted
replaced
3130:c47cd8dbd310 | 3131:ddd39ca7b953 |
---|---|
6 | 6 |
7 module:set_global(); | 7 module:set_global(); |
8 module:depends "http"; | 8 module:depends "http"; |
9 | 9 |
10 local tostring = tostring; | 10 local tostring = tostring; |
11 local s_format = string.format; | |
12 local t_insert = table.insert; | 11 local t_insert = table.insert; |
13 local t_concat = table.concat; | 12 local t_concat = table.concat; |
14 local socket = require "socket"; | 13 local socket = require "socket"; |
15 local mt = require "util.multitable"; | |
16 | 14 |
17 local meta = mt.new(); meta.data = module:shared"meta"; | 15 local data = {}; |
18 local data = mt.new(); data.data = module:shared"data"; | |
19 | 16 |
20 local function escape(text) | 17 local function escape(text) |
21 return text:gsub("\\", "\\\\"):gsub("\"", "\\\""):gsub("\n", "\\n"); | 18 return text:gsub("\\", "\\\\"):gsub("\"", "\\\""):gsub("\n", "\\n"); |
22 end | 19 end |
23 | 20 |
63 return escape_name(metric)..repr_labels(labels).." "..value.." "..timestamp.."\n"; | 60 return escape_name(metric)..repr_labels(labels).." "..value.." "..timestamp.."\n"; |
64 end | 61 end |
65 | 62 |
66 module:hook("stats-updated", function (event) | 63 module:hook("stats-updated", function (event) |
67 local all_stats, this = event.stats_extra; | 64 local all_stats, this = event.stats_extra; |
68 local host, sect, name, typ, key; | 65 local host, sect, name, typ; |
69 for stat, value in pairs(event.changed_stats) do | 66 data = {}; |
67 for stat, value in pairs(event.stats) do | |
70 this = all_stats[stat]; | 68 this = all_stats[stat]; |
71 -- module:log("debug", "changed_stats[%q] = %s", stat, tostring(value)); | 69 -- module:log("debug", "changed_stats[%q] = %s", stat, tostring(value)); |
72 host, sect, name, typ = stat:match("^/([^/]+)/([^/]+)/(.+):(%a+)$"); | 70 host, sect, name, typ = stat:match("^/([^/]+)/([^/]+)/(.+):(%a+)$"); |
73 if host == nil then | 71 if host == nil then |
74 sect, name, typ, host = stat:match("^([^.]+)%.([^:]+):(%a+)$"); | 72 sect, name, typ = stat:match("^([^.]+)%.(.+):(%a+)$"); |
75 elseif host == "*" then | 73 elseif host == "*" then |
76 host = nil; | 74 host = nil; |
77 end | 75 end |
78 if sect:find("^mod_measure_.") then | 76 if sect:find("^mod_measure_.") then |
79 sect = sect:sub(13); | 77 sect = sect:sub(13); |
80 elseif sect:find("^mod_statistics_.") then | 78 elseif sect:find("^mod_statistics_.") then |
81 sect = sect:sub(16); | 79 sect = sect:sub(16); |
82 end | 80 end |
83 key = escape_name(s_format("%s_%s_%s", host or "global", sect, typ)); | |
84 | 81 |
85 if not meta:get(key) then | 82 local key = escape_name("prosody_"..sect.."_"..name); |
86 if host then | 83 local field = { |
87 meta:set(key, "", "graph_title", s_format("%s %s on %s", sect, typ, host)); | 84 value = value, |
88 else | 85 labels = {}, |
89 meta:set(key, "", "graph_title", s_format("Global %s %s", sect, typ, host)); | 86 -- TODO: Use the other types where it makes sense. |
90 end | 87 typ = (typ == "rate" and "counter" or "gauge"), |
91 meta:set(key, "", "graph_vlabel", this and this.units or typ); | 88 }; |
92 meta:set(key, "", "graph_category", sect); | 89 if host then |
93 | 90 field.labels.host = host; |
94 meta:set(key, name, "label", name); | |
95 elseif not meta:get(key, name, "label") then | |
96 meta:set(key, name, "label", name); | |
97 end | 91 end |
98 | 92 if data[key] == nil then |
99 data:set(key, name, value); | 93 data[key] = {}; |
94 end | |
95 t_insert(data[key], field); | |
100 end | 96 end |
101 end); | 97 end); |
102 | 98 |
103 local function get_metrics(event) | 99 local function get_metrics(event) |
104 local response = event.response; | 100 local response = event.response; |
105 response.headers.content_type = "text/plain; version=0.4.4"; | 101 response.headers.content_type = "text/plain; version=0.4.4"; |
106 | 102 |
107 local answer = {}; | 103 local answer = {}; |
108 local timestamp = tostring(get_timestamp()); | 104 local timestamp = tostring(get_timestamp()); |
109 for section, content in pairs(data.data) do | 105 for key, fields in pairs(data) do |
110 for key, value in pairs(content) do | 106 t_insert(answer, repr_help(key, "TODO: add a description here.")); |
111 local name = "prosody_"..section.."_"..key; | 107 t_insert(answer, repr_type(key, fields[1].typ)); |
112 t_insert(answer, repr_help(name, "TODO: add a description here.")); | 108 for _, field in pairs(fields) do |
113 t_insert(answer, repr_type(name, "gauge")); | 109 t_insert(answer, repr_sample(key, field.labels, field.value, timestamp)); |
114 t_insert(answer, repr_sample(name, {}, value, timestamp)); | |
115 end | 110 end |
116 end | 111 end |
117 return t_concat(answer, ""); | 112 return t_concat(answer, ""); |
118 end | 113 end |
119 | 114 |