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