emqx_telemetry_api.erl 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2023 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_telemetry_api).
  17. -behaviour(minirest_api).
  18. -include_lib("hocon/include/hoconsc.hrl").
  19. -include_lib("typerefl/include/types.hrl").
  20. -import(hoconsc, [mk/2, ref/1, ref/2, array/1]).
  21. -export([
  22. status/2,
  23. data/2
  24. ]).
  25. -export([
  26. api_spec/0,
  27. paths/0,
  28. schema/1,
  29. fields/1
  30. ]).
  31. -define(BAD_REQUEST, 'BAD_REQUEST').
  32. -define(NOT_FOUND, 'NOT_FOUND').
  33. api_spec() ->
  34. emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}).
  35. paths() ->
  36. [
  37. "/telemetry/status",
  38. "/telemetry/data"
  39. ].
  40. schema("/telemetry/status") ->
  41. #{
  42. 'operationId' => status,
  43. get =>
  44. #{
  45. description => ?DESC(get_telemetry_status_api),
  46. tags => [<<"Telemetry">>],
  47. responses =>
  48. #{200 => status_schema(?DESC(get_telemetry_status_api))}
  49. },
  50. put =>
  51. #{
  52. description => ?DESC(update_telemetry_status_api),
  53. tags => [<<"Telemetry">>],
  54. 'requestBody' => status_schema(?DESC(update_telemetry_status_api)),
  55. responses =>
  56. #{
  57. 200 => status_schema(?DESC(update_telemetry_status_api)),
  58. 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad Request">>)
  59. }
  60. }
  61. };
  62. schema("/telemetry/data") ->
  63. #{
  64. 'operationId' => data,
  65. get =>
  66. #{
  67. description => ?DESC(get_telemetry_data_api),
  68. tags => [<<"Telemetry">>],
  69. responses =>
  70. #{
  71. 200 => mk(ref(?MODULE, telemetry), #{desc => ?DESC(get_telemetry_data_api)}),
  72. 404 => emqx_dashboard_swagger:error_codes(
  73. [?NOT_FOUND], <<"Telemetry is not enabled">>
  74. )
  75. }
  76. }
  77. }.
  78. status_schema(Desc) ->
  79. mk(ref(?MODULE, status), #{in => body, desc => Desc}).
  80. fields(status) ->
  81. [
  82. {enable,
  83. mk(
  84. boolean(),
  85. #{
  86. desc => ?DESC(enable),
  87. default => true,
  88. example => false
  89. }
  90. )}
  91. ];
  92. fields(telemetry) ->
  93. [
  94. {emqx_version,
  95. mk(
  96. string(),
  97. #{
  98. desc => ?DESC(emqx_version),
  99. example => <<"5.0.0-beta.3-32d1547c">>
  100. }
  101. )},
  102. {license,
  103. mk(
  104. map(),
  105. #{
  106. desc => ?DESC(license),
  107. example => #{edition => <<"opensource">>}
  108. }
  109. )},
  110. {os_name,
  111. mk(
  112. string(),
  113. #{
  114. desc => ?DESC(os_name),
  115. example => <<"Linux">>
  116. }
  117. )},
  118. {os_version,
  119. mk(
  120. string(),
  121. #{
  122. desc => ?DESC(os_version),
  123. example => <<"20.04">>
  124. }
  125. )},
  126. {otp_version,
  127. mk(
  128. string(),
  129. #{
  130. desc => ?DESC(otp_version),
  131. example => <<"24">>
  132. }
  133. )},
  134. {up_time,
  135. mk(
  136. integer(),
  137. #{
  138. desc => ?DESC(up_time),
  139. example => 20220113
  140. }
  141. )},
  142. {uuid,
  143. mk(
  144. string(),
  145. #{
  146. desc => ?DESC(uuid),
  147. example => <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">>
  148. }
  149. )},
  150. {nodes_uuid,
  151. mk(
  152. array(binary()),
  153. #{
  154. desc => ?DESC(nodes_uuid),
  155. example => [
  156. <<"AAAAAAAA-BBBB-CCCC-2022-DDDDEEEEFFF">>,
  157. <<"ZZZZZZZZ-CCCC-BBBB-2022-DDDDEEEEFFF">>
  158. ]
  159. }
  160. )},
  161. {active_plugins,
  162. mk(
  163. array(binary()),
  164. #{
  165. desc => ?DESC(active_plugins),
  166. example => [<<"Plugin A">>, <<"Plugin B">>]
  167. }
  168. )},
  169. {active_modules,
  170. mk(
  171. array(binary()),
  172. #{
  173. desc => ?DESC(active_modules),
  174. example => [<<"Module A">>, <<"Module B">>]
  175. }
  176. )},
  177. {num_clients,
  178. mk(
  179. integer(),
  180. #{
  181. desc => ?DESC(num_clients),
  182. example => 20220113
  183. }
  184. )},
  185. {messages_received,
  186. mk(
  187. integer(),
  188. #{
  189. desc => ?DESC(messages_received),
  190. example => 2022
  191. }
  192. )},
  193. {messages_sent,
  194. mk(
  195. integer(),
  196. #{
  197. desc => ?DESC(messages_sent),
  198. example => 2022
  199. }
  200. )}
  201. ].
  202. %%--------------------------------------------------------------------
  203. %% HTTP API
  204. %%--------------------------------------------------------------------
  205. status(get, _Params) ->
  206. {200, get_telemetry_status()};
  207. status(put, #{body := Body}) ->
  208. Enable = maps:get(<<"enable">>, Body),
  209. case Enable =:= emqx_modules_conf:is_telemetry_enabled() of
  210. true ->
  211. Reason =
  212. case Enable of
  213. true -> <<"Telemetry status is already enabled">>;
  214. false -> <<"Telemetry status is already disabled">>
  215. end,
  216. {400, #{code => ?BAD_REQUEST, message => Reason}};
  217. false ->
  218. case enable_telemetry(Enable) of
  219. ok ->
  220. {200, get_telemetry_status()};
  221. {error, Reason} ->
  222. {400, #{
  223. code => ?BAD_REQUEST,
  224. message => Reason
  225. }}
  226. end
  227. end.
  228. data(get, _Request) ->
  229. case emqx_modules_conf:is_telemetry_enabled() of
  230. true ->
  231. {200, emqx_utils_json:encode(get_telemetry_data())};
  232. false ->
  233. {404, #{
  234. code => ?NOT_FOUND,
  235. message => <<"Telemetry is not enabled">>
  236. }}
  237. end.
  238. %%--------------------------------------------------------------------
  239. %% Internal functions
  240. %%--------------------------------------------------------------------
  241. enable_telemetry(Enable) ->
  242. emqx_modules_conf:set_telemetry_status(Enable).
  243. get_telemetry_status() ->
  244. #{enable => emqx_modules_conf:is_telemetry_enabled()}.
  245. get_telemetry_data() ->
  246. {ok, TelemetryData} = emqx_telemetry:get_telemetry(),
  247. TelemetryData.