From 4e429c8ec783947b84ef7e8e337e3af0cd5603ed Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 11 Jun 2018 14:56:34 +0200 Subject: [logger] Skip some overload protection tests when using dirty schedulers --- lib/kernel/test/logger_std_h_SUITE.erl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 36b123b07d..27a8db1db6 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -79,6 +79,18 @@ init_per_testcase(TestHooksCase, Config) when ct:print("********** ~w **********", [TestHooksCase]), Config end; +init_per_testcase(OPCase, Config) when + OPCase == qlen_kill_new; + OPCase == restart_after -> + case re:run(erlang:system_info(system_version), + "dirty-schedulers-TEST", + [{capture,none}]) of + match -> + {skip,"Overload protection test skipped on dirty-schedulers-TEST"}; + nomatch -> + ct:print("********** ~w **********", [OPCase]), + Config + end; init_per_testcase(TestCase, Config) -> ct:print("********** ~w **********", [TestCase]), Config. -- cgit v1.2.3 From 42f0d79cf02b4d74508bd4fdeac95574ae811949 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 11 Jun 2018 14:58:03 +0200 Subject: [logger] Skip test involving file access rights on windows --- lib/kernel/test/logger_std_h_SUITE.erl | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 27a8db1db6..27b1cfc5ea 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -226,11 +226,17 @@ errors(Config) -> logger:add_handler(?MODULE,logger_std_h, #{config => #{type => faulty_type}}), - NoDir = lists:concat(["/",?MODULE,"_dir"]), - {error, - {handler_not_added,{{open_failed,NoDir,eacces},_}}} = - logger:add_handler(myh2,logger_std_h, - #{config=>#{type=>{file,NoDir}}}), + case os:type() of + {win32,_} -> + %% No use in testing file access on windows + ok; + _ -> + NoDir = lists:concat(["/",?MODULE,"_dir"]), + {error, + {handler_not_added,{{open_failed,NoDir,eacces},_}}} = + logger:add_handler(myh2,logger_std_h, + #{config=>#{type=>{file,NoDir}}}) + end, {error, {handler_not_added,{{open_failed,Log,_},_}}} = -- cgit v1.2.3 From 6154d847b67f726f0a459d24bc8128578b1f79f9 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 11 Jun 2018 15:52:47 +0200 Subject: [logger] Sort keys when testing formatter template --- lib/kernel/test/logger_formatter_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kernel/test/logger_formatter_SUITE.erl b/lib/kernel/test/logger_formatter_SUITE.erl index 864a40b618..8fe8d5199b 100644 --- a/lib/kernel/test/logger_formatter_SUITE.erl +++ b/lib/kernel/test/logger_formatter_SUITE.erl @@ -208,7 +208,7 @@ template(_Config) -> time=>Time, tuple=>{1,atom,"list"}, nested=>#{subkey=>subvalue}}, - Template6 = lists:join(";",maps:keys(maps:remove(nested,Meta6)) ++ + Template6 = lists:join(";",lists:sort(maps:keys(maps:remove(nested,Meta6))) ++ [[nested,subkey]]), String6 = format(info,{"~p",[term]},Meta6,#{template=>Template6, single_line=>true}), -- cgit v1.2.3 From 158bbc210378c53281306d295208ec562b3718af Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 11 Jun 2018 15:59:37 +0200 Subject: [logger] Remove some compiler warnings in test suites --- lib/kernel/test/logger_env_var_SUITE.erl | 3 ++- lib/kernel/test/logger_legacy_SUITE.erl | 12 ++++++---- lib/kernel/test/logger_simple_h_SUITE.erl | 38 +++++++++++++++---------------- lib/kernel/test/logger_std_h_SUITE.erl | 8 +++---- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/lib/kernel/test/logger_env_var_SUITE.erl b/lib/kernel/test/logger_env_var_SUITE.erl index 6e182d4bca..3a8560bbf5 100644 --- a/lib/kernel/test/logger_env_var_SUITE.erl +++ b/lib/kernel/test/logger_env_var_SUITE.erl @@ -214,6 +214,7 @@ logger_file(Config) -> file,% dest 0),% progress in std logger + notice = maps:get(level,P), #{module:=logger_std_h} = StdC = find(?STANDARD_HANDLER,Hs), all = maps:get(level,StdC), StdFilters = maps:get(filters,StdC), @@ -525,7 +526,7 @@ logger_many_handlers_default_last_broken_filter(Config) -> {logger_level,info}], LogErr, LogInfo, 7). logger_many_handlers(Config, Env, LogErr, LogInfo, NumProgress) -> - {ok,#{handlers:=Hs},Node} = setup(Config,Env), + {ok,_,Node} = setup(Config,Env), check_single_log(Node,LogErr, file,% dest 0,% progress in std logger diff --git a/lib/kernel/test/logger_legacy_SUITE.erl b/lib/kernel/test/logger_legacy_SUITE.erl index de73b6152a..a0d133b7e9 100644 --- a/lib/kernel/test/logger_legacy_SUITE.erl +++ b/lib/kernel/test/logger_legacy_SUITE.erl @@ -20,6 +20,8 @@ -module(logger_legacy_SUITE). -compile(export_all). +-compile({nowarn_deprecated_function,[{gen_fsm,start,3}, + {gen_fsm,send_all_state_event,2}]}). -include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/logger.hrl"). @@ -122,7 +124,7 @@ all() -> gen_server(_Config) -> {ok,Pid} = gen_server:start(?MODULE,gen_server,[]), - Msg = fun() -> a=b end, + Msg = fun() -> erlang:error({badmatch,b}) end, Pid ! Msg, ?check({warning_msg,"** Undefined handle_info in ~p"++_,[?MODULE,Msg]}), ok = gen_server:cast(Pid,Msg), @@ -132,7 +134,7 @@ gen_server(_Config) -> gen_event(_Config) -> {ok,Pid} = gen_event:start(), ok = gen_event:add_handler(Pid,?MODULE,gen_event), - Msg = fun() -> a=b end, + Msg = fun() -> erlang:error({badmatch,b}) end, Pid ! Msg, ?check({warning_msg,"** Undefined handle_info in ~tp"++_,[?MODULE,Msg]}), gen_event:notify(Pid,Msg), @@ -141,7 +143,7 @@ gen_event(_Config) -> gen_fsm(_Config) -> {ok,Pid} = gen_fsm:start(?MODULE,gen_fsm,[]), - Msg = fun() -> a=b end, + Msg = fun() -> erlang:error({badmatch,b}) end, Pid ! Msg, ?check({warning_msg,"** Undefined handle_info in ~p"++_,[?MODULE,Msg]}), gen_fsm:send_all_state_event(Pid,Msg), @@ -150,7 +152,7 @@ gen_fsm(_Config) -> gen_statem(_Config) -> {ok,Pid} = gen_statem:start(?MODULE,gen_statem,[]), - Msg = fun() -> a=b end, + Msg = fun() -> erlang:error({badmatch,b}) end, Pid ! Msg, ?check({error,"** State machine ~tp terminating"++_, [Pid,{info,Msg},{mystate,gen_statem},error,{badmatch,b}|_]}). @@ -179,7 +181,7 @@ sasl_reports(Config) -> ok = gen_server:cast(ChPid, fun() -> spawn_link(fun() -> receive x->ok end end) end), - Msg = fun() -> a=b end, + Msg = fun() -> erlang:error({badmatch,b}) end, ok = gen_server:cast(ChPid,Msg), ?check_no_flush({error,"** Generic server ~tp terminating"++_, [ChPid,{'$gen_cast',Msg},gen_server,{{badmatch,b},_}]}), diff --git a/lib/kernel/test/logger_simple_h_SUITE.erl b/lib/kernel/test/logger_simple_h_SUITE.erl index e4e48b538a..79e5c057ad 100644 --- a/lib/kernel/test/logger_simple_h_SUITE.erl +++ b/lib/kernel/test/logger_simple_h_SUITE.erl @@ -107,15 +107,15 @@ start_stop(cleanup,_Config) -> replace_default(Config) -> {ok, _, Node} = logger_test_lib:setup(Config, [{logger, [{handler, default, undefined}]}]), - log(Node, emergency, [M1=?str]), - log(Node, alert, [M2=?str,[]]), - log(Node, error, [M3=?map_rep]), - log(Node, info, [M4=?keyval_rep]), - log(Node, info, [M41=?keyval_rep++[not_key_val]]), - rpc:call(Node, error_logger, error_report, [some_type,M5=?map_rep]), - rpc:call(Node, error_logger, warning_report, ["some_type",M6=?map_rep]), - log(Node, critical, [M7=?str,[A7=?keyval_rep]]), - log(Node, notice, [M8=["fake",string,"line:",?LINE]]), + log(Node, emergency, [?str]), + log(Node, alert, [?str,[]]), + log(Node, error, [?map_rep]), + log(Node, info, [?keyval_rep]), + log(Node, info, [?keyval_rep++[not_key_val]]), + rpc:call(Node, error_logger, error_report, [some_type,?map_rep]), + rpc:call(Node, error_logger, warning_report, ["some_type",?map_rep]), + log(Node, critical, [?str,[?keyval_rep]]), + log(Node, notice, [["fake",string,"line:",?LINE]]), Env = rpc:call(Node, application, get_env, [kernel, logger, []]), ok = rpc:call(Node, logger, add_handlers, [Env]), @@ -127,11 +127,11 @@ replace_file(Config) -> {ok, _, Node} = logger_test_lib:setup(Config, [{logger, [{handler, default, undefined}]}]), log(Node, emergency, [M1=?str]), log(Node, alert, [M2=?str,[]]), - log(Node, error, [M3=?map_rep]), - log(Node, warning, [M4=?keyval_rep]), - log(Node, warning, [M41=?keyval_rep++[not_key_val]]), - log(Node, critical, [M7=?str,[A7=?keyval_rep]]), - log(Node, notice, [M8=["fake",string,"line:",?LINE]]), + log(Node, error, [?map_rep]), + log(Node, warning, [?keyval_rep]), + log(Node, warning, [?keyval_rep++[not_key_val]]), + log(Node, critical, [?str,[?keyval_rep]]), + log(Node, notice, [["fake",string,"line:",?LINE]]), File = filename:join(proplists:get_value(priv_dir,Config), atom_to_list(?FUNCTION_NAME)++".log"), @@ -171,11 +171,11 @@ replace_disk_log(Config) -> {ok, _, Node} = logger_test_lib:setup(Config, [{logger, [{handler, default, undefined}]}]), log(Node, emergency, [M1=?str]), log(Node, alert, [M2=?str,[]]), - log(Node, error, [M3=?map_rep]), - log(Node, warning, [M4=?keyval_rep]), - log(Node, warning, [M41=?keyval_rep++[not_key_val]]), - log(Node, critical, [M7=?str,[A7=?keyval_rep]]), - log(Node, notice, [M8=["fake",string,"line:",?LINE]]), + log(Node, error, [?map_rep]), + log(Node, warning, [?keyval_rep]), + log(Node, warning, [?keyval_rep++[not_key_val]]), + log(Node, critical, [?str,[?keyval_rep]]), + log(Node, notice, [["fake",string,"line:",?LINE]]), File = filename:join(proplists:get_value(priv_dir,Config), atom_to_list(?FUNCTION_NAME)++".log"), diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 27b1cfc5ea..0bdd7fa00e 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -695,10 +695,10 @@ start_std_h_on_new_node(Config, Log) -> Node. %% functions for test hook macros to be called by rpc -set_internal_log(Mod, Func) -> - ?set_internal_log({Mod,Func}). -set_result(Op, Result) -> - ?set_result(Op, Result). +set_internal_log(_Mod, _Func) -> + ?set_internal_log({_Mod,_Func}). +set_result(_Op, _Result) -> + ?set_result(_Op, _Result). set_defaults() -> ?set_defaults(). -- cgit v1.2.3 From 686a45b34520c84d9ebfab427a036fa2021371b9 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 11 Jun 2018 18:29:14 +0200 Subject: [logger] Stress overload_kill tests a bit more --- lib/kernel/test/logger_std_h_SUITE.erl | 57 +++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 0bdd7fa00e..5253051b02 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -968,7 +968,7 @@ kill_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). qlen_kill_new(Config) -> - {_Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), + {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), Pid0 = whereis(h_proc_name()), {_,Mem0} = process_info(Pid0, memory), RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, @@ -980,7 +980,7 @@ qlen_kill_new(Config) -> ok = logger:set_handler_config(?MODULE, NewHConfig), MRef = erlang:monitor(process, Pid0), NumOfReqs = 100, - Procs = 2, + Procs = 4, send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), %% send_burst({n,NumOfReqs}, seq, {chars,79}, notice), receive @@ -991,8 +991,8 @@ qlen_kill_new(Config) -> killed -> ct:pal("Slow shutdown, handler process was killed!", []) end, - timer:sleep(RestartAfter + 2000), - true = is_pid(whereis(h_proc_name())), + file_delete(Log), + {ok,_} = wait_for_process_up(h_proc_name(), RestartAfter * 3), ok after 5000 -> @@ -1019,7 +1019,7 @@ qlen_kill_std(_Config) -> {skip,"Not done yet"}. mem_kill_new(Config) -> - {_Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), + {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), Pid0 = whereis(h_proc_name()), {_,Mem0} = process_info(Pid0, memory), RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER, @@ -1031,7 +1031,7 @@ mem_kill_new(Config) -> ok = logger:set_handler_config(?MODULE, NewHConfig), MRef = erlang:monitor(process, Pid0), NumOfReqs = 100, - Procs = 2, + Procs = 4, send_burst({n,NumOfReqs}, {spawn,Procs,0}, {chars,79}, notice), %% send_burst({n,NumOfReqs}, seq, {chars,79}, notice), receive @@ -1042,8 +1042,8 @@ mem_kill_new(Config) -> killed -> ct:pal("Slow shutdown, handler process was killed!", []) end, - timer:sleep(RestartAfter * 3), - true = is_pid(whereis(h_proc_name())), + file_delete(Log), + {ok,_} = wait_for_process_up(h_proc_name(), RestartAfter * 3), ok after 5000 -> @@ -1059,6 +1059,8 @@ mem_kill_new(cleanup, _Config) -> mem_kill_std(_Config) -> {skip,"Not done yet"}. +restart_after() -> + [{timetrap,{minutes,2}}]. restart_after(Config) -> {Log,HConfig,StdHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config), NewHConfig1 = @@ -1068,14 +1070,16 @@ restart_after(Config) -> ok = logger:set_handler_config(?MODULE, NewHConfig1), MRef1 = erlang:monitor(process, whereis(h_proc_name())), %% kill handler - send_burst({n,100}, {spawn,2,0}, {chars,79}, notice), + send_burst({n,100}, {spawn,4,0}, {chars,79}, notice), receive - {'DOWN', MRef1, _, _, _Info1} -> - timer:sleep(?OVERLOAD_KILL_RESTART_AFTER + 1000), - undefined = whereis(h_proc_name()), + {'DOWN', MRef1, _, _, _Reason1} -> + file_delete(Log), + error = wait_for_process_up(h_proc_name(),?OVERLOAD_KILL_RESTART_AFTER * 3), ok after 5000 -> + Info1 = logger_std_h:info(?MODULE), + ct:pal("Handler state = ~p", [Info1]), ct:fail("Handler not dead! It should not have survived this!") end, @@ -1089,16 +1093,17 @@ restart_after(Config) -> Pid0 = whereis(h_proc_name()), MRef2 = erlang:monitor(process, Pid0), %% kill handler - send_burst({n,100}, {spawn,2,0}, {chars,79}, notice), + send_burst({n,100}, {spawn,4,0}, {chars,79}, notice), receive - {'DOWN', MRef2, _, _, _Info2} -> - timer:sleep(RestartAfter + 2000), - Pid1 = whereis(h_proc_name()), - true = is_pid(Pid1), + {'DOWN', MRef2, _, _, _Reason2} -> + file_delete(Log), + {ok,Pid1} = wait_for_process_up(h_proc_name(),RestartAfter * 3), false = (Pid1 == Pid0), ok after 5000 -> + Info2 = logger_std_h:info(?MODULE), + ct:pal("Handler state = ~p", [Info2]), ct:fail("Handler not dead! It should not have survived this!") end, ok. @@ -1248,7 +1253,8 @@ send_n_burst(N, seq, Text, Class) -> send_n_burst(N-1, seq, Text, Class); send_n_burst(N, {spawn,Ps,TO}, Text, Class) -> ct:pal("~w processes each sending ~w messages", [Ps,N]), - PerProc = fun() -> + PerProc = fun() -> + process_flag(priority,high), send_n_burst(N, seq, Text, Class) end, MRefs = [begin if TO == 0 -> ok; true -> timer:sleep(TO) end, @@ -1559,3 +1565,18 @@ h_proc_name(Name) -> file_delete(Log) -> file:delete(Log). + +wait_for_process_up(Name,T) -> + N = (T div 500) + 1, + wait_for_process_up1(Name,N). + +wait_for_process_up1(Name,0) -> + error; +wait_for_process_up1(Name,N) -> + timer:sleep(500), + case whereis(Name) of + Pid when is_pid(Pid) -> + {ok,Pid}; + undefined -> + wait_for_process_up1(Name,N-1) + end. -- cgit v1.2.3 From e15b8683b041330ce36c86729f72d7c0922a1844 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 11 Jun 2018 19:53:00 +0200 Subject: [logger] Set up priority for processes generatig test bursts --- lib/kernel/test/logger_disk_log_h_SUITE.erl | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index 5f7b505ecb..5c23960c90 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -1,3 +1,22 @@ +%% +%% %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_disk_log_h_SUITE). -compile(export_all). @@ -1256,7 +1275,8 @@ send_n_burst(N, seq, Text, Class) -> send_n_burst(N-1, seq, Text, Class); send_n_burst(N, {spawn,Ps,TO}, Text, Class) -> ct:pal("~w processes each sending ~w messages", [Ps,N]), - PerProc = fun() -> + PerProc = fun() -> + process_flag(priority,high), send_n_burst(N, seq, Text, Class) end, MRefs = [begin if TO == 0 -> ok; true -> timer:sleep(TO) end, -- cgit v1.2.3 From ad55c4b112f5231e66f4e61dbdb5bede505fb2e2 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Tue, 12 Jun 2018 11:10:28 +0200 Subject: [logger] Don't delete log file of failing test cases --- lib/kernel/test/logger_disk_log_h_SUITE.erl | 21 +++++++++++++-------- lib/kernel/test/logger_std_h_SUITE.erl | 18 +++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index 5c23960c90..7225d4b57c 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -880,8 +880,8 @@ op_switch_to_sync(Config) -> ok = logger:set_handler_config(?MODULE, NewHConfig), send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Lines = count_lines(Log), - ok = file_delete(Log), NumOfReqs = Lines, + ok = file_delete(Log), ok. op_switch_to_sync(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -911,11 +911,11 @@ op_switch_to_drop(Config) -> _ <- lists:seq(1, Bursts)], Logged = count_lines(Log), ok = stop_handler(?MODULE), - _ = file_delete(Log), ct:pal("Number of messages dropped = ~w (~w)", [Procs*NumOfReqs*Bursts-Logged,Procs*NumOfReqs*Bursts]), true = (Logged < (Procs*NumOfReqs*Bursts)), true = (Logged > 0), + _ = file_delete(Log), ok end, %% As it's tricky to get the timing right in only one go, we perform the @@ -963,11 +963,11 @@ op_switch_to_flush(Config) -> _ <- lists:seq(1,Bursts)], Logged = count_lines(Log), ok= stop_handler(?MODULE), - _ = file_delete(Log), ct:pal("Number of messages flushed/dropped = ~w (~w)", [NumOfReqs*Procs*Bursts-Logged,NumOfReqs*Procs*Bursts]), true = (Logged < (NumOfReqs*Procs*Bursts)), true = (Logged > 0), + _ = file_delete(Log), ok end, %% As it's tricky to get the timing right in only one go, we perform the @@ -995,8 +995,9 @@ limit_burst_disabled(Config) -> send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), + NumOfReqs = Logged, ok = file_delete(Log), - NumOfReqs = Logged. + ok. limit_burst_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1014,8 +1015,9 @@ limit_burst_enabled_one(Config) -> send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), + ReqLimit = Logged, ok = file_delete(Log), - ReqLimit = Logged. + ok. limit_burst_enabled_one(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1036,9 +1038,10 @@ limit_burst_enabled_period(Config) -> Logged = count_lines(Log), ct:pal("Number of messages sent = ~w~nNumber of messages logged = ~w", [Sent,Logged]), - ok = file_delete(Log), true = (Logged > (ReqLimit*Windows)) andalso - (Logged < (ReqLimit*(Windows+2))). + (Logged < (ReqLimit*(Windows+2))), + ok = file_delete(Log), + ok. limit_burst_enabled_period(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1239,6 +1242,8 @@ start_handler(Name, FuncName, Config) -> Dir = ?config(priv_dir,Config), File = filename:join(Dir, FuncName), ct:pal("Logging to ~tp", [File]), + FullFile = lists:concat([File,".1"]), + _ = file_delete(FullFile), ok = logger:add_handler(Name, logger_disk_log_h, #{config=>#{file => File, @@ -1248,7 +1253,7 @@ start_handler(Name, FuncName, Config) -> filters=>?DEFAULT_HANDLER_FILTERS([Name]), formatter=>{?MODULE,op}}), {ok,HConfig = #{config := DLHConfig}} = logger:get_handler_config(Name), - {lists:concat([File,".1"]),HConfig,DLHConfig}. + {FullFile,HConfig,DLHConfig}. stop_handler(Name) -> ct:pal("Stopping handler ~p!", [Name]), diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 5253051b02..e0bc79012c 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -725,7 +725,6 @@ op_switch_to_sync_file(Config) -> %% TRecvPid = start_op_trace(), send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Lines = count_lines(Log), - ok = file_delete(Log), %% true = analyse_trace(TRecvPid, %% fun(Events) -> find_mode(async,Events) end), %% true = analyse_trace(TRecvPid, @@ -738,6 +737,7 @@ op_switch_to_sync_file(Config) -> %% fun(Events) -> find_mode(flush,Events) end), %% stop_op_trace(TRecvPid), NumOfReqs = Lines, + ok = file_delete(Log), ok. op_switch_to_sync_file(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -782,11 +782,11 @@ op_switch_to_drop_file(Config) -> _ <- lists:seq(1, Bursts)], Logged = count_lines(Log), ok = stop_handler(?MODULE), - _ = file_delete(Log), ct:pal("Number of messages dropped = ~w (~w)", [Procs*NumOfReqs*Bursts-Logged,Procs*NumOfReqs*Bursts]), true = (Logged < (Procs*NumOfReqs*Bursts)), true = (Logged > 0), + _ = file_delete(Log), ok end, %% As it's tricky to get the timing right in only one go, we perform the @@ -850,11 +850,11 @@ op_switch_to_flush_file(Config) -> _ <- lists:seq(1,Bursts)], Logged = count_lines(Log), ok = stop_handler(?MODULE), - _ = file_delete(Log), ct:pal("Number of messages flushed/dropped = ~w (~w)", [NumOfReqs*Procs*Bursts-Logged,NumOfReqs*Procs*Bursts]), true = (Logged < (NumOfReqs*Procs*Bursts)), true = (Logged > 0), + _ = file_delete(Log), ok end, %% As it's tricky to get the timing right in only one go, we perform the @@ -903,8 +903,9 @@ limit_burst_disabled(Config) -> send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), + NumOfReqs = Logged, ok = file_delete(Log), - NumOfReqs = Logged. + ok. limit_burst_disabled(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -922,8 +923,9 @@ limit_burst_enabled_one(Config) -> send_burst({n,NumOfReqs}, seq, {chars,79}, notice), Logged = count_lines(Log), ct:pal("Number of messages logged = ~w", [Logged]), + ReqLimit = Logged, ok = file_delete(Log), - ReqLimit = Logged. + ok. limit_burst_enabled_one(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -944,9 +946,10 @@ limit_burst_enabled_period(Config) -> Logged = count_lines(Log), ct:pal("Number of messages sent = ~w~nNumber of messages logged = ~w", [Sent,Logged]), - ok = file_delete(Log), true = (Logged > (ReqLimit*Windows)) andalso - (Logged < (ReqLimit*(Windows+2))). + (Logged < (ReqLimit*(Windows+2))), + ok = file_delete(Log), + ok. limit_burst_enabled_period(cleanup, _Config) -> ok = stop_handler(?MODULE). @@ -1183,6 +1186,7 @@ start_handler(Name, FuncName, Config) -> Log = filename:join(Dir, lists:concat([FuncName,".log"])), ct:pal("Logging to ~tp", [Log]), Type = {file,Log}, + _ = file_delete(Log), ok = logger:add_handler(Name, logger_std_h, #{config => #{type => Type}, -- cgit v1.2.3 From a575d83ba9c4336523baa741b22d1de8d6c1ff87 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Tue, 12 Jun 2018 14:03:12 +0200 Subject: [logger] Reset logger config after tests --- lib/kernel/test/logger_SUITE.erl | 2 +- lib/kernel/test/logger_legacy_SUITE.erl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/kernel/test/logger_SUITE.erl b/lib/kernel/test/logger_SUITE.erl index f837c31e64..b367b4dd54 100644 --- a/lib/kernel/test/logger_SUITE.erl +++ b/lib/kernel/test/logger_SUITE.erl @@ -329,7 +329,7 @@ log_no_levels(_Config) -> ok. log_no_levels(cleanup,_Config) -> logger:remove_handler(h1), - logger:set_primary_config(level,info), + logger:set_primary_config(level,notice), logger:unset_module_level(?MODULE), ok. diff --git a/lib/kernel/test/logger_legacy_SUITE.erl b/lib/kernel/test/logger_legacy_SUITE.erl index a0d133b7e9..c3cab07d81 100644 --- a/lib/kernel/test/logger_legacy_SUITE.erl +++ b/lib/kernel/test/logger_legacy_SUITE.erl @@ -91,6 +91,7 @@ init_per_group(_Group, Config) -> end_per_group(sasl, Config) -> Apps = ?config(stop_apps,Config), [application:stop(App) || App <- Apps], + ok = logger:set_primary_config(level,notice), ok; end_per_group(_Group, _Config) -> ok. -- cgit v1.2.3 From 950a7175e2d5f2f2c5c50c81ef4a6a0ecbb38530 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 13 Jun 2018 12:18:37 +0200 Subject: [logger] Change name of function sync/1 to filesync/1 --- lib/kernel/src/logger_disk_log_h.erl | 12 +++++----- lib/kernel/src/logger_h_common.erl | 2 +- lib/kernel/src/logger_std_h.erl | 12 +++++----- lib/kernel/test/logger_disk_log_h_SUITE.erl | 34 ++++++++++++++--------------- lib/kernel/test/logger_std_h_SUITE.erl | 22 +++++++++---------- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/lib/kernel/src/logger_disk_log_h.erl b/lib/kernel/src/logger_disk_log_h.erl index a074d0210e..f08621c9c5 100644 --- a/lib/kernel/src/logger_disk_log_h.erl +++ b/lib/kernel/src/logger_disk_log_h.erl @@ -26,7 +26,7 @@ -include("logger_h_common.hrl"). %%% API --export([start_link/3, info/1, sync/1, reset/1]). +-export([start_link/3, info/1, filesync/1, reset/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -58,19 +58,19 @@ start_link(Name, Config, HandlerState) -> %%%----------------------------------------------------------------- %%% --spec sync(Name) -> ok | {error,Reason} when +-spec filesync(Name) -> ok | {error,Reason} when Name :: atom(), Reason :: handler_busy | {badarg,term()}. -sync(Name) when is_atom(Name) -> +filesync(Name) when is_atom(Name) -> try gen_server:call(?name_to_reg_name(?MODULE,Name), disk_log_sync, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; -sync(Name) -> - {error,{badarg,{sync,[Name]}}}. +filesync(Name) -> + {error,{badarg,{filesync,[Name]}}}. %%%----------------------------------------------------------------- %%% @@ -704,7 +704,7 @@ disk_log_sync(Name, State) -> ok; _ -> LogOpts = maps:get(log_opts, State), - logger_h_common:error_notify({Name,sync, + logger_h_common:error_notify({Name,filesync, LogOpts, SyncError}) end, diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl index d556938f02..1458c55e80 100644 --- a/lib/kernel/src/logger_h_common.erl +++ b/lib/kernel/src/logger_h_common.erl @@ -261,7 +261,7 @@ flush_log_events(Limit, Limit) -> Limit; flush_log_events(N, Limit) -> %% flush log events but leave other events, such as - %% file/disk_log_sync, info and change_config, so that these + %% filesync, info and change_config, so that these %% have a chance to be processed even under heavy load receive {'$gen_cast',{log,_}} -> diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl index ce9daa50ab..a03e1ffc2a 100644 --- a/lib/kernel/src/logger_std_h.erl +++ b/lib/kernel/src/logger_std_h.erl @@ -28,7 +28,7 @@ -include_lib("kernel/include/file.hrl"). %% API --export([start_link/3, info/1, sync/1, reset/1]). +-export([start_link/3, info/1, filesync/1, reset/1]). %% gen_server and proc_lib callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -60,19 +60,19 @@ start_link(Name, Config, HandlerState) -> %%%----------------------------------------------------------------- %%% --spec sync(Name) -> ok | {error,Reason} when +-spec filesync(Name) -> ok | {error,Reason} when Name :: atom(), Reason :: handler_busy | {badarg,term()}. -sync(Name) when is_atom(Name) -> +filesync(Name) when is_atom(Name) -> try gen_server:call(?name_to_reg_name(?MODULE,Name), filesync, ?DEFAULT_CALL_TIMEOUT) catch _:{timeout,_} -> {error,handler_busy} end; -sync(Name) -> - {error,{badarg,{sync,[Name]}}}. +filesync(Name) -> + {error,{badarg,{filesync,[Name]}}}. %%%----------------------------------------------------------------- %%% @@ -816,7 +816,7 @@ sync_dev(Fd, DevName, PrevSyncResult, HandlerName) -> %% don't report same error twice PrevSyncResult; Error -> - logger_h_common:error_notify({HandlerName,sync,DevName,Error}), + logger_h_common:error_notify({HandlerName,filesync,DevName,Error}), Error end. diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index 7225d4b57c..e1b1cbcb1a 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -143,7 +143,7 @@ create_log(Config) -> formatter=>{?MODULE,self()}}, #{file=>LogFile1}), logger:notice("hello", ?domain), - logger_disk_log_h:sync(Name1), + logger_disk_log_h:filesync(Name1), ct:pal("Checking contents of ~p", [?log_no(LogFile1,1)]), try_read_file(?log_no(LogFile1,1), {ok,<<"hello\n">>}, 5000), @@ -156,7 +156,7 @@ create_log(Config) -> formatter=>{?MODULE,self()}}, #{file=>LogFile2}), logger:notice("dummy", ?domain), - logger_disk_log_h:sync(Name2), + logger_disk_log_h:filesync(Name2), ct:pal("Checking contents of ~p", [?log_no(LogFile2,1)]), try_read_file(?log_no(LogFile2,1), {ok,<<"dummy\n">>}, 5000), @@ -177,7 +177,7 @@ open_existing_log(Config) -> formatter=>{?MODULE,self()}}, #{file=>LogFile1}), logger:notice("one", ?domain), - logger_disk_log_h:sync(HName), + logger_disk_log_h:filesync(HName), ct:pal("Checking contents of ~p", [?log_no(LogFile1,1)]), try_read_file(?log_no(LogFile1,1), {ok,<<"one\n">>}, 5000), logger:notice("two", ?domain), @@ -191,7 +191,7 @@ open_existing_log(Config) -> formatter=>{?MODULE,self()}}, #{file=>LogFile1}), logger:notice("three", ?domain), - logger_disk_log_h:sync(HName), + logger_disk_log_h:filesync(HName), try_read_file(?log_no(LogFile1,1), {ok,<<"one\ntwo\nthree\n">>}, 5000), remove_and_stop(HName), try_read_file(?log_no(LogFile1,1), {ok,<<"one\ntwo\nthree\n">>}, 5000). @@ -216,22 +216,22 @@ disk_log_opts(Config) -> {WFileFull,wrap,{Size,2},1} = {Get(file,WInfo1),Get(type,WInfo1), Get(size,WInfo1),Get(current_file,WInfo1)}, logger:notice("123", ?domain), - logger_disk_log_h:sync(WName), + logger_disk_log_h:filesync(WName), timer:sleep(500), 1 = Get(current_file, disk_log:info(WName)), logger:notice("45", ?domain), - logger_disk_log_h:sync(WName), + logger_disk_log_h:filesync(WName), timer:sleep(500), 1 = Get(current_file, disk_log:info(WName)), logger:notice("6", ?domain), - logger_disk_log_h:sync(WName), + logger_disk_log_h:filesync(WName), timer:sleep(500), 2 = Get(current_file, disk_log:info(WName)), logger:notice("7890", ?domain), - logger_disk_log_h:sync(WName), + logger_disk_log_h:filesync(WName), timer:sleep(500), 2 = Get(current_file, disk_log:info(WName)), @@ -249,7 +249,7 @@ disk_log_opts(Config) -> {HFile1Full,halt,infinity} = {Get(file,HInfo1),Get(type,HInfo1), Get(size,HInfo1)}, logger:notice("12345", ?domain), - logger_disk_log_h:sync(HName1), + logger_disk_log_h:filesync(HName1), timer:sleep(500), 1 = Get(no_written_items, disk_log:info(HName1)), @@ -426,8 +426,8 @@ config_fail(cleanup,_Config) -> logger:remove_handler(?MODULE). bad_input(_Config) -> - {error,{badarg,{sync,["BadType"]}}} = - logger_disk_log_h:sync("BadType"), + {error,{badarg,{filesync,["BadType"]}}} = + logger_disk_log_h:filesync("BadType"), {error,{badarg,{info,["BadType"]}}} = logger_disk_log_h:info("BadType"), {error,{badarg,{reset,["BadType"]}}} = logger_disk_log_h:reset("BadType"). @@ -545,7 +545,7 @@ sync(Config) -> logger:notice("second", ?domain), logger:notice("third", ?domain), %% do explicit sync - logger_disk_log_h:sync(?MODULE), + logger_disk_log_h:filesync(?MODULE), check_tracer(100), %% check that if there's no repeated disk_log_sync active, @@ -758,7 +758,7 @@ write_failure(Config) -> ct:pal("LogOpts = ~p", [LogOpts = maps:get(log_opts, HState)]), ok = log_on_remote_node(Node, "Logged1"), - rpc:call(Node, logger_disk_log_h, sync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_disk_log_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\n">>}, ?SYNC_REP_INT), @@ -778,7 +778,7 @@ write_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [disk_log_blog,ok]), ok = log_on_remote_node(Node, "Logged2"), - rpc:call(Node, logger_disk_log_h, sync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_disk_log_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, ?SYNC_REP_INT), ok. @@ -814,7 +814,7 @@ sync_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [disk_log_sync,{error,no_such_log}]), ok = log_on_remote_node(Node, "Cause simple error printout"), - ?check({error,{?STANDARD_HANDLER,sync,LogOpts,{error,no_such_log}}}), + ?check({error,{?STANDARD_HANDLER,filesync,LogOpts,{error,no_such_log}}}), ok = log_on_remote_node(Node, "No second error printout"), ?check_no_log, @@ -822,7 +822,7 @@ sync_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [disk_log_sync,{error,{blocked_log,?STANDARD_HANDLER}}]), ok = log_on_remote_node(Node, "Cause simple error printout"), - ?check({error,{?STANDARD_HANDLER,sync,LogOpts, + ?check({error,{?STANDARD_HANDLER,filesync,LogOpts, {error,{blocked_log,?STANDARD_HANDLER}}}}), rpc:call(Node, ?MODULE, set_result, [disk_log_sync,ok]), @@ -1195,7 +1195,7 @@ handler_requests_under_load(Config) -> flush_qlen => 2000, burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{sync,[]}, + Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{filesync,[]}, {info,[]}, {reset,[]}, {change_config,[]}]) diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index e0bc79012c..5227cac4e7 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -411,7 +411,7 @@ crash_std_h(cleanup) -> [test_server:stop_node(Node) || Node <- Nodes]. sync_and_read(Node,disk_log,Log) -> - rpc:call(Node,logger_disk_log_h,sync,[?STANDARD_HANDLER]), + rpc:call(Node,logger_disk_log_h,filesync,[?STANDARD_HANDLER]), case file:read_file(Log ++ ".1") of {ok,<<>>} -> timer:sleep(5000), @@ -420,7 +420,7 @@ sync_and_read(Node,disk_log,Log) -> Ok end; sync_and_read(Node,file,Log) -> - rpc:call(Node,logger_std_h,sync,[?STANDARD_HANDLER]), + rpc:call(Node,logger_std_h,filesync,[?STANDARD_HANDLER]), case file:read_file(Log) of {ok,<<>>} -> timer:sleep(5000), @@ -430,7 +430,7 @@ sync_and_read(Node,file,Log) -> end. bad_input(_Config) -> - {error,{badarg,{sync,["BadType"]}}} = logger_std_h:sync("BadType"), + {error,{badarg,{filesync,["BadType"]}}} = logger_std_h:filesync("BadType"), {error,{badarg,{info,["BadType"]}}} = logger_std_h:info("BadType"), {error,{badarg,{reset,["BadType"]}}} = logger_std_h:reset("BadType"). @@ -557,9 +557,9 @@ sync(Config) -> ]), logger:notice("second", ?domain), %% do explicit sync - logger_std_h:sync(?MODULE), + logger_std_h:filesync(?MODULE), %% a second sync should be ignored - logger_std_h:sync(?MODULE), + logger_std_h:filesync(?MODULE), check_tracer(100), %% check that if there's no repeated filesync active, @@ -618,7 +618,7 @@ write_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [file_write,ok]), ok = log_on_remote_node(Node, "Logged1"), - rpc:call(Node, logger_std_h, sync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_std_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\n">>}, ?FILESYNC_REP_INT), @@ -636,7 +636,7 @@ write_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [file_write,ok]), ok = log_on_remote_node(Node, "Logged2"), - rpc:call(Node, logger_std_h, sync, [?STANDARD_HANDLER]), + rpc:call(Node, logger_std_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, ?FILESYNC_REP_INT), ok. @@ -667,14 +667,14 @@ sync_failure(Config) -> rpc:call(Node, ?MODULE, set_result, [file_datasync,{error,terminated}]), ok = log_on_remote_node(Node, "Cause simple error printout"), - ?check({error,{?STANDARD_HANDLER,sync,Log,{error,terminated}}}), + ?check({error,{?STANDARD_HANDLER,filesync,Log,{error,terminated}}}), ok = log_on_remote_node(Node, "No second error printout"), ?check_no_log, rpc:call(Node, ?MODULE, set_result, [file_datasync,{error,eacces}]), ok = log_on_remote_node(Node, "Cause simple error printout"), - ?check({error,{?STANDARD_HANDLER,sync,Log,{error,eacces}}}), + ?check({error,{?STANDARD_HANDLER,filesync,Log,{error,eacces}}}), rpc:call(Node, ?MODULE, set_result, [file_datasync,ok]), ok = log_on_remote_node(Node, "Logged2"), @@ -1127,7 +1127,7 @@ handler_requests_under_load(Config) -> flush_qlen => 2000, burst_limit_enable => false}}, ok = logger:set_handler_config(?MODULE, NewHConfig), - Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{sync,[]}, + Pid = spawn_link(fun() -> send_requests(?MODULE, 1, [{filesync,[]}, {info,[]}, {reset,[]}, {change_config,[]}]) @@ -1328,7 +1328,7 @@ add_remove_instance_nofile(Type) -> logger:notice(M1=?msg,?domain), ?check(M1), %% check that sync doesn't do damage even if not relevant - ok = logger_std_h:sync(?MODULE), + ok = logger_std_h:filesync(?MODULE), ok = logger:remove_handler(?MODULE), timer:sleep(500), undefined = whereis(h_proc_name()), -- cgit v1.2.3 From 46a02602af6265888c426b3ca6eb426600437406 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 13 Jun 2018 12:30:37 +0200 Subject: [logger] Change overload_kill_restart_after value to infinity --- lib/kernel/src/logger_h_common.erl | 2 +- lib/kernel/src/logger_h_common.hrl | 4 ++-- lib/kernel/test/logger_disk_log_h_SUITE.erl | 6 +++--- lib/kernel/test/logger_std_h_SUITE.erl | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl index 1458c55e80..f9f762405c 100644 --- a/lib/kernel/src/logger_h_common.erl +++ b/lib/kernel/src/logger_h_common.erl @@ -115,7 +115,7 @@ check_common_config({overload_kill_qlen,N}) when is_integer(N) -> check_common_config({overload_kill_mem_size,N}) when is_integer(N) -> valid; check_common_config({overload_kill_restart_after,NorA}) when is_integer(NorA); - NorA == never -> + NorA == infinity -> valid; check_common_config({filesync_repeat_interval,NorA}) when is_integer(NorA); diff --git a/lib/kernel/src/logger_h_common.hrl b/lib/kernel/src/logger_h_common.hrl index ad80b51109..e0a7b6e3ca 100644 --- a/lib/kernel/src/logger_h_common.hrl +++ b/lib/kernel/src/logger_h_common.hrl @@ -41,10 +41,10 @@ -define(OVERLOAD_KILL_MEM_SIZE, 3000000). %% This is the default time that the handler will wait before -%% restarting and accepting new requests. The value 'never' +%% restarting and accepting new requests. The value 'infinity' %% disables restarts. -define(OVERLOAD_KILL_RESTART_AFTER, 5000). -%%-define(OVERLOAD_KILL_RESTART_AFTER, never). +%%-define(OVERLOAD_KILL_RESTART_AFTER, infinity). %% The handler sends asynchronous write requests to the process %% controlling the i/o device, but every once in this interval diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index e1b1cbcb1a..2f4ee504ea 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -475,7 +475,7 @@ reconfig(Config) -> overload_kill_enable => true, overload_kill_qlen => 100000, overload_kill_mem_size => 10000000, - overload_kill_restart_after => never, + overload_kill_restart_after => infinity, filesync_repeat_interval => no_repeat}, ok = logger:set_handler_config(?MODULE, config, HConfig1), #{id := ?MODULE, @@ -488,7 +488,7 @@ reconfig(Config) -> overload_kill_enable := true, overload_kill_qlen := 100000, overload_kill_mem_size := 10000000, - overload_kill_restart_after := never, + overload_kill_restart_after := infinity, filesync_repeat_interval := no_repeat} = logger_disk_log_h:info(?MODULE), @@ -1141,7 +1141,7 @@ restart_after(Config) -> NewHConfig1 = HConfig#{config=>DLHConfig#{overload_kill_enable=>true, overload_kill_qlen=>10, - overload_kill_restart_after=>never}}, + overload_kill_restart_after=>infinity}}, ok = logger:set_handler_config(?MODULE, NewHConfig1), MRef1 = erlang:monitor(process, whereis(h_proc_name())), %% kill handler diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 5227cac4e7..675e8d731f 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -473,7 +473,7 @@ reconfig(Config) -> overload_kill_enable => true, overload_kill_qlen => 100000, overload_kill_mem_size => 10000000, - overload_kill_restart_after => never, + overload_kill_restart_after => infinity, filesync_repeat_interval => no_repeat}), #{id := ?MODULE, type := standard_io, @@ -487,7 +487,7 @@ reconfig(Config) -> overload_kill_enable := true, overload_kill_qlen := 100000, overload_kill_mem_size := 10000000, - overload_kill_restart_after := never, + overload_kill_restart_after := infinity, filesync_repeat_interval := no_repeat} = logger_std_h:info(?MODULE), ok. @@ -1069,7 +1069,7 @@ restart_after(Config) -> NewHConfig1 = HConfig#{config=>StdHConfig#{overload_kill_enable=>true, overload_kill_qlen=>10, - overload_kill_restart_after=>never}}, + overload_kill_restart_after=>infinity}}, ok = logger:set_handler_config(?MODULE, NewHConfig1), MRef1 = erlang:monitor(process, whereis(h_proc_name())), %% kill handler -- cgit v1.2.3 From e7b7ae45884002c075697ff250400b247d158405 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 14 Jun 2018 11:15:21 +0200 Subject: [logger] Fix failing tests --- lib/kernel/test/logger_env_var_SUITE.erl | 2 +- lib/kernel/test/logger_test_lib.erl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/kernel/test/logger_env_var_SUITE.erl b/lib/kernel/test/logger_env_var_SUITE.erl index 3a8560bbf5..04a4364947 100644 --- a/lib/kernel/test/logger_env_var_SUITE.erl +++ b/lib/kernel/test/logger_env_var_SUITE.erl @@ -531,7 +531,7 @@ logger_many_handlers(Config, Env, LogErr, LogInfo, NumProgress) -> file,% dest 0,% progress in std logger error), % level - ok = rpc:call(Node,logger_std_h,sync,[info]), + ok = rpc:call(Node,logger_std_h,filesync,[info]), {ok, Bin} = file:read_file(LogInfo), ct:log("Log content:~n~s",[Bin]), match(Bin,<<"info:">>,NumProgress,info,info), diff --git a/lib/kernel/test/logger_test_lib.erl b/lib/kernel/test/logger_test_lib.erl index 9097453c10..81eb9ce5eb 100644 --- a/lib/kernel/test/logger_test_lib.erl +++ b/lib/kernel/test/logger_test_lib.erl @@ -52,10 +52,10 @@ log(Node, M, F, A) -> rpc:call(Node, M, F, A ++ [MD]). sync_and_read(Node,disk_log,Log) -> - rpc:call(Node,logger_disk_log_h,sync,[?STANDARD_HANDLER]), + rpc:call(Node,logger_disk_log_h,filesync,[?STANDARD_HANDLER]), file:read_file(Log ++ ".1"); sync_and_read(Node, file,Log) -> - ok = rpc:call(Node,logger_std_h,sync,[?STANDARD_HANDLER]), + ok = rpc:call(Node,logger_std_h,filesync,[?STANDARD_HANDLER]), file:read_file(Log). -- cgit v1.2.3 From 2ed5c964d31805b431d70e2d8b59260a76a809d5 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 14 Jun 2018 15:23:01 +0200 Subject: [logger] Fix test suite compilation warnings --- lib/kernel/test/logger_disk_log_h_SUITE.erl | 25 ++++++++++++--------- lib/kernel/test/logger_std_h_SUITE.erl | 35 ++++++++++++++++------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl index 2f4ee504ea..4c6fa1b5af 100644 --- a/lib/kernel/test/logger_disk_log_h_SUITE.erl +++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl @@ -45,10 +45,6 @@ -define(log_no(File,N), lists:concat([File,".",N])). -define(domain,#{domain=>[?MODULE]}). --define(SYNC_REP_INT, if is_atom(?FILESYNC_REPEAT_INTERVAL) -> 5500; - true -> ?FILESYNC_REPEAT_INTERVAL + 500 - end). - suite() -> [{timetrap,{seconds,30}}, {ct_hooks,[logger_test_lib]}]. @@ -69,9 +65,10 @@ end_per_group(_Group, _Config) -> init_per_testcase(TestHooksCase, Config) when TestHooksCase == write_failure; TestHooksCase == sync_failure -> - if ?TEST_HOOKS_TAB == undefined -> + case (fun() -> ?TEST_HOOKS_TAB == undefined end)() of + true -> {skip,"Define the TEST_HOOKS macro to run this test"}; - true -> + false -> ct:print("********** ~w **********", [TestHooksCase]), Config end; @@ -760,7 +757,13 @@ write_failure(Config) -> ok = log_on_remote_node(Node, "Logged1"), rpc:call(Node, logger_disk_log_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, - try_read_file(Log, {ok,<<"Logged1\n">>}, ?SYNC_REP_INT), + + SyncRepInt = case (fun() -> is_atom(?FILESYNC_REPEAT_INTERVAL) end)() of + true -> 5500; + false -> ?FILESYNC_REPEAT_INTERVAL + 500 + end, + + try_read_file(Log, {ok,<<"Logged1\n">>}, SyncRepInt), rpc:call(Node, ?MODULE, set_result, [disk_log_blog,{error,no_such_log}]), ok = log_on_remote_node(Node, "Cause simple error printout"), @@ -780,7 +783,7 @@ write_failure(Config) -> ok = log_on_remote_node(Node, "Logged2"), rpc:call(Node, logger_disk_log_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, - try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, ?SYNC_REP_INT), + try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, SyncRepInt), ok. write_failure(cleanup, _Config) -> Nodes = nodes(), @@ -1424,10 +1427,10 @@ wait_until_written(File, Sz) -> {ok,#file_info{size = Sz}} -> timer:sleep(1000), case file:read_file_info(File) of - {ok,#file_info{size = Sz1}} -> + {ok,#file_info{size = Sz}} -> ok; - {ok,#file_info{size = Sz2}} -> - wait_until_written(File, Sz2) + {ok,#file_info{size = Sz1}} -> + wait_until_written(File, Sz1) end; {ok,#file_info{size = Sz1}} -> wait_until_written(File, Sz1) diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl index 675e8d731f..134358bb64 100644 --- a/lib/kernel/test/logger_std_h_SUITE.erl +++ b/lib/kernel/test/logger_std_h_SUITE.erl @@ -45,10 +45,6 @@ -define(bin(Msg), list_to_binary(Msg++"\n")). -define(domain,#{domain=>[?MODULE]}). --define(FILESYNC_REP_INT, if is_atom(?FILESYNC_REPEAT_INTERVAL) -> 5500; - true -> ?FILESYNC_REPEAT_INTERVAL + 500 - end). - suite() -> [{timetrap,{seconds,30}}, {ct_hooks,[logger_test_lib]}]. @@ -73,9 +69,10 @@ end_per_group(_Group, _Config) -> init_per_testcase(TestHooksCase, Config) when TestHooksCase == write_failure; TestHooksCase == sync_failure -> - if ?TEST_HOOKS_TAB == undefined -> + case (fun() -> ?TEST_HOOKS_TAB == undefined end)() of + true -> {skip,"Define the TEST_HOOKS macro to run this test"}; - true -> + false -> ct:print("********** ~w **********", [TestHooksCase]), Config end; @@ -187,13 +184,13 @@ add_remove_instance_file(Log, Type) -> logger:notice(M1=?msg,?domain), ?check(M1), B1 = ?bin(M1), - try_read_file(Log, {ok,B1}, ?FILESYNC_REP_INT), + try_read_file(Log, {ok,B1}, filesync_rep_int()), ok = logger:remove_handler(?MODULE), timer:sleep(500), undefined = whereis(h_proc_name()), logger:notice(?msg,?domain), ?check_no_log, - try_read_file(Log, {ok,B1}, ?FILESYNC_REP_INT), + try_read_file(Log, {ok,B1}, filesync_rep_int()), ok. default_formatter(_Config) -> @@ -517,7 +514,7 @@ file_opts(Config) -> logger:notice(M1=?msg,?domain), ?check(M1), B1 = ?bin(M1), - try_read_file(Log, {ok,B1}, ?FILESYNC_REP_INT), + try_read_file(Log, {ok,B1}, filesync_rep_int()), ok. file_opts(cleanup, _Config) -> logger:remove_handler(?MODULE). @@ -544,7 +541,7 @@ sync(Config) -> logger:notice("first", ?domain), %% wait for automatic filesync - check_tracer(?FILESYNC_REP_INT*2), + check_tracer(filesync_rep_int()*2), %% check that explicit filesync is only done once start_tracer([{logger_std_h, write_to_dev, 5}, @@ -620,7 +617,7 @@ write_failure(Config) -> ok = log_on_remote_node(Node, "Logged1"), rpc:call(Node, logger_std_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, - try_read_file(Log, {ok,<<"Logged1\n">>}, ?FILESYNC_REP_INT), + try_read_file(Log, {ok,<<"Logged1\n">>}, filesync_rep_int()), rpc:call(Node, ?MODULE, set_result, [file_write,{error,terminated}]), ok = log_on_remote_node(Node, "Cause simple error printout"), @@ -638,7 +635,7 @@ write_failure(Config) -> ok = log_on_remote_node(Node, "Logged2"), rpc:call(Node, logger_std_h, filesync, [?STANDARD_HANDLER]), ?check_no_log, - try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, ?FILESYNC_REP_INT), + try_read_file(Log, {ok,<<"Logged1\nLogged2\n">>}, filesync_rep_int()), ok. write_failure(cleanup, _Config) -> Nodes = nodes(), @@ -1211,10 +1208,10 @@ wait_until_written(File, Sz) -> {ok,#file_info{size = Sz}} -> timer:sleep(1000), case file:read_file_info(File) of - {ok,#file_info{size = Sz1}} -> + {ok,#file_info{size = Sz}} -> ok; - {ok,#file_info{size = Sz2}} -> - wait_until_written(File, Sz2) + {ok,#file_info{size = Sz1}} -> + wait_until_written(File, Sz1) end; {ok,#file_info{size = Sz1}} -> wait_until_written(File, Sz1) @@ -1574,7 +1571,7 @@ wait_for_process_up(Name,T) -> N = (T div 500) + 1, wait_for_process_up1(Name,N). -wait_for_process_up1(Name,0) -> +wait_for_process_up1(_Name,0) -> error; wait_for_process_up1(Name,N) -> timer:sleep(500), @@ -1584,3 +1581,9 @@ wait_for_process_up1(Name,N) -> undefined -> wait_for_process_up1(Name,N-1) end. + +filesync_rep_int() -> + case (fun() -> is_atom(?FILESYNC_REPEAT_INTERVAL) end)() of + true -> 5500; + false -> ?FILESYNC_REPEAT_INTERVAL + 500 + end. -- cgit v1.2.3 From 9af8bca495c1704d7ce010939c7e54df7bfdef71 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Mon, 11 Jun 2018 22:48:25 +0200 Subject: [logger] Update handler documentation --- lib/kernel/doc/src/logger_chapter.xml | 243 +++++++++++++++++-------------- lib/kernel/doc/src/logger_disk_log_h.xml | 123 ++++++++-------- lib/kernel/doc/src/logger_std_h.xml | 71 ++++----- 3 files changed, 234 insertions(+), 203 deletions(-) diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml index f7df0a3e6e..5eab48f63e 100644 --- a/lib/kernel/doc/src/logger_chapter.xml +++ b/lib/kernel/doc/src/logger_chapter.xml @@ -1103,184 +1103,205 @@ do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) ->
Protecting the Handler from Overload -

In order for the built-in handlers to survive, and stay responsive, - during periods of high load (i.e. when huge numbers of incoming - log requests must be handled), a mechanism for overload protection - has been implemented in the - logger_std_h - and logger_disk_log_h - handler. The mechanism, used by both handlers, works - as follows:

+

The default handlers, + logger_std_h and + logger_disk_log_h, feature an overload protection + mechanism, which makes it possible for the handlers to survive, + and stay responsive, during periods of high load (i.e. when huge + numbers of incoming log requests must be handled). + The mechanism works as follows:

Message Queue Length

The handler process keeps track of the length of its message - queue and reacts in different ways depending on the current status. - The purpose is to keep the handler in, or (as quickly as possible), - get the handler into, a state where it can keep up with the pace - of incoming log requests. The memory usage of the handler must never - keep growing larger and larger, since that would eventually cause the - handler to crash. Three thresholds with associated actions have been - defined:

+ queue and takes some form of action when the current length exceeds a + configurable threshold. The purpose is to keep the handler in, or to + as quickly as possible get the handler into, a state where it can + keep up with the pace of incoming log events. The memory use of the + handler must never grow larger and larger, since that will eventually + cause the handler to crash. These three thresholds, with associated + actions, exist:

- toggle_sync_qlen + sync_mode_qlen -

The default value of this level is 10 messages, - and as long as the length of the message queue is lower, all log - requests are handled asynchronously. This simply means that the - process sending the log request (by calling a log function in the - Logger API) does not wait for a response from the handler but - continues executing immediately after the request (i.e. it will not - be affected by the time it takes the handler to print to the log - device). If the message queue grows larger than this value, however, - the handler starts handling the log requests synchronously instead, - meaning the process sending the request will have to wait for a - response. When the handler manages to reduce the message queue to a - level below the toggle_sync_qlen threshold, asynchronous +

As long as the length of the message queue is lower than this + value, all log events are handled asynchronously. This means that + the process sending the log event, by calling a log function in the + Logger API, does not wait for a response from the handler, but + continues executing immediately after the event is sent (that is, it + is not affected by the time it takes the handler to print the event + to the log device). If the message queue grows larger than this value, + the handler starts handling log events synchronously instead, + meaning that the process sending the event, must wait for a + response. When the handler reduces the message queue to a + level below the sync_mode_qlen threshold, asynchronous operation is resumed. The switch from asynchronous to synchronous - mode will force the logging tempo of few busy senders to slow down, - but cannot protect the handler sufficiently in situations of many - concurrent senders.

+ mode can slow down the logging tempo of one, or a few, busy senders, + but cannot protect the handler sufficiently in a situation of many + busy concurrent senders.

+

Default value of the threshold: 10 messages.

- drop_new_reqs_qlen + drop_mode_qlen -

When the message queue has grown larger than this threshold, which - defaults to 200 messages, the handler switches to a mode in - which it drops any new requests being made. Dropping a message in - this state means that the log function never actually sends a message - to the handler. The log call simply returns without an action. When - the length of the message queue has been reduced to a level below this - threshold, synchronous or asynchronous request handling mode is - resumed.

+

When the message queue grows larger than this threshold, the + handler switches to a mode in which it drops all new events that + senders want to send. Dropping an event in ths mode, means that the + log function never sends a message to the handler, but returns + without taking any action. The handler keeps logging events already + in the message queue, and when the length of the message queue is + reduced to a level below the threshold, synchronous or asynchronous + mode is resumed. Note that when the handler activates, or deactivates, + drop mode, information about it is printed to the log.

+

Default value of the threshold: 200 messages.

- flush_reqs_qlen + flush_qlen -

Above this threshold, which defaults to 1000 messages, a - flush operation takes place, in which all messages buffered in the - process mailbox get deleted without any logging actually taking - place. (Processes waiting for a response from a synchronous log request - will receive a reply indicating that the request has been dropped).

+

If the length of the message queue grows larger than this threshold, + a flush (delete) operation takes place. To flush events, the handler receives + the messages in the process mailbox in a loop without logging (that is, the + handler deletes the events). Processes waiting for a response from a + synchronous log request will receive a reply from the handler indicating + that the request has been dropped. The handler process will set its own priority + to high during the flush loop to make sure that no new events come in + during the operation. Note that after the flush operation is performed, + the handler prints information in the log about how many events have been + deleted

+

Default value of the threshold: 1000 messages.

For the overload protection algorithm to work properly, it is required that:

-

toggle_sync_qlen =< drop_new_reqs_qlen =< flush_reqs_qlen

+

sync_mode_qlen =< drop_mode_qlen =< flush_qlen

and that:

-

drop_new_reqs_qlen > 1

+

drop_mode_qlen > 1

-

If toggle_sync_qlen is set to 0, the handler will handle all - requests synchronously. Setting the value of toggle_sync_qlen to the same - as drop_new_reqs_qlen, disables the synchronous mode. Likewise, setting - the value of drop_new_reqs_qlen to the same as flush_reqs_qlen, - disables the drop mode.

+

To disable certain modes, do the following:

+ + If sync_mode_qlen is set to 0, all log events are handled + synchronously. That is, asynchronous logging is disabled. + If sync_mode_qlen is set to the same value as + drop_mode_qlen, synchronous mode is disabled. That is, the handler + always runs in asychronous mode, unless dropping or flushing is invoked. + If drop_mode_qlen is set to the same value as flush_qlen, + drop mode is disabled and can never occur. +

During high load scenarios, the length of the handler message queue rarely grows in a linear and predictable way. Instead, whenever the handler process gets scheduled in, it can have an almost arbitrary number of messages waiting in the mailbox. It's for this reason that the overload - protection mechanism is focused on acting quickly and quite drastically - (such as immediately dropping or flushing messages) as soon as a large - queue length is detected.

- -

The thresholds listed above may be modified by the user if, e.g, a handler - shouldn't drop or flush messages unless the message queue length grows - extremely large. (The handler must be allowed to use large amounts of memory - under such circumstances however). Another example of when the user might want - to change the settings is if, for performance reasons, the logging processes must - never get blocked by synchronous log requests, while dropping or flushing requests - is perfectly acceptable (since it doesn't affect the performance of the - loggers).

+ protection mechanism is focused on acting quickly, and quite drastically, + such as immediately dropping or flushing messages, when a large queue length + is detected.

+ +

The values of the previously listed thresholds can be specified by the user. + This way, a handler can be configured to, for example, not drop or flush + messages unless the message queue length of the handler process grows extremely + large. Note that large amounts of memory can be required for the node under such + circumstances. Another example of user configuration is when, for performance + reasons, the logging processes must never get blocked by synchronous log requests. + It's possible, perhaps, that dropping or flushing events is still acceptable (since + it does not affect the performance of the processes sending the log events).

A configuration example:

logger:add_handler(my_standard_h, logger_std_h, #{config => #{type => {file,"./system_info.log"}, - toggle_sync_qlen => 100, - drop_new_reqs_qlen => 1000, - flush_reqs_qlen => 2000}}). + sync_mode_qlen => 100, + drop_mode_qlen => 1000, + flush_qlen => 2000}}).
Controlling Bursts of Log Requests -

A potential problem with large bursts of log requests, is that log files - may get full or wrapped too quickly (in the latter case overwriting - previously logged data that could be of great importance). For this reason, - both built-in handlers offer the possibility to set a maximum level of how - many requests to process with a certain time frame. With this burst control - feature enabled, the handler will take care of bursts of log requests - without choking log files, or the terminal, with massive amounts of - printouts. These are the configuration parameters:

+

Large bursts of log events (that is, many events received by the handler + under a short period of time), can potentially cause problems, such as:

+ + Log files grow very large, very quickly. + Circular logs wrap too quickly so that important data gets overwritten. + Write buffers grow large, which slows down file sync operations. + + +

For this reason, both built-in handlers offer the possibility to specify the + maximum number of events to be handled within a certain time frame. + With this burst control feature enabled, the handler can avoid choking the log with + massive amounts of printouts. These are the configuration parameters:

- enable_burst_limit + burst_limit_enable -

This is set to true by default. The value false - disables the burst control feature.

+

Value true enables burst control and false disables it.

+

Defaults to true.

- burst_limit_size + burst_limit_max_count -

This is how many requests should be processed within the - burst_window_time time frame. After this maximum has been - reached, successive requests will be dropped until the end of the - time frame. The default value is 500 messages.

+

This is the maximum number of events to handle within a + burst_limit_window_time time frame. After the limit has been + reached, successive events get dropped until the end of the time frame.

+

Defaults to 500 events.

- burst_window_time + burst_limit_window_time -

The default window is 1000 milliseconds long.

+

See the previous description of burst_limit_window_time.

+

Defaults to 1000 milliseconds.

A configuration example:

logger:add_handler(my_disk_log_h, logger_disk_log_h, - #{disk_log_opts => - #{file => "./my_disk_log"}, - config => - #{burst_limit_size => 10, - burst_window_time => 500}}). + #{config => + #{file => "./my_disk_log", + burst_limit_enable => true, + burst_limit_max_count => 20, + burst_limit_window_time => 500}}).
- Terminating a Large Handler -

A handler process may grow large even if it can manage peaks of high load - without crashing. The overload protection mechanism includes user configurable - levels for a maximum allowed message queue length and maximum allowed memory - usage. This feature is disabled by default, but can be switched on by means - of the following configuration parameters:

- + Terminating an Overloaded Handler +

It is possible that a handler, even if it can successfully manage peaks + of high load without crashing, can build up a large message queue, or use a + large amount of memory. The overload protection mechanism includes an + automatic termination and restart feature for the purpose of guaranteeing + that a handler does not grow out of bounds. The feature can be configured + with the following parameters:

- enable_kill_overloaded + overload_kill_enable -

This is set to false by default. The value true - enables the feature.

+

Value true enables the feature and false disables it.

+

Defaults to false.

- handler_overloaded_qlen + overload_kill_qlen

This is the maximum allowed queue length. If the mailbox grows larger than this, the handler process gets terminated.

+

Defaults to 20000 messages.

- handler_overloaded_mem + overload_kill_mem_size -

This is the maximum allowed memory usage of the handler process. If - the handler grows any larger, the process gets terminated.

+

This is the maximum memory size that the handler process is allowed to use. + If the handler grows larger than this, the process gets terminated.

+

Defaults to 3000000 bytes.

- handler_restart_after + overload_kill_restart_after -

If the handler gets terminated because of its queue length or - memory usage, it can get automatically restarted again after a - configurable delay time. The time is specified in milliseconds - and 5000 is the default value. The value never can - also be set, which prevents a restart.

+

If the handler gets terminated, it can restart automatically after a + delay, specified in milliseconds. The value infinity can also be set, + which prevents restarts.

+

Defaults to 5000 milliseconds.

+

If the handler process gets terminated because of overload, information about + this event is printed in the log. Information about when a restart has taken + place, and the handler is back in action, is also printed.

diff --git a/lib/kernel/doc/src/logger_disk_log_h.xml b/lib/kernel/doc/src/logger_disk_log_h.xml index 63c29cb010..c60cf14cc7 100644 --- a/lib/kernel/doc/src/logger_disk_log_h.xml +++ b/lib/kernel/doc/src/logger_disk_log_h.xml @@ -38,101 +38,110 @@

This is a handler for Logger that offers circular (wrapped) logs by using disk_log. - Multiple instances - of this handler can be added to Logger, and each instance prints to - its own disk_log file, created with the name and settings specified in - the handler configuration.

+ Multiple instances of this handler can be added to Logger, and each instance + prints to its own disk_log file, created with the name and settings specified + in the handler configuration.

The default standard handler, logger_std_h, can be - replaced by a disk_log handler at start up of the Kernel application. + replaced by a disk_log handler at startup of the Kernel application. See an example of this below.

-

The handler has an overload protection mechanism that will keep the handler - process and the Kernel application alive during a high load of log - requests. How this feature works, and how to modify the configuration, - is described in the +

The handler has an overload protection mechanism that keeps the handler + process and the Kernel application alive during high loads of log + events. How overload protection works, and how to configure it, is + described in the User's Guide .

To add a new instance of the disk_log handler, use logger:add_handler/3 - . The handler configuration argument is a map which may contain + . The handler configuration argument is a map which can contain general configuration parameters, as documented in the User's Guide - , as well as handler specific parameters.

-

The settings for the disk_log log file should be specified with the - key disk_log_opts. These settings are a subset of the disk_log - data type - dlog_option().

-

Parameters in the disk_log_opts map:

+ , and handler specific parameters. The specific data + is stored in a sub map with the key config, and can contain the + following parameters:

file - This is the full name of the disk_log log file. + +

This is the full name of the disk_log log file. The option + corresponds to the name property in the + dlog_option() + datatype.

+
type - This is the disk_log type, wrap or halt. The - default value is wrap. + +

This is the disk_log type, wrap or halt. The option + corresponds to the type property in the + dlog_option() + datatype.

+

Defaults to wrap.

+
max_no_files - This is the maximum number of files that disk_log will use - for its circular logging. The default value is 10. (The setting - has no effect on a halt log). + +

This is the maximum number of files that disk_log will use + for its circular logging. The option + corresponds to the MaxNoFiles element in the size property in the + dlog_option() + datatype.

+

Defaults to 10. (The setting has no effect on a halt log).

+
max_no_bytes - This is the maximum number of bytes that will be written to - a log file before disk_log proceeds with the next file in order (or - generates an error in case of a full halt log). The default value for - a wrap log is 1048576 bytes, and infinity for a halt - log. -
-

Specific configuration for the handler (represented as a sub map) - is specified with the key config. It may contain the - following parameter:

- + +

This is the maximum number of bytes that will be written to + a log file before disk_log proceeds with the next file in order (or + generates an error in case of a full halt log). The option + corresponds to the MaxNoBytes element in the size property in the + dlog_option() + datatype.

+

Defaults to 1048576 bytes for a wrap log, and + infinity for a halt log.

+
filesync_repeat_interval -

This value (in milliseconds) specifies how often the handler will - do a disk_log sync operation in order to make sure that buffered data - gets written to disk. The handler will repeatedly attempt this - operation, but only perform it if something has actually been logged - since the last sync. The default value is 5000 milliseconds. - If no_repeat is set as value, the repeated sync operation is - disabled. The user can also call the - sync/1 - function to perform a disk_log sync.

+

This value, in milliseconds, specifies how often the handler does + a disk_log sync operation to write buffered data to disk. The handler attempts + the operation repeatedly, but only performs a new sync if something has + actually been logged.

+

Defaults to 5000 milliseconds.

+

If no_repeat is set as value, the repeated sync operation + is disabled. The user can also call the + filesync/1 + function to perform a disk_log sync.

+
-

There are a number of other configuration parameters available, that are - to be used for customizing the overload protection behaviour. The same - parameters are used both in the standard handler and the disk_log handler, - and are documented in the +

Other configuration parameters exist, to be used for customizing + the overload protection behaviour. The same parameters are used both in the + standard handler and the disk_log handler, and are documented in the User's Guide .

Note that when changing the configuration of the handler in runtime, by calling logger:set_handler_config/2 - or logger:set_handler_config/3, the disk_log_opts - settings may not be modified.

+ or logger:set_handler_config/3, the disk_log options (file, + type, max_no_files, max_no_bytes) must not be modified.

Example of adding a disk_log handler:

logger:add_handler(my_disk_log_h, logger_disk_log_h, #{level => error, filter_default => log, - disk_log_opts => - #{file => "./my_disk_log", - type => wrap, - max_no_files => 4, - max_no_bytes => 10000}, - config => - #{filesync_repeat_interval => 1000}}). + config => #{file => "./my_disk_log", + type => wrap, + max_no_files => 4, + max_no_bytes => 10000}, + filesync_repeat_interval => 1000}}). -

In order to use the disk_log handler instead of the default standard +

To use the disk_log handler instead of the default standard handler when starting an Erlang node, change the Kernel default logger to use disk_log. Example:

erl -kernel logger '[{handler,default,logger_disk_log_h, - #{disk_log_opts => #{file => "./system_disk_log"}}}]' + #{config => #{file => "./system_disk_log"}}}]'
- + Writes buffered data to disk.

Write buffered data to disk.

diff --git a/lib/kernel/doc/src/logger_std_h.xml b/lib/kernel/doc/src/logger_std_h.xml index 89e11389c5..08667ae7f9 100644 --- a/lib/kernel/doc/src/logger_std_h.xml +++ b/lib/kernel/doc/src/logger_std_h.xml @@ -38,62 +38,63 @@

This is the default handler for Logger. Multiple instances of this handler can be added to - Logger, and each instance will print logs to standard_io, + Logger, and each instance prints logs to standard_io, standard_error or to file. The default instance that starts - with Kernel is named default - which is the name to be used + with Kernel is named default, which is the name to be used for reconfiguration.

-

The handler has an overload protection mechanism that will keep the handler - process and the Kernel application alive during a high load of log - requests. How this feature works, and how to modify the configuration, - is described in the +

The handler has an overload protection mechanism that keeps the handler + process and the Kernel application alive during high loads of log + events. How overload protection works, and how to configure it, is + described in the User's Guide .

To add a new instance of the standard handler, use logger:add_handler/3 - . The handler configuration argument is a map which may contain - general configuration parameters, as documented in the + . The handler configuration argument is a map which can contain + general configuration parameters, as documented in the User's Guide - , as well as handler specific parameters. The specific parameters - are stored in a sub map with the key config. The following - keys and values may be specified:

+ , and handler specific parameters. The specific data + is stored in a sub map with the key config, and can contain the + following parameters:

type -

This will have the value standard_io, standard_error, - {file,LogFileName}, or {file,LogFileName,LogFileOpts}, - where standard_io is the default value for type. It's recommended - to not specify LogFileOpts if not absolutely necessary. The - default options used by the handler to open a file for logging are: - raw, append and delayed_write. The standard +

This has the value standard_io, standard_error, + {file,LogFileName}, or {file,LogFileName,LogFileOpts}.

+

Defaults to standard_io.

+

It is recommended to not specify LogFileOpts, unless absolutely + necessary. The default options used by the handler to open a file for logging are: + raw, append and delayed_write. Note that the standard handler does not have support for circular logging. Use the logger_disk_log_h - handler for this.

+ handler for this.

+ filesync_repeat_interval -

This value (in milliseconds) specifies how often the handler will - do a file sync operation in order to make sure that buffered data gets - written to disk. The handler will repeatedly attempt this - operation, but only perform it if something has actually been logged - since the last sync. The default value is 5000 milliseconds. - If no_repeat is set as value, the repeated file sync operation +

This value, in milliseconds, specifies how often the handler does + a file sync operation to write buffered data to disk. The handler attempts + the operation repeatedly, but only performs a new sync if something has + actually been logged.

+

Defaults to 5000 milliseconds.

+

If no_repeat is set as value, the repeated file sync operation is disabled, and it will be the operating system settings that determine how quickly or slowly data gets written to disk. The user can also call - the sync/1 - function to perform a file sync.

+ the filesync/1 + function to perform a file sync.

+
-

There are a number of other configuration parameters available, that are - to be used for customizing the overload protection behaviour. The same - parameters are used both in the standard handler and the disk_log handler, - and are documented in the +

Other configuration parameters exist, to be used for customizing + the overload protection behaviour. The same parameters are used both in the + standard handler and the disk_log handler, and are documented in the User's Guide .

-

Note that when changing the configuration of the handler in runtime, by +

Note that if changing the configuration of the handler in runtime, by calling logger:set_handler_config/2 , or logger:set_handler_config/3 , - the type parameter may not be modified.

+ the type parameter must not be modified.

Example of adding a standard handler:

logger:add_handler(my_standard_h, logger_std_h, @@ -103,9 +104,9 @@ logger:add_handler(my_standard_h, logger_std_h, #{type => {file,"./system_info.log"}, filesync_repeat_interval => 1000}}). -

In order to configure the default handler (that starts initially with +

To set the default handler (that starts initially with the Kernel application) to log to file instead of standard_io, - change the Kernel default logger to use a file. Example:

+ change the Kernel default logger configuration. Example:

erl -kernel logger '[{handler,default,logger_std_h, #{config => #{type => {file,"./log.log"}}}}]' @@ -118,7 +119,7 @@ erl -kernel logger '[{handler,default,logger_std_h, - + Writes buffered data to disk.

Write buffered data to disk.

-- cgit v1.2.3 From 343298ef2ef349e7b74265751fd6151ada224470 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Wed, 13 Jun 2018 23:56:38 +0200 Subject: [logger] Correct documentation --- lib/kernel/doc/src/logger_chapter.xml | 128 ++++++++++++++++--------------- lib/kernel/doc/src/logger_disk_log_h.xml | 33 ++++---- lib/kernel/doc/src/logger_std_h.xml | 47 +++++------- 3 files changed, 101 insertions(+), 107 deletions(-) diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml index 5eab48f63e..a4951022bb 100644 --- a/lib/kernel/doc/src/logger_chapter.xml +++ b/lib/kernel/doc/src/logger_chapter.xml @@ -97,6 +97,7 @@ defined.

+ Logger API

The API for logging consists of a set of macros, and a set @@ -1107,7 +1108,7 @@ do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) -> logger_std_h and logger_disk_log_h, feature an overload protection mechanism, which makes it possible for the handlers to survive, - and stay responsive, during periods of high load (i.e. when huge + and stay responsive, during periods of high load (when huge numbers of incoming log requests must be handled). The mechanism works as follows:

@@ -1127,47 +1128,49 @@ do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) ->

As long as the length of the message queue is lower than this value, all log events are handled asynchronously. This means that - the process sending the log event, by calling a log function in the - Logger API, does not wait for a response from the handler, but - continues executing immediately after the event is sent (that is, it - is not affected by the time it takes the handler to print the event - to the log device). If the message queue grows larger than this value, + the client process sending the log event, by calling a log function + in the Logger API, + does not wait for a response from the handler but continues + executing immediately after the event is sent. It is not affected + by the time it takes the handler to print the event to the log + device. If the message queue grows larger than this value, the handler starts handling log events synchronously instead, - meaning that the process sending the event, must wait for a + meaning that the client process sending the event must wait for a response. When the handler reduces the message queue to a level below the sync_mode_qlen threshold, asynchronous operation is resumed. The switch from asynchronous to synchronous mode can slow down the logging tempo of one, or a few, busy senders, but cannot protect the handler sufficiently in a situation of many busy concurrent senders.

-

Default value of the threshold: 10 messages.

+

Defaults to 10 messages.

drop_mode_qlen

When the message queue grows larger than this threshold, the handler switches to a mode in which it drops all new events that - senders want to send. Dropping an event in ths mode, means that the - log function never sends a message to the handler, but returns - without taking any action. The handler keeps logging events already - in the message queue, and when the length of the message queue is - reduced to a level below the threshold, synchronous or asynchronous - mode is resumed. Note that when the handler activates, or deactivates, - drop mode, information about it is printed to the log.

-

Default value of the threshold: 200 messages.

+ senders want to log. Dropping an event in this mode means that the + call to the log function never results in a message being sent to + the handler, but the function returns without taking any action. + The handler keeps logging the events that are already in its message + queue, and when the length of the message queue is reduced to a level + below the threshold, synchronous or asynchronous mode is resumed. + Notice that when the handler activates or deactivates drop mode, + information about it is printed in the log.

+

Defaults to 200 messages.

flush_qlen

If the length of the message queue grows larger than this threshold, - a flush (delete) operation takes place. To flush events, the handler receives - the messages in the process mailbox in a loop without logging (that is, the - handler deletes the events). Processes waiting for a response from a - synchronous log request will receive a reply from the handler indicating - that the request has been dropped. The handler process will set its own priority - to high during the flush loop to make sure that no new events come in - during the operation. Note that after the flush operation is performed, - the handler prints information in the log about how many events have been - deleted

-

Default value of the threshold: 1000 messages.

+ a flush (delete) operation takes place. To flush events, the handler + discards the messages in the message queue by receiving them in a + loop without logging. Client processes waiting for a response from a + synchronous log request receive a reply from the handler indicating + that the request is dropped. The handler process increases its + priority during the flush loop to make sure that no new events + are received during the operation. Notice that after the flush operation + is performed, the handler prints information in the log about how many + events have been deleted.

+

Defaults to 1000 messages.

@@ -1186,15 +1189,15 @@ do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) -> synchronously. That is, asynchronous logging is disabled. If sync_mode_qlen is set to the same value as drop_mode_qlen, synchronous mode is disabled. That is, the handler - always runs in asychronous mode, unless dropping or flushing is invoked. + always runs in asynchronous mode, unless dropping or flushing is invoked. If drop_mode_qlen is set to the same value as flush_qlen, drop mode is disabled and can never occur.

During high load scenarios, the length of the handler message queue rarely grows in a linear and predictable way. Instead, whenever the - handler process gets scheduled in, it can have an almost arbitrary number - of messages waiting in the mailbox. It's for this reason that the overload + handler process is scheduled in, it can have an almost arbitrary number + of messages waiting in the message queue. It is for this reason that the overload protection mechanism is focused on acting quickly, and quite drastically, such as immediately dropping or flushing messages, when a large queue length is detected.

@@ -1202,38 +1205,36 @@ do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) ->

The values of the previously listed thresholds can be specified by the user. This way, a handler can be configured to, for example, not drop or flush messages unless the message queue length of the handler process grows extremely - large. Note that large amounts of memory can be required for the node under such + large. Notice that large amounts of memory can be required for the node under such circumstances. Another example of user configuration is when, for performance - reasons, the logging processes must never get blocked by synchronous log requests. - It's possible, perhaps, that dropping or flushing events is still acceptable (since - it does not affect the performance of the processes sending the log events).

+ reasons, the client processes must never be blocked by synchronous log requests. + It is possible, perhaps, that dropping or flushing events is still acceptable, since + it does not affect the performance of the client processes sending the log events.

A configuration example:

logger:add_handler(my_standard_h, logger_std_h, - #{config => - #{type => {file,"./system_info.log"}, - sync_mode_qlen => 100, - drop_mode_qlen => 1000, - flush_qlen => 2000}}). + #{config => #{type => {file,"./system_info.log"}, + sync_mode_qlen => 100, + drop_mode_qlen => 1000, + flush_qlen => 2000}}).
Controlling Bursts of Log Requests -

Large bursts of log events (that is, many events received by the handler - under a short period of time), can potentially cause problems, such as:

+

Large bursts of log events - many events received by the handler + under a short period of time - can potentially cause problems, such as:

Log files grow very large, very quickly. - Circular logs wrap too quickly so that important data gets overwritten. + Circular logs wrap too quickly so that important data is overwritten. Write buffers grow large, which slows down file sync operations.

For this reason, both built-in handlers offer the possibility to specify the maximum number of events to be handled within a certain time frame. With this burst control feature enabled, the handler can avoid choking the log with - massive amounts of printouts. These are the configuration parameters:

- + massive amounts of printouts. The configuration parameters are:

burst_limit_enable @@ -1243,13 +1244,13 @@ logger:add_handler(my_standard_h, logger_std_h, burst_limit_max_count

This is the maximum number of events to handle within a - burst_limit_window_time time frame. After the limit has been - reached, successive events get dropped until the end of the time frame.

+ burst_limit_window_time time frame. After the limit is + reached, successive events are dropped until the end of the time frame.

Defaults to 500 events.

burst_limit_window_time -

See the previous description of burst_limit_window_time.

+

See the previous description of burst_limit_max_count.

Defaults to 1000 milliseconds.

@@ -1257,11 +1258,10 @@ logger:add_handler(my_standard_h, logger_std_h,

A configuration example:

logger:add_handler(my_disk_log_h, logger_disk_log_h, - #{config => - #{file => "./my_disk_log", - burst_limit_enable => true, - burst_limit_max_count => 20, - burst_limit_window_time => 500}}). + #{config => #{file => "./my_disk_log", + burst_limit_enable => true, + burst_limit_max_count => 20, + burst_limit_window_time => 500}}).
@@ -1271,7 +1271,7 @@ logger:add_handler(my_disk_log_h, logger_disk_log_h, of high load without crashing, can build up a large message queue, or use a large amount of memory. The overload protection mechanism includes an automatic termination and restart feature for the purpose of guaranteeing - that a handler does not grow out of bounds. The feature can be configured + that a handler does not grow out of bounds. The feature is configured with the following parameters:

overload_kill_enable @@ -1281,27 +1281,33 @@ logger:add_handler(my_disk_log_h, logger_disk_log_h, overload_kill_qlen -

This is the maximum allowed queue length. If the mailbox grows larger - than this, the handler process gets terminated.

+

This is the maximum allowed queue length. If the message queue grows + larger than this, the handler process is terminated.

Defaults to 20000 messages.

overload_kill_mem_size

This is the maximum memory size that the handler process is allowed to use. - If the handler grows larger than this, the process gets terminated.

+ If the handler grows larger than this, the process is terminated.

Defaults to 3000000 bytes.

overload_kill_restart_after -

If the handler gets terminated, it can restart automatically after a - delay, specified in milliseconds. The value infinity can also be set, - which prevents restarts.

+

If the handler is terminated, it restarts automatically after a + delay specified in milliseconds. The value infinity prevents + restarts.

Defaults to 5000 milliseconds.

-

If the handler process gets terminated because of overload, information about - this event is printed in the log. Information about when a restart has taken - place, and the handler is back in action, is also printed.

+

If the handler process is terminated because of overload, it prints + information about it in the log. It also prints information about when a + restart has taken place, and the handler is back in action.

+ +

The sizes of the log events affect the memory needs of the handler. + For information about how to limit the size of log events, see the + logger_formatter(3) + manual page.

+
diff --git a/lib/kernel/doc/src/logger_disk_log_h.xml b/lib/kernel/doc/src/logger_disk_log_h.xml index c60cf14cc7..98439983cf 100644 --- a/lib/kernel/doc/src/logger_disk_log_h.xml +++ b/lib/kernel/doc/src/logger_disk_log_h.xml @@ -33,13 +33,13 @@ logger_disk_log_h.xml logger_disk_log_h - A disk_log based handler for the Logger. + A disk_log based handler for Logger

This is a handler for Logger that offers circular (wrapped) logs by using disk_log. Multiple instances of this handler can be added to Logger, and each instance - prints to its own disk_log file, created with the name and settings specified + prints to its own disk log file, created with the name and settings specified in the handler configuration.

The default standard handler, logger_std_h, can be @@ -62,14 +62,14 @@ file -

This is the full name of the disk_log log file. The option +

This is the full name of the disk log file. The option corresponds to the name property in the dlog_option() datatype.

type -

This is the disk_log type, wrap or halt. The option +

This is the disk log type, wrap or halt. The option corresponds to the type property in the dlog_option() datatype.

@@ -77,18 +77,19 @@
max_no_files -

This is the maximum number of files that disk_log will use +

This is the maximum number of files that disk_log uses for its circular logging. The option corresponds to the MaxNoFiles element in the size property in the dlog_option() datatype.

-

Defaults to 10. (The setting has no effect on a halt log).

+

Defaults to 10.

+

The setting has no effect on a halt log.

max_no_bytes -

This is the maximum number of bytes that will be written to - a log file before disk_log proceeds with the next file in order (or - generates an error in case of a full halt log). The option +

This is the maximum number of bytes that is written to + a log file before disk_log proceeds with the next file in order, or + generates an error in case of a full halt log. The option corresponds to the MaxNoBytes element in the size property in the dlog_option() datatype.

@@ -113,17 +114,13 @@ standard handler and the disk_log handler, and are documented in the User's Guide .

-

Note that when changing the configuration of the handler in runtime, by - calling - logger:set_handler_config/2 - or logger:set_handler_config/3, the disk_log options (file, - type, max_no_files, max_no_bytes) must not be modified.

+

Notice that when changing the configuration of the handler in runtime, the + disk_log options (file, type, max_no_files, + max_no_bytes) must not be modified.

Example of adding a disk_log handler:

logger:add_handler(my_disk_log_h, logger_disk_log_h, - #{level => error, - filter_default => log, - config => #{file => "./my_disk_log", + #{config => #{file => "./my_disk_log", type => wrap, max_no_files => 4, max_no_bytes => 10000}, @@ -131,7 +128,7 @@ logger:add_handler(my_disk_log_h, logger_disk_log_h,

To use the disk_log handler instead of the default standard handler when starting an Erlang node, change the Kernel default logger to - use disk_log. Example:

+ use logger_disk_log_h. Example:

erl -kernel logger '[{handler,default,logger_disk_log_h, #{config => #{file => "./system_disk_log"}}}]' diff --git a/lib/kernel/doc/src/logger_std_h.xml b/lib/kernel/doc/src/logger_std_h.xml index 08667ae7f9..95b4baf160 100644 --- a/lib/kernel/doc/src/logger_std_h.xml +++ b/lib/kernel/doc/src/logger_std_h.xml @@ -33,15 +33,13 @@ logger_std_h.xml logger_std_h - Default handler for Logger. + Standard handler for Logger. -

This is the default handler for Logger. +

This is the standard handler for Logger. Multiple instances of this handler can be added to Logger, and each instance prints logs to standard_io, - standard_error or to file. The default instance that starts - with Kernel is named default, which is the name to be used - for reconfiguration.

+ standard_error, or to file.

The handler has an overload protection mechanism that keeps the handler process and the Kernel application alive during high loads of log events. How overload protection works, and how to configure it, is @@ -62,12 +60,12 @@

This has the value standard_io, standard_error, {file,LogFileName}, or {file,LogFileName,LogFileOpts}.

Defaults to standard_io.

-

It is recommended to not specify LogFileOpts, unless absolutely - necessary. The default options used by the handler to open a file for logging are: - raw, append and delayed_write. Note that the standard - handler does not have support for circular logging. Use the - logger_disk_log_h - handler for this.

+

It is recommended not to specify LogFileOpts unless absolutely + necessary. The default options used by the handler to open a file for logging are + raw, append, and delayed_write. Notice that the standard + handler does not have support for circular logging. Use the disk_log handler, + logger_disk_log_h, + for this.

filesync_repeat_interval @@ -77,8 +75,8 @@ actually been logged.

Defaults to 5000 milliseconds.

If no_repeat is set as value, the repeated file sync operation - is disabled, and it will be the operating system settings that determine - how quickly or slowly data gets written to disk. The user can also call + is disabled, and it is the operating system settings that determine + how quickly or slowly data is written to disk. The user can also call the filesync/1 function to perform a file sync.

@@ -88,32 +86,25 @@ standard handler and the disk_log handler, and are documented in the User's Guide .

-

Note that if changing the configuration of the handler in runtime, by - calling - logger:set_handler_config/2 - , or - logger:set_handler_config/3 - , +

Notice that if changing the configuration of the handler in runtime, the type parameter must not be modified.

Example of adding a standard handler:

logger:add_handler(my_standard_h, logger_std_h, - #{level => info, - filter_default => log, - config => - #{type => {file,"./system_info.log"}, - filesync_repeat_interval => 1000}}). + #{config => #{type => {file,"./system_info.log"}, + filesync_repeat_interval => 1000}}). -

To set the default handler (that starts initially with - the Kernel application) to log to file instead of standard_io, +

To set the default handler, that starts initially with + the Kernel application, to log to file instead of standard_io, change the Kernel default logger configuration. Example:

erl -kernel logger '[{handler,default,logger_std_h, #{config => #{type => {file,"./log.log"}}}}]'

An example of how to replace the standard handler with a disk_log handler - at start up can be found in the manual of - logger_disk_log_h.

+ at startup is found in the + logger_disk_log_h + manual.

-- cgit v1.2.3