Comparison

core/statsmanager.lua @ 7521:1c8b63fe6472

statsmanager: Add 'stats_provider' option, to allow selecting alternative API providers to util.statistics
author Matthew Wild <mwild1@gmail.com>
date Wed, 27 Jul 2016 14:04:36 +0100
parent 6910:82765a4ec799
child 7522:ebf2e77ac8a7
comparison
equal deleted inserted replaced
7520:fc6c24cb3599 7521:1c8b63fe6472
1 1
2 local stats = require "util.statistics".new();
3 local config = require "core.configmanager"; 2 local config = require "core.configmanager";
4 local log = require "util.logger".init("stats"); 3 local log = require "util.logger".init("stats");
5 local timer = require "util.timer"; 4 local timer = require "util.timer";
6 local fire_event = prosody.events.fire_event; 5 local fire_event = prosody.events.fire_event;
7 6
9 local stats_interval = tonumber(stats_config); 8 local stats_interval = tonumber(stats_config);
10 if stats_config and not stats_interval then 9 if stats_config and not stats_interval then
11 log("error", "Invalid 'statistics_interval' setting, statistics will be disabled"); 10 log("error", "Invalid 'statistics_interval' setting, statistics will be disabled");
12 end 11 end
13 12
13 local stats_provider_config = config.get("*", "statistics_provider");
14 local stats_provider = stats_provider_config or "internal";
15
16 local builtin_providers = {
17 internal = "util.statistics";
18 };
19
20 if stats_provider:match("^library:") then
21 stats_provider = stats_provider:match(":(.+)$");
22 else
23 stats_provider = builtin_providers[stats_provider];
24 if not stats_provider then
25 log("error", "Unrecognized built-in statistics provider '%s', using internal instead", stats_provider_config);
26 stats_provider = builtin_providers["internal"];
27 end
28 end
29
30 local have_stats_provider, stats_lib = pcall(require, stats_provider);
31
32 local stats, stats_err;
33
34 if not have_stats_provider then
35 stats, stats_err = nil, stats_lib;
36 else
37 local stats_config = config.get("*", "statistics_config");
38 stats, stats_err = stats_lib.new(stats_config);
39 end
40
41 if not stats then
42 log("error", "Error loading statistics provider '%s': %s", stats_provider, stats_err);
43 end
44
14 local measure, collect; 45 local measure, collect;
15 local latest_stats = {}; 46 local latest_stats = {};
16 local changed_stats = {}; 47 local changed_stats = {};
17 local stats_extra = {}; 48 local stats_extra = {};
18 49
19 if stats_interval then 50 if stats then
20 log("debug", "Statistics collection is enabled every %d seconds", stats_interval);
21 function measure(type, name) 51 function measure(type, name)
22 local f = assert(stats[type], "unknown stat type: "..type); 52 local f = assert(stats[type], "unknown stat type: "..type);
23 return f(name); 53 return f(name);
24 end 54 end
55 end
25 56
26 local mark_collection_start = measure("times", "stats.collection"); 57 if stats_interval then
27 local mark_processing_start = measure("times", "stats.processing"); 58 if stats.get_stats then
59 log("debug", "Statistics collection is enabled every %d seconds", stats_interval);
28 60
29 function collect() 61 local mark_collection_start = measure("times", "stats.collection");
30 local mark_collection_done = mark_collection_start(); 62 local mark_processing_start = measure("times", "stats.processing");
31 fire_event("stats-update"); 63
32 changed_stats, stats_extra = {}, {}; 64 function collect()
33 for stat_name, getter in pairs(stats.get_stats()) do 65 local mark_collection_done = mark_collection_start();
34 local type, value, extra = getter(); 66 fire_event("stats-update");
35 local old_value = latest_stats[stat_name]; 67 changed_stats, stats_extra = {}, {};
36 latest_stats[stat_name] = value; 68 for stat_name, getter in pairs(stats.get_stats()) do
37 if value ~= old_value then 69 local type, value, extra = getter();
38 changed_stats[stat_name] = value; 70 local old_value = latest_stats[stat_name];
71 latest_stats[stat_name] = value;
72 if value ~= old_value then
73 changed_stats[stat_name] = value;
74 end
75 if extra then
76 stats_extra[stat_name] = extra;
77 end
39 end 78 end
40 if extra then 79 mark_collection_done();
41 stats_extra[stat_name] = extra; 80 local mark_processing_done = mark_processing_start();
42 end 81 fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra });
82 mark_processing_done();
83 return stats_interval;
43 end 84 end
44 mark_collection_done(); 85 timer.add_task(stats_interval, collect);
45 local mark_processing_done = mark_processing_start(); 86 prosody.events.add_handler("server-started", function () collect() end, -1);
46 fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra }); 87 else
47 mark_processing_done(); 88 log("error", "statistics_interval specified, but the selected statistics_provider (%s) does not support statistics collection", stats_provider_config or "internal");
48 return stats_interval;
49 end 89 end
90 end
50 91
51 timer.add_task(stats_interval, collect); 92 if not stats_interval and stats_provider == "util.statistics" then
52 prosody.events.add_handler("server-started", function () collect() end, -1);
53 else
54 log("debug", "Statistics collection is disabled"); 93 log("debug", "Statistics collection is disabled");
55 -- nop 94 -- nop
56 function measure() 95 function measure()
57 return measure; 96 return measure;
58 end 97 end
60 end 99 end
61 end 100 end
62 101
63 return { 102 return {
64 measure = measure; 103 measure = measure;
65 collect = collect;
66 get_stats = function () 104 get_stats = function ()
67 return latest_stats, changed_stats, stats_extra; 105 return latest_stats, changed_stats, stats_extra;
68 end; 106 end;
69 get = function (name) 107 get = function (name)
70 return latest_stats[name], stats_extra[name]; 108 return latest_stats[name], stats_extra[name];