% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2018. 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. %% %% %CopyrightEnd% %% -module(logger_env_var_SUITE). -compile(export_all). -include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/logger.hrl"). -include_lib("kernel/src/logger_internal.hrl"). -define(all_vars,[{kernel,logger_dest}, {kernel,logger_level}, {kernel,logger_log_progress}, {kernel,logger_sasl_compatible}, {kernel,error_logger}]). suite() -> [{timetrap,{seconds,30}}]. init_per_suite(Config) -> Env = [{App,Key,application:get_env(App,Key)} || {App,Key} <- ?all_vars], Removed = cleanup(), [{env,Env},{logger,Removed}|Config]. end_per_suite(Config) -> [application:set_env(App,Key,Val) || {App,Key,Val} <- ?config(env,Config), Val =/= undefined], Hs = ?config(logger,Config), [ok = logger:add_handler(Id,Mod,C) || {Id,Mod,C} <- Hs], ok. init_per_group(_Group, Config) -> Config. end_per_group(_Group, _Config) -> ok. init_per_testcase(_TestCase, Config) -> Config. end_per_testcase(Case, Config) -> try apply(?MODULE,Case,[cleanup,Config]) catch error:undef -> ok end, cleanup(), ok. groups() -> []. all() -> [default, default_sasl_compatible, dest_tty, dest_tty_sasl_compatible, dest_false, dest_false_progress, dest_false_sasl_compatible, dest_silent, dest_silent_sasl_compatible, dest_file_old, dest_file, dest_disk_log, %% disk_log_vars, % or test this in logger_disk_log_SUITE? sasl_compatible_false, sasl_compatible_false_no_progress, sasl_compatible, bad_dest%% , %% bad_level, %% bad_sasl_compatibility, %% bad_progress ]. default(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, undefined, undefined, % dest undefined, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) {logger_std_h,logger_std_h,StdC} = lists:keyfind(logger_std_h,1,Hs), true = is_pid(whereis(logger_std_h)), info = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), {domain,{_,{log,prefix_of,[beam,erlang,otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), true = lists:keymember(stop_progress,1,StdFilters), false = lists:keymember(logger_simple,1,Hs), false = lists:keymember(sasl_h,1,Hs), false = is_pid(whereis(sasl_h)), ok. default_sasl_compatible(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, undefined, undefined, % dest undefined, % level true, % sasl comp (default=false) undefined), % progress (default=false) {logger_std_h,logger_std_h,StdC} = lists:keyfind(logger_std_h,1,Hs), true = is_pid(whereis(logger_std_h)), info = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), {domain,{_,{log,prefix_of,[beam,erlang,otp]}}} = lists:keyfind(domain,1,StdFilters), false = lists:keymember(stop_progress,1,StdFilters), false = lists:keymember(logger_simple,1,Hs), true = lists:keymember(sasl_h,1,Hs), true = is_pid(whereis(sasl_h)), ok. dest_tty(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, tty, % dest undefined, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) {logger_std_h,logger_std_h,StdC} = lists:keyfind(logger_std_h,1,Hs), true = is_pid(whereis(logger_std_h)), info = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), {domain,{_,{log,prefix_of,[beam,erlang,otp,sasl]}}} = lists:keyfind(domain,1,StdFilters), true = lists:keymember(stop_progress,1,StdFilters), false = lists:keymember(logger_simple,1,Hs), false = lists:keymember(sasl_h,1,Hs), false = is_pid(whereis(sasl_h)), ok. dest_tty_sasl_compatible(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, tty, % dest undefined, % level true, % sasl comp (default=false) undefined), % progress (default=false) {logger_std_h,logger_std_h,StdC} = lists:keyfind(logger_std_h,1,Hs), true = is_pid(whereis(logger_std_h)), info = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), {domain,{_,{log,prefix_of,[beam,erlang,otp]}}} = lists:keyfind(domain,1,StdFilters), false = lists:keymember(stop_progress,1,StdFilters), false = lists:keymember(logger_simple,1,Hs), true = lists:keymember(sasl_h,1,Hs), true = is_pid(whereis(sasl_h)), ok. dest_false(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, false, % dest notice, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) false = lists:keymember(logger_std_h,1,Hs), {logger_simple,logger_simple,SimpleC} = lists:keyfind(logger_simple,1,Hs), notice = maps:get(level,SimpleC), SimpleFilters = maps:get(filters,SimpleC), {domain,{_,{log,prefix_of,[beam,erlang,otp,sasl]}}} = lists:keyfind(domain,1,SimpleFilters), true = lists:keymember(stop_progress,1,SimpleFilters), false = lists:keymember(sasl_h,1,Hs), ok. dest_false_progress(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, false, % dest notice, % level undefined, % sasl comp (default=false) true), % progress (default=false) false = lists:keymember(logger_std_h,1,Hs), {logger_simple,logger_simple,SimpleC} = lists:keyfind(logger_simple,1,Hs), notice = maps:get(level,SimpleC), SimpleFilters = maps:get(filters,SimpleC), {domain,{_,{log,prefix_of,[beam,erlang,otp,sasl]}}} = lists:keyfind(domain,1,SimpleFilters), false = lists:keymember(stop_progress,1,SimpleFilters), false = lists:keymember(sasl_h,1,Hs), ok. dest_false_sasl_compatible(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, false, % dest notice, % level true, % sasl comp (default=false) undefined), % progress (default=false) false = lists:keymember(logger_std_h,1,Hs), {logger_simple,logger_simple,SimpleC} = lists:keyfind(logger_simple,1,Hs), notice = maps:get(level,SimpleC), SimpleFilters = maps:get(filters,SimpleC), {domain,{_,{log,prefix_of,[beam,erlang,otp]}}} = lists:keyfind(domain,1,SimpleFilters), false = lists:keymember(stop_progress,1,SimpleFilters), true = lists:keymember(sasl_h,1,Hs), true = is_pid(whereis(sasl_h)), ok. dest_silent(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, silent, % dest undefined, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) false = lists:keymember(logger_std_h,1,Hs), false = lists:keymember(logger_simple,1,Hs), false = lists:keymember(sasl_h,1,Hs), ok. dest_silent_sasl_compatible(Config) -> {ok,{_Log,Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, silent, % dest undefined, % level true, % sasl comp (default=false) undefined), % progress (default=false) false = lists:keymember(logger_std_h,1,Hs), false = lists:keymember(logger_simple,1,Hs), true = lists:keymember(sasl_h,1,Hs), true = is_pid(whereis(sasl_h)), ok. dest_file_old(Config) -> {ok,{Log,_Hs}} = setup(Config,?FUNCTION_NAME, error_logger, file, % dest undefined, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) check_log(Log, file, % dest 0), % progress in std logger ok. dest_file(Config) -> {ok,{Log,_Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, file, % dest undefined, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) check_log(Log, file, % dest 0), % progress in std logger ok. dest_disk_log(Config) -> {ok,{Log,_Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, disk_log, % dest undefined, % level undefined, % sasl comp (default=false) undefined), % progress (default=false) check_log(Log, disk_log, % dest 0), % progress in std logger ok. sasl_compatible_false(Config) -> {ok,{Log,_Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, file, % dest undefined, % level false, % sasl comp true), % progress check_log(Log, file, % dest 4), % progress in std logger ok. sasl_compatible_false_no_progress(Config) -> {ok,{Log,_Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, file, % dest undefined, % level false, % sasl comp false), % progress check_log(Log, file, % dest 0), % progress in std logger ok. sasl_compatible(Config) -> {ok,{Log,_Hs}} = setup(Config,?FUNCTION_NAME, logger_dest, file, % dest undefined, % level true, % sasl comp undefined), % progress check_log(Log, file, % dest 0), % progress in std logger ok. bad_dest(Config) -> {error,{bad_config,{kernel,{logger_dest,baddest}}}} = setup(Config,?FUNCTION_NAME, logger_dest, baddest, undefined, undefined, undefined). bad_level(Config) -> error = setup(Config,?FUNCTION_NAME, logger_dest, tty, badlevel, undefined, undefined). bad_sasl_compatibility(Config) -> error = setup(Config,?FUNCTION_NAME, logger_dest, tty, info, badcomp, undefined). bad_progress(Config) -> error = setup(Config,?FUNCTION_NAME, logger_dest, tty, info, undefined, badprogress). %%%----------------------------------------------------------------- %%% Internal setup(Config,Func,DestVar,Dest,Level,SaslComp,Progress) -> ok = logger:add_handler(logger_simple,logger_simple, #{filter_default=>log, logger_simple=>#{buffer=>true}}), Dir = ?config(priv_dir,Config), File = lists:concat([?MODULE,"_",Func,".log"]), Log = filename:join(Dir,File), case Dest of undefined -> ok; F when F==file; F==disk_log -> application:set_env(kernel,DestVar,{Dest,Log}); _ -> application:set_env(kernel,DestVar,Dest) end, case Level of undefined -> ok; _ -> application:set_env(kernel,logger_level,Level) end, case SaslComp of undefined -> ok; _ -> application:set_env(kernel,logger_sasl_compatible,SaslComp) end, case Progress of undefined -> ok; _ -> application:set_env(kernel,logger_log_progress,Progress) end, case logger:setup_standard_handler() of ok -> application:start(sasl), StdH = case Dest of NoH when NoH==false; NoH==silent -> false; _ -> true end, StdH = is_pid(whereis(?STANDARD_HANDLER)), SaslH = if SaslComp -> true; true -> false end, SaslH = is_pid(whereis(sasl_h)), {ok,{Log,maps:get(handlers,logger:i())}}; Error -> Error end. check_log(Log,Dest,NumProgress) -> ok = logger:alert("dummy1"), ok = logger:debug("dummy1"), %% Check that there are progress reports (supervisor and %% application_controller) and an error report (the call above) in %% the log. There should not be any info reports yet. {ok,Bin1} = sync_and_read(Dest,Log), ct:log("Log content:~n~s",[Bin1]), match(Bin1,<<"PROGRESS REPORT">>,NumProgress), match(Bin1,<<"ALERT REPORT">>,1), match(Bin1,<<"INFO REPORT">>,0), match(Bin1,<<"DEBUG REPORT">>,0), %% Then stop sasl and see that the info report from %% application_controller is there ok = application:stop(sasl), {ok,Bin2} = sync_and_read(Dest,Log), ct:log("Log content:~n~s",[Bin2]), match(Bin2,<<"INFO REPORT">>,1), match(Bin1,<<"DEBUG REPORT">>,0), ok. match(Bin,Pattern,0) -> nomatch = re:run(Bin,Pattern,[{capture,none}]); match(Bin,Pattern,N) -> {match,M} = re:run(Bin,Pattern,[{capture,all},global]), N = length(M). sync_and_read(disk_log,Log) -> logger_disk_log_h:disk_log_sync(?STANDARD_HANDLER), file:read_file(Log ++ ".1"); sync_and_read(file,Log) -> logger_std_h:filesync(?STANDARD_HANDLER), file:read_file(Log). cleanup() -> application:stop(sasl), [application:unset_env(App,Key) || {App,Key} <- ?all_vars], #{handlers:=Hs0} = logger:i(), Hs = lists:keydelete(cth_log_redirect,1,Hs0), [ok = logger:remove_handler(Id) || {Id,_,_} <- Hs], Hs.