aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/statsmanager.lua1
-rw-r--r--util/statsd.lua84
2 files changed, 85 insertions, 0 deletions
diff --git a/core/statsmanager.lua b/core/statsmanager.lua
index d103c6a7..9572f68d 100644
--- a/core/statsmanager.lua
+++ b/core/statsmanager.lua
@@ -15,6 +15,7 @@ local stats_provider = stats_provider_config or "internal";
local builtin_providers = {
internal = "util.statistics";
+ statsd = "util.statsd";
};
if stats_provider:match("^library:") then
diff --git a/util/statsd.lua b/util/statsd.lua
new file mode 100644
index 00000000..2874e8a8
--- /dev/null
+++ b/util/statsd.lua
@@ -0,0 +1,84 @@
+local socket = require "socket";
+
+local time = require "socket".gettime;
+
+local function new(config)
+ if not config or not config.statsd_server then
+ return nil, "No statsd server specified in the config, please see https://prosody.im/doc/statistics";
+ end
+
+ local sock = socket.udp();
+ sock:setpeername(config.statsd_server, config.statsd_port or 8125);
+
+ local prefix = (config.prefix or "prosody")..".";
+
+ local function send_metric(s)
+ return sock:send(prefix..s);
+ end
+
+ local function send_gauge(name, amount, relative)
+ local s_amount = tostring(amount);
+ if relative and amount > 0 then
+ s_amount = "+"..s_amount;
+ end
+ return send_metric(name..":"..s_amount.."|g");
+ end
+
+ local function send_counter(name, amount)
+ return send_metric(name..":"..tostring(amount).."|c");
+ end
+
+ local function send_duration(name, duration)
+ return send_metric(name..":"..tostring(duration).."|ms");
+ end
+
+ local function send_histogram_sample(name, sample)
+ return send_metric(name..":"..tostring(sample).."|h");
+ end
+
+ local methods;
+ methods = {
+ amount = function (name, initial)
+ if initial then
+ send_gauge(name, initial);
+ end
+ return function (new_v) send_gauge(name, new_v); end
+ end;
+ counter = function (name, initial)
+ return function (delta)
+ send_gauge(name, delta, true);
+ end;
+ end;
+ rate = function (name)
+ return function ()
+ send_counter(name, 1);
+ end;
+ end;
+ distribution = function (name, unit, type) --luacheck: ignore 212/unit 212/type
+ return function (value)
+ send_histogram_sample(name, value);
+ end;
+ end;
+ sizes = function (name)
+ name = name.."_size";
+ return function (value)
+ send_histogram_sample(name, value);
+ end;
+ end;
+ times = function (name)
+ return function ()
+ local start_time = time();
+ return function ()
+ local end_time = time();
+ local duration = end_time - start_time;
+ send_duration(name, duration*1000);
+ end
+ end;
+ end;
+ };
+ return methods;
+end
+
+return {
+ new = new;
+}