emqx/apps/emqx_management/src/emqx_mgmt_api_stats.erl

136 lines
4.8 KiB
Erlang

%%--------------------------------------------------------------------
%% Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(emqx_mgmt_api_stats).
-behaviour(minirest_api).
-include_lib("typerefl/include/types.hrl").
-import(
hoconsc,
[
mk/2,
ref/1,
ref/2,
array/1
]
).
-export([
api_spec/0,
paths/0,
schema/1,
fields/1
]).
-export([list/2]).
api_spec() ->
emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}).
paths() ->
["/stats"].
schema("/stats") ->
#{
'operationId' => list,
get =>
#{
description => <<"EMQX stats">>,
tags => [<<"Metrics">>],
parameters => [ref(aggregate)],
responses =>
#{
200 => mk(
hoconsc:union([
ref(?MODULE, node_stats_data),
array(ref(?MODULE, aggergate_data))
]),
#{desc => <<"List stats ok">>}
)
}
}
}.
fields(aggregate) ->
[
{aggregate,
mk(
boolean(),
#{
desc => <<"Calculation aggregate for all nodes">>,
in => query,
required => false,
example => false
}
)}
];
fields(node_stats_data) ->
[
stats_schema('channels.count', <<"sessions.count">>),
stats_schema('channels.max', <<"session.max">>),
stats_schema('connections.count', <<"Number of current connections">>),
stats_schema('connections.max', <<"Historical maximum number of connections">>),
stats_schema('delayed.count', <<"Number of delayed messages">>),
stats_schema('delayed.max', <<"Historical maximum number of delayed messages">>),
stats_schema('live_connections.count', <<"Number of current live connections">>),
stats_schema('live_connections.max', <<"Historical maximum number of live connections">>),
stats_schema('retained.count', <<"Number of currently retained messages">>),
stats_schema('retained.max', <<"Historical maximum number of retained messages">>),
stats_schema('sessions.count', <<"Number of current sessions">>),
stats_schema('sessions.max', <<"Historical maximum number of sessions">>),
stats_schema('suboptions.count', <<"subscriptions.count">>),
stats_schema('suboptions.max', <<"subscriptions.max">>),
stats_schema('subscribers.count', <<"Number of current subscribers">>),
stats_schema('subscribers.max', <<"Historical maximum number of subscribers">>),
stats_schema(
'subscriptions.count',
<<"Number of current subscriptions, including shared subscriptions">>
),
stats_schema('subscriptions.max', <<"Historical maximum number of subscriptions">>),
stats_schema('subscriptions.shared.count', <<"Number of current shared subscriptions">>),
stats_schema(
'subscriptions.shared.max', <<"Historical maximum number of shared subscriptions">>
),
stats_schema('topics.count', <<"Number of current topics">>),
stats_schema('topics.max', <<"Historical maximum number of topics">>)
];
fields(aggergate_data) ->
[
{node,
mk(string(), #{
desc => <<"Node name">>,
example => <<"emqx@127.0.0.1">>
})}
] ++ fields(node_stats_data).
stats_schema(Name, Desc) ->
{Name, mk(non_neg_integer(), #{desc => Desc, example => 0})}.
%%%==============================================================================================
%% api apply
list(get, #{query_string := Qs}) ->
case maps:get(<<"aggregate">>, Qs, undefined) of
true ->
{200, emqx_mgmt:get_stats()};
_ ->
Data = [
maps:from_list(emqx_mgmt:get_stats(Node) ++ [{node, Node}])
|| Node <- mria_mnesia:running_nodes()
],
{200, Data}
end.