| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- %%--------------------------------------------------------------------
- %% Copyright (c) 2020-2024 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_prometheus_api_SUITE).
- -compile(export_all).
- -compile(nowarn_export_all).
- -include_lib("eunit/include/eunit.hrl").
- -include_lib("common_test/include/ct.hrl").
- %%--------------------------------------------------------------------
- %% Setups
- %%--------------------------------------------------------------------
- all() ->
- [
- {group, new_config},
- {group, legacy_config}
- ].
- groups() ->
- [
- {new_config, [sequence], [t_stats_auth_api, t_stats_no_auth_api, t_prometheus_api]},
- {legacy_config, [sequence], [t_stats_no_auth_api, t_legacy_prometheus_api]}
- ].
- init_per_suite(Config) ->
- Apps = emqx_cth_suite:start(
- [
- emqx,
- emqx_conf,
- emqx_management,
- {emqx_prometheus, #{start => false}},
- {emqx_dashboard, "dashboard.listeners.http { enable = true, bind = 18083 }"},
- {emqx_license, "license.key = default"}
- ],
- #{work_dir => emqx_cth_suite:work_dir(Config)}
- ),
- {ok, _} = emqx_common_test_http:create_default_app(),
- [{suite_apps, Apps} | Config].
- end_per_suite(Config) ->
- ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
- init_per_group(new_config, Config) ->
- Apps = emqx_cth_suite:start_app(
- emqx_prometheus,
- #{config => emqx_prometheus_SUITE:config(default)}
- ),
- [{group_apps, Apps} | Config];
- init_per_group(legacy_config, Config) ->
- Apps = emqx_cth_suite:start_app(
- emqx_prometheus,
- #{config => emqx_prometheus_SUITE:config(legacy)}
- ),
- [{group_apps, Apps} | Config].
- end_per_group(_Group, Config) ->
- ok = emqx_cth_suite:stop_apps(?config(group_apps, Config)).
- %%--------------------------------------------------------------------
- %% Cases
- %%--------------------------------------------------------------------
- %% we return recommend config for prometheus even if prometheus is legacy.
- t_legacy_prometheus_api(_) ->
- Path = emqx_mgmt_api_test_util:api_path(["prometheus"]),
- Auth = emqx_mgmt_api_test_util:auth_header_(),
- {ok, Response} = emqx_mgmt_api_test_util:request_api(get, Path, "", Auth),
- OldConf = emqx:get_raw_config([prometheus]),
- Conf = emqx_utils_json:decode(Response, [return_maps]),
- %% Always return new config.
- ?assertMatch(
- #{
- <<"collectors">> :=
- #{
- <<"mnesia">> := <<"disabled">>,
- <<"vm_dist">> := <<"disabled">>,
- <<"vm_memory">> := <<"disabled">>,
- <<"vm_msacc">> := <<"disabled">>,
- <<"vm_statistics">> := <<"disabled">>,
- <<"vm_system_info">> := <<"disabled">>
- },
- <<"enable_basic_auth">> := false,
- <<"push_gateway">> :=
- #{
- <<"enable">> := true,
- <<"headers">> := #{<<"Authorization">> := <<"some-authz-tokens">>},
- <<"interval">> := <<"1s">>,
- <<"job_name">> := <<"${name}~${host}">>,
- <<"url">> := <<"http://127.0.0.1:9091">>
- }
- },
- Conf
- ),
- #{<<"push_gateway">> := #{<<"enable">> := Enable}} = Conf,
- ?assertEqual(Enable, undefined =/= erlang:whereis(emqx_prometheus)),
- NewConf = OldConf#{
- <<"interval">> => <<"2s">>,
- <<"vm_statistics_collector">> => <<"enabled">>,
- <<"headers">> => #{
- <<"test-str1">> => <<"test-value">>,
- <<"test-str2">> => <<"42">>
- }
- },
- {ok, Response2} = emqx_mgmt_api_test_util:request_api(put, Path, "", Auth, NewConf),
- Conf2 = emqx_utils_json:decode(Response2, [return_maps]),
- ?assertEqual(NewConf, Conf2),
- EnvCollectors = env_collectors(),
- PromCollectors = all_collectors(),
- ?assertEqual(lists:sort(EnvCollectors), lists:sort(PromCollectors)),
- ?assert(lists:member(prometheus_vm_statistics_collector, EnvCollectors), EnvCollectors),
- lists:foreach(
- fun({C, Enabled}) ->
- ?assertEqual(Enabled, lists:member(C, EnvCollectors), EnvCollectors)
- end,
- [
- {prometheus_vm_dist_collector, false},
- {prometheus_vm_system_info_collector, false},
- {prometheus_vm_memory_collector, false},
- {prometheus_mnesia_collector, false},
- {prometheus_vm_msacc_collector, false},
- {prometheus_vm_statistics_collector, true}
- ]
- ),
- ?assertMatch(
- #{
- <<"headers">> := #{
- <<"test-str1">> := <<"test-value">>,
- <<"test-str2">> := <<"42">>
- }
- },
- emqx_config:get_raw([prometheus])
- ),
- ?assertMatch(
- #{
- headers := [
- {"test-str2", "42"},
- {"test-str1", "test-value"}
- ]
- },
- emqx_config:get([prometheus])
- ),
- NewConf1 = OldConf#{<<"enable">> => (not Enable)},
- {ok, _Response3} = emqx_mgmt_api_test_util:request_api(put, Path, "", Auth, NewConf1),
- ?assertEqual((not Enable), undefined =/= erlang:whereis(emqx_prometheus)),
- ConfWithoutScheme = OldConf#{<<"push_gateway_server">> => "127.0.0.1:8081"},
- ?assertMatch(
- {error, {"HTTP/1.1", 400, _}},
- emqx_mgmt_api_test_util:request_api(put, Path, "", Auth, ConfWithoutScheme)
- ),
- ok.
- t_prometheus_api(_) ->
- Path = emqx_mgmt_api_test_util:api_path(["prometheus"]),
- Auth = emqx_mgmt_api_test_util:auth_header_(),
- {ok, Response} = emqx_mgmt_api_test_util:request_api(get, Path, "", Auth),
- Conf = emqx_utils_json:decode(Response, [return_maps]),
- ?assertMatch(
- #{
- <<"push_gateway">> := #{},
- <<"collectors">> := _,
- <<"enable_basic_auth">> := _
- },
- Conf
- ),
- #{
- <<"push_gateway">> :=
- #{<<"url">> := Url, <<"enable">> := Enable} = PushGateway,
- <<"collectors">> := Collector
- } = Conf,
- Pid = erlang:whereis(emqx_prometheus),
- ?assertEqual(Enable, undefined =/= Pid, {Url, Pid}),
- NewConf = Conf#{
- <<"push_gateway">> => PushGateway#{
- <<"interval">> => <<"2s">>,
- <<"headers">> => #{
- <<"test-str1">> => <<"test-value">>,
- <<"test-str2">> => <<"42">>
- }
- },
- <<"collectors">> => Collector#{
- <<"vm_dist">> => <<"enabled">>,
- <<"vm_system_info">> => <<"enabled">>,
- <<"vm_memory">> => <<"enabled">>,
- <<"vm_msacc">> => <<"enabled">>,
- <<"mnesia">> => <<"enabled">>,
- <<"vm_statistics">> => <<"enabled">>
- }
- },
- {ok, Response2} = emqx_mgmt_api_test_util:request_api(put, Path, "", Auth, NewConf),
- Conf2 = emqx_utils_json:decode(Response2, [return_maps]),
- ?assertMatch(NewConf, Conf2),
- EnvCollectors = env_collectors(),
- PromCollectors = all_collectors(),
- ?assertEqual(lists:sort(EnvCollectors), lists:sort(PromCollectors)),
- ?assert(lists:member(prometheus_vm_statistics_collector, EnvCollectors), EnvCollectors),
- lists:foreach(
- fun({C, Enabled}) ->
- ?assertEqual(Enabled, lists:member(C, EnvCollectors), EnvCollectors)
- end,
- [
- {prometheus_vm_dist_collector, true},
- {prometheus_vm_system_info_collector, true},
- {prometheus_vm_memory_collector, true},
- {prometheus_mnesia_collector, true},
- {prometheus_vm_msacc_collector, true},
- {prometheus_vm_statistics_collector, true}
- ]
- ),
- ?assertMatch(
- #{
- <<"push_gateway">> := #{
- <<"headers">> := #{
- <<"test-str1">> := <<"test-value">>,
- <<"test-str2">> := <<"42">>
- }
- }
- },
- emqx_config:get_raw([prometheus])
- ),
- ?assertMatch(
- #{
- push_gateway := #{
- headers := [
- {"test-str2", "42"},
- {"test-str1", "test-value"}
- ]
- }
- },
- emqx_config:get([prometheus])
- ),
- NewConf1 = Conf#{<<"push_gateway">> => PushGateway#{<<"enable">> => false}},
- {ok, _Response3} = emqx_mgmt_api_test_util:request_api(put, Path, "", Auth, NewConf1),
- ?assertEqual(undefined, erlang:whereis(emqx_prometheus)),
- ConfWithoutScheme = Conf#{
- <<"push_gateway">> => PushGateway#{<<"url">> => <<"127.0.0.1:8081">>}
- },
- ?assertMatch(
- {error, {"HTTP/1.1", 400, _}},
- emqx_mgmt_api_test_util:request_api(put, Path, "", Auth, ConfWithoutScheme)
- ),
- ok.
- t_stats_no_auth_api(_) ->
- %% undefined is legacy prometheus
- case emqx:get_config([prometheus, enable_basic_auth], undefined) of
- true ->
- {ok, _} = emqx:update_config([prometheus, enable_basic_auth], false);
- _ ->
- ok
- end,
- emqx_dashboard_listener:regenerate_minirest_dispatch(),
- Headers = accept_josn_header(),
- request_stats(Headers, []).
- t_stats_auth_api(_) ->
- {ok, _} = emqx:update_config([prometheus, enable_basic_auth], true),
- emqx_dashboard_listener:regenerate_minirest_dispatch(),
- Auth = emqx_mgmt_api_test_util:auth_header_(),
- Headers = [Auth | accept_josn_header()],
- request_stats(Headers, Auth),
- ok.
- accept_josn_header() ->
- [{"accept", "application/json"}].
- request_stats(Headers, Auth) ->
- Path = emqx_mgmt_api_test_util:api_path(["prometheus", "stats"]),
- {ok, Response} = emqx_mgmt_api_test_util:request_api(get, Path, "", Headers),
- Data = emqx_utils_json:decode(Response, [return_maps]),
- ?assertMatch(#{<<"client">> := _, <<"delivery">> := _}, Data),
- {ok, _} = emqx_mgmt_api_test_util:request_api(get, Path, "", Auth),
- ok = meck:expect(mria_rlog, backend, fun() -> rlog end),
- {ok, _} = emqx_mgmt_api_test_util:request_api(get, Path, "", Auth).
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %%% Internal Functions
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- env_collectors() ->
- do_env_collectors(application:get_env(prometheus, collectors, []), []).
- do_env_collectors([], Acc) ->
- lists:reverse(Acc);
- do_env_collectors([{_Registry, Collector} | Rest], Acc) when is_atom(Collector) ->
- do_env_collectors(Rest, [Collector | Acc]);
- do_env_collectors([Collector | Rest], Acc) when is_atom(Collector) ->
- do_env_collectors(Rest, [Collector | Acc]).
- all_collectors() ->
- emqx_prometheus_config:all_collectors().
|