From 9f59d86b2350d383ae6fb914130a50e65b33dc39 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Sat, 25 Apr 2015 23:04:12 +0800 Subject: [PATCH] add emqttd_stats --- apps/emqttd/src/emqttd_broker.erl | 5 -- apps/emqttd/src/emqttd_stats.erl | 143 ++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 apps/emqttd/src/emqttd_stats.erl diff --git a/apps/emqttd/src/emqttd_broker.erl b/apps/emqttd/src/emqttd_broker.erl index 1933a180f..17d685156 100644 --- a/apps/emqttd/src/emqttd_broker.erl +++ b/apps/emqttd/src/emqttd_broker.erl @@ -41,11 +41,6 @@ -export([version/0, uptime/0, datetime/0, sysdescr/0]). -%% statistics API. --export([statsfun/1, statsfun/2, - getstats/0, getstat/1, - setstat/2, setstats/3]). - %% gen_server Function Exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). diff --git a/apps/emqttd/src/emqttd_stats.erl b/apps/emqttd/src/emqttd_stats.erl new file mode 100644 index 000000000..0af6fc827 --- /dev/null +++ b/apps/emqttd/src/emqttd_stats.erl @@ -0,0 +1,143 @@ +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% emqttd statistics. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqttd_stats). + +-author("Feng Lee "). + +-include("emqttd_systop.hrl"). + +-behaviour(gen_server). + +-define(SERVER, ?MODULE). + +%% statistics API. +-export([statsfun/1, statsfun/2, + getstats/0, getstat/1, + setstat/2, setstats/3]). + +%% gen_server Function Exports +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-define(STATS_TAB, mqtt_stats). + +-record(state, {sys_interval, tick_timer}). + +%%%============================================================================= +%%% API +%%%============================================================================= + +%%------------------------------------------------------------------------------ +%% @doc Start stats server +%% @end +%%------------------------------------------------------------------------------ +-spec start_link() -> {ok, pid()} | ignore | {error, term()}. +start_link() -> + gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). + +%%------------------------------------------------------------------------------ +%% @doc Generate stats fun +%% @end +%%------------------------------------------------------------------------------ +-spec statsfun(Stat :: atom()) -> fun(). +statsfun(Stat) -> + fun(Val) -> setstat(Stat, Val) end. + +-spec statsfun(Stat :: atom(), MaxStat :: atom()) -> fun(). +statsfun(Stat, MaxStat) -> + fun(Val) -> setstats(Stat, MaxStat, Val) end. + +%%------------------------------------------------------------------------------ +%% @doc Get broker statistics +%% @end +%%------------------------------------------------------------------------------ +-spec getstats() -> [{atom(), non_neg_integer()}]. +getstats() -> + ets:tab2list(?STATS_TAB). + +%%------------------------------------------------------------------------------ +%% @doc Get stats by name +%% @end +%%------------------------------------------------------------------------------ +-spec getstat(atom()) -> non_neg_integer() | undefined. +getstat(Name) -> + case ets:lookup(?STATS_TAB, Name) of + [{Name, Val}] -> Val; + [] -> undefined + end. + +%%------------------------------------------------------------------------------ +%% @doc Set broker stats +%% @end +%%------------------------------------------------------------------------------ +-spec setstat(Stat :: atom(), Val :: pos_integer()) -> boolean(). +setstat(Stat, Val) -> + ets:update_element(?STATS_TAB, Stat, {2, Val}). + +%%------------------------------------------------------------------------------ +%% @doc Set stats with max +%% @end +%%------------------------------------------------------------------------------ +-spec setstats(Stat :: atom(), MaxStat :: atom(), Val :: pos_integer()) -> boolean(). +setstats(Stat, MaxStat, Val) -> + MaxVal = ets:lookup_element(?STATS_TAB, MaxStat, 2), + if + Val > MaxVal -> + ets:update_element(?STATS_TAB, MaxStat, {2, Val}); + true -> ok + end, + ets:update_element(?STATS_TAB, Stat, {2, Val}). + +%%%============================================================================= +%%% gen_server callbacks +%%%============================================================================= + +init([]) -> + random:seed(now()), + ets:new(?STATS_TAB, [set, public, named_table, {write_concurrency, true}]), + {ok, #state{}}. + +handle_call(_Request, _From, State) -> + {reply, error, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%============================================================================= +%%% Internal functions +%%%============================================================================= + +