statsmanager, prosody: New core module and API for gathering statistics about the...
authorMatthew Wild <mwild1@gmail.com>
Tue, 20 Jan 2015 12:33:20 +0000 (12:33 +0000)
committerMatthew Wild <mwild1@gmail.com>
Tue, 20 Jan 2015 12:33:20 +0000 (12:33 +0000)
core/statsmanager.lua [new file with mode: 0644]
prosody

diff --git a/core/statsmanager.lua b/core/statsmanager.lua
new file mode 100644 (file)
index 0000000..83df618
--- /dev/null
@@ -0,0 +1,75 @@
+
+local stats = require "util.statistics".new();
+local config = require "core.configmanager";
+local log = require "util.logger".init("stats");
+local timer = require "util.timer";
+local fire_event = prosody.events.fire_event;
+
+local stats_config = config.get("*", "statistics_interval");
+local stats_interval = tonumber(stats_config);
+if stats_config and not stats_interval then
+       log("error", "Invalid 'statistics_interval' setting, statistics will be disabled");
+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);
+       function measure(type, name)
+               local f = assert(stats[type], "unknown stat type: "..type);
+               return f(name);
+       end
+
+       local mark_collection_start = measure("duration", "stats.collection_time");
+       local mark_processing_start = measure("duration", "stats.processing_time");
+
+       function collect()
+               local mark_collection_done = mark_collection_start();
+               changed_stats, stats_extra = {}, {};
+               for name, getter in pairs(stats.get_stats()) do
+                       local type, value, extra = getter();
+                       local stat_name = name..":"..type;
+                       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
+                               print(stat_name, extra)
+                               stats_extra[stat_name] = extra;
+                               if type == "duration" then
+                                       local rate = extra.rate;
+                                       local rate_name = name..":rate";
+                                       latest_stats[rate_name] = rate;
+                                       changed_stats[rate_name] = rate;
+                               end
+                       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
+
+       timer.add_task(stats_interval, collect);
+else
+       log("debug", "Statistics collection is disabled");
+       -- nop
+       function measure()
+               return measure;
+       end
+       function collect()
+       end
+end
+
+return {
+       measure = measure;
+       collect = collect;
+       get_stats = function ()
+               return latest_stats, changed_stats, stats_extra;
+       end;
+};
diff --git a/prosody b/prosody
index e8f81d5d6ec6a8144237cd37635a7f142c303ba7..e6a23d8e703f6fb172f188d45a6e87a089fde333 100755 (executable)
--- a/prosody
+++ b/prosody
@@ -292,6 +292,7 @@ function load_secondary_libraries()
        require "util.import"
        require "util.xmppstream"
        require "core.stanza_router"
+       require "core.statsmanager"
        require "core.hostmanager"
        require "core.portmanager"
        require "core.modulemanager"