Mercurial > prosody-hg
comparison core/statsmanager.lua @ 7533:4ef37ac69562
statsmanager: Refactor to simplify logic. Notably renames 'statistics_provider' to 'statistics', and external libs now just begin with ':'
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 29 Jul 2016 13:20:02 +0100 |
| parents | b6f32bb3b584 |
| children | 4f145a9f1477 |
comparison
equal
deleted
inserted
replaced
| 7531:2db68d1a6eeb | 7533:4ef37ac69562 |
|---|---|
| 2 local config = require "core.configmanager"; | 2 local config = require "core.configmanager"; |
| 3 local log = require "util.logger".init("stats"); | 3 local log = require "util.logger".init("stats"); |
| 4 local timer = require "util.timer"; | 4 local timer = require "util.timer"; |
| 5 local fire_event = prosody.events.fire_event; | 5 local fire_event = prosody.events.fire_event; |
| 6 | 6 |
| 7 local stats_config = config.get("*", "statistics_interval"); | 7 local stats_interval_config = config.get("*", "statistics_interval"); |
| 8 local stats_interval = tonumber(stats_config); | 8 local stats_interval = tonumber(stats_interval_config); |
| 9 if stats_config and not stats_interval then | 9 if stats_config and not stats_interval then |
| 10 log("error", "Invalid 'statistics_interval' setting, statistics will be disabled"); | 10 log("error", "Invalid 'statistics_interval' setting, statistics will be disabled"); |
| 11 end | 11 end |
| 12 | 12 |
| 13 local stats_provider_config = config.get("*", "statistics_provider"); | 13 local stats_provider_name; |
| 14 local stats_provider = stats_provider_config or "internal"; | 14 local stats_provider_config = config.get("*", "statistics"); |
| 15 local stats_provider = stats_provider_config; | |
| 16 | |
| 17 if not stats_provider and stats_interval then | |
| 18 stats_provider = "internal"; | |
| 19 elseif stats_provider and not stats_interval then | |
| 20 stats_interval = 60; | |
| 21 end | |
| 15 | 22 |
| 16 local builtin_providers = { | 23 local builtin_providers = { |
| 17 internal = "util.statistics"; | 24 internal = "util.statistics"; |
| 18 statsd = "util.statsd"; | 25 statsd = "util.statsd"; |
| 19 }; | 26 }; |
| 20 | 27 |
| 21 if stats_provider:match("^library:") then | 28 |
| 22 stats_provider = stats_provider:match(":(.+)$"); | 29 local stats, stats_err = false, nil; |
| 23 else | 30 |
| 24 stats_provider = builtin_providers[stats_provider]; | 31 if stats_provider then |
| 25 if not stats_provider then | 32 if stats_provider:sub(1,1) == ":" then |
| 26 log("error", "Unrecognized built-in statistics provider '%s', using internal instead", stats_provider_config); | 33 stats_provider = stats_provider:sub(2); |
| 27 stats_provider = builtin_providers["internal"]; | 34 stats_provider_name = "external "..stats_provider; |
| 35 elseif stats_provider then | |
| 36 stats_provider_name = "built-in "..stats_provider; | |
| 37 stats_provider = builtin_providers[stats_provider]; | |
| 38 if not stats_provider then | |
| 39 log("error", "Unrecognized statistics provider '%s', statistics will be disabled", stats_provider_config); | |
| 40 end | |
| 41 end | |
| 42 | |
| 43 local have_stats_provider, stats_lib = pcall(require, stats_provider); | |
| 44 if not have_stats_provider then | |
| 45 stats, stats_err = nil, stats_lib; | |
| 46 else | |
| 47 local stats_config = config.get("*", "statistics_config"); | |
| 48 stats, stats_err = stats_lib.new(stats_config); | |
| 49 stats_provider_name = stats_lib._NAME or stats_provider_name; | |
| 28 end | 50 end |
| 29 end | 51 end |
| 30 | 52 |
| 31 local have_stats_provider, stats_lib = pcall(require, stats_provider); | 53 if stats == nil then |
| 32 | |
| 33 local stats, stats_err; | |
| 34 | |
| 35 if not have_stats_provider then | |
| 36 stats, stats_err = nil, stats_lib; | |
| 37 else | |
| 38 local stats_config = config.get("*", "statistics_config"); | |
| 39 stats, stats_err = stats_lib.new(stats_config); | |
| 40 end | |
| 41 | |
| 42 if not stats then | |
| 43 log("error", "Error loading statistics provider '%s': %s", stats_provider, stats_err); | 54 log("error", "Error loading statistics provider '%s': %s", stats_provider, stats_err); |
| 44 end | 55 end |
| 45 | 56 |
| 46 local measure, collect; | 57 local measure, collect; |
| 47 local latest_stats = {}; | 58 local latest_stats = {}; |
| 51 if stats then | 62 if stats then |
| 52 function measure(type, name) | 63 function measure(type, name) |
| 53 local f = assert(stats[type], "unknown stat type: "..type); | 64 local f = assert(stats[type], "unknown stat type: "..type); |
| 54 return f(name); | 65 return f(name); |
| 55 end | 66 end |
| 67 | |
| 68 if stats_interval then | |
| 69 log("debug", "Statistics enabled using %s provider, collecting every %d seconds", stats_provider_name, stats_interval); | |
| 70 | |
| 71 local mark_collection_start = measure("times", "stats.collection"); | |
| 72 local mark_processing_start = measure("times", "stats.processing"); | |
| 73 | |
| 74 function collect() | |
| 75 local mark_collection_done = mark_collection_start(); | |
| 76 fire_event("stats-update"); | |
| 77 mark_collection_done(); | |
| 78 | |
| 79 if stats.get_stats then | |
| 80 changed_stats, stats_extra = {}, {}; | |
| 81 for stat_name, getter in pairs(stats.get_stats()) do | |
| 82 local type, value, extra = getter(); | |
| 83 local old_value = latest_stats[stat_name]; | |
| 84 latest_stats[stat_name] = value; | |
| 85 if value ~= old_value then | |
| 86 changed_stats[stat_name] = value; | |
| 87 end | |
| 88 if extra then | |
| 89 stats_extra[stat_name] = extra; | |
| 90 end | |
| 91 end | |
| 92 local mark_processing_done = mark_processing_start(); | |
| 93 fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra }); | |
| 94 mark_processing_done(); | |
| 95 end | |
| 96 return stats_interval; | |
| 97 end | |
| 98 timer.add_task(stats_interval, collect); | |
| 99 prosody.events.add_handler("server-started", function () collect() end, -1); | |
| 100 else | |
| 101 log("debug", "Statistics enabled using %s provider, collection is disabled", stats_provider_name); | |
| 102 end | |
| 103 else | |
| 104 log("debug", "Statistics disabled"); | |
| 105 function measure() return measure; end | |
| 56 end | 106 end |
| 57 | 107 |
| 58 if stats_interval then | |
| 59 log("debug", "Statistics collection is enabled every %d seconds", stats_interval); | |
| 60 | |
| 61 local mark_collection_start = measure("times", "stats.collection"); | |
| 62 local mark_processing_start = measure("times", "stats.processing"); | |
| 63 | |
| 64 function collect() | |
| 65 local mark_collection_done = mark_collection_start(); | |
| 66 fire_event("stats-update"); | |
| 67 mark_collection_done(); | |
| 68 | |
| 69 if stats.get_stats then | |
| 70 changed_stats, stats_extra = {}, {}; | |
| 71 for stat_name, getter in pairs(stats.get_stats()) do | |
| 72 local type, value, extra = getter(); | |
| 73 local old_value = latest_stats[stat_name]; | |
| 74 latest_stats[stat_name] = value; | |
| 75 if value ~= old_value then | |
| 76 changed_stats[stat_name] = value; | |
| 77 end | |
| 78 if extra then | |
| 79 stats_extra[stat_name] = extra; | |
| 80 end | |
| 81 end | |
| 82 local mark_processing_done = mark_processing_start(); | |
| 83 fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra }); | |
| 84 mark_processing_done(); | |
| 85 end | |
| 86 return stats_interval; | |
| 87 end | |
| 88 timer.add_task(stats_interval, collect); | |
| 89 prosody.events.add_handler("server-started", function () collect() end, -1); | |
| 90 end | |
| 91 | |
| 92 if not stats_interval and stats_provider == "util.statistics" then | |
| 93 log("debug", "Statistics collection is disabled"); | |
| 94 -- nop | |
| 95 function measure() | |
| 96 return measure; | |
| 97 end | |
| 98 function collect() | |
| 99 end | |
| 100 end | |
| 101 | 108 |
| 102 return { | 109 return { |
| 103 measure = measure; | 110 measure = measure; |
| 104 get_stats = function () | 111 get_stats = function () |
| 105 return latest_stats, changed_stats, stats_extra; | 112 return latest_stats, changed_stats, stats_extra; |
