Software /
code /
prosody
File
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 |
line wrap: on
line source
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 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 then function measure(type, name) local f = assert(stats[type], "unknown stat type: "..type); return f(name); end end if stats_interval then if stats.get_stats then log("debug", "Statistics collection is enabled every %d seconds", stats_interval); 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 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 if not stats_interval and stats_provider == "util.statistics" then log("debug", "Statistics collection is disabled"); -- nop function measure() return measure; end function collect() end end return { measure = measure; get_stats = function () return latest_stats, changed_stats, stats_extra; end; get = function (name) return latest_stats[name], stats_extra[name]; end; };