From 0f8377e56a0fa4e6a46c96195445aeee07557c58 Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Wed, 27 Jul 2016 14:04:36 +0100
Subject: statsmanager: Add 'stats_provider' option, to allow selecting
 alternative API providers to util.statistics

---
 core/statsmanager.lua | 92 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 65 insertions(+), 27 deletions(-)

(limited to 'core')

diff --git a/core/statsmanager.lua b/core/statsmanager.lua
index 7771a2b3..d103c6a7 100644
--- a/core/statsmanager.lua
+++ b/core/statsmanager.lua
@@ -1,5 +1,4 @@
 
-local stats = require "util.statistics".new();
 local config = require "core.configmanager";
 local log = require "util.logger".init("stats");
 local timer = require "util.timer";
@@ -11,46 +10,86 @@ if stats_config and not stats_interval then
 	log("error", "Invalid 'statistics_interval' setting, statistics will be disabled");
 end
 
+local stats_provider_config = config.get("*", "statistics_provider");
+local stats_provider = stats_provider_config or "internal";
+
+local builtin_providers = {
+	internal = "util.statistics";
+};
+
+if stats_provider:match("^library:") then
+	stats_provider = stats_provider:match(":(.+)$");
+else
+	stats_provider = builtin_providers[stats_provider];
+	if not stats_provider then
+		log("error", "Unrecognized built-in statistics provider '%s', using internal instead", stats_provider_config);
+		stats_provider = builtin_providers["internal"];
+	end
+end
+
+local have_stats_provider, stats_lib = pcall(require, stats_provider);
+
+local stats, stats_err;
+
+if not have_stats_provider then
+	stats, stats_err = nil, stats_lib;
+else
+	local stats_config = config.get("*", "statistics_config");
+	stats, stats_err = stats_lib.new(stats_config);
+end
+
+if not stats then
+	log("error", "Error loading statistics provider '%s': %s", stats_provider, stats_err);
+end
+
 local measure, collect;
 local latest_stats = {};
 local changed_stats = {};
 local stats_extra = {};
 
-if stats_interval then
-	log("debug", "Statistics collection is enabled every %d seconds", stats_interval);
+if stats then
 	function measure(type, name)
 		local f = assert(stats[type], "unknown stat type: "..type);
 		return f(name);
 	end
+end
 
-	local mark_collection_start = measure("times", "stats.collection");
-	local mark_processing_start = measure("times", "stats.processing");
+if stats_interval then
+	if stats.get_stats then
+		log("debug", "Statistics collection is enabled every %d seconds", stats_interval);
 
-	function collect()
-		local mark_collection_done = mark_collection_start();
-		fire_event("stats-update");
-		changed_stats, stats_extra = {}, {};
-		for stat_name, getter in pairs(stats.get_stats()) do
-			local type, value, extra = getter();
-			local old_value = latest_stats[stat_name];
-			latest_stats[stat_name] = value;
-			if value ~= old_value then
-				changed_stats[stat_name] = value;
-			end
-			if extra then
-				stats_extra[stat_name] = extra;
+		local mark_collection_start = measure("times", "stats.collection");
+		local mark_processing_start = measure("times", "stats.processing");
+
+		function collect()
+			local mark_collection_done = mark_collection_start();
+			fire_event("stats-update");
+			changed_stats, stats_extra = {}, {};
+			for stat_name, getter in pairs(stats.get_stats()) do
+				local type, value, extra = getter();
+				local old_value = latest_stats[stat_name];
+				latest_stats[stat_name] = value;
+				if value ~= old_value then
+					changed_stats[stat_name] = value;
+				end
+				if extra then
+					stats_extra[stat_name] = extra;
+				end
 			end
+			mark_collection_done();
+			local mark_processing_done = mark_processing_start();
+			fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra });
+			mark_processing_done();
+			return stats_interval;
 		end
-		mark_collection_done();
-		local mark_processing_done = mark_processing_start();
-		fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra });
-		mark_processing_done();
-		return stats_interval;
+		timer.add_task(stats_interval, collect);
+		prosody.events.add_handler("server-started", function () collect() end, -1);
+	else
+		log("error", "statistics_interval specified, but the selected statistics_provider (%s) does not support statistics collection", stats_provider_config or "internal");
 	end
+end
 
-	timer.add_task(stats_interval, collect);
-	prosody.events.add_handler("server-started", function () collect() end, -1);
-else
+if not stats_interval and stats_provider == "util.statistics" then
 	log("debug", "Statistics collection is disabled");
 	-- nop
 	function measure()
@@ -62,7 +101,6 @@ end
 
 return {
 	measure = measure;
-	collect = collect;
 	get_stats = function ()
 		return latest_stats, changed_stats, stats_extra;
 	end;
-- 
cgit v1.2.3


From 79940f40e79e453383693bb7e2559e3e335b87dc Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Wed, 27 Jul 2016 14:06:10 +0100
Subject: statsmanager, util.statsd: Add built-in statsd provider

---
 core/statsmanager.lua | 1 +
 1 file changed, 1 insertion(+)

(limited to 'core')

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
-- 
cgit v1.2.3