Mercurial > prosody-hg
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 |
| parents | 82765a4ec799 |
| children | 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]; |
