From cfbe1afe6ba1f1083c8aa41c7aeb422f253f5d23 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 18 May 2018 13:27:56 +0200 Subject: Add logger:update_formatter_config/2,3 --- lib/kernel/doc/src/logger.xml | 25 ++++++++++++ lib/kernel/doc/src/logger_chapter.xml | 6 +-- lib/kernel/src/logger.erl | 18 ++++++++- lib/kernel/src/logger_server.erl | 26 ++++++++++++- lib/kernel/test/logger_formatter_SUITE.erl | 61 +++++++++++++++++++++++++++++- 5 files changed, 130 insertions(+), 6 deletions(-) diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml index f7e740e90d..be733685cc 100644 --- a/lib/kernel/doc/src/logger.xml +++ b/lib/kernel/doc/src/logger.xml @@ -773,6 +773,31 @@ logger:set_handler_config(HandlerId,maps:merge(Old,Config)). + + + Update the formatter configuration for the specified handler. + +

Update the formatter configuration for the specified handler.

+

The new configuration is merged with the existing formatter + configuration.

+

To overwrite the existing configuration without any merge, + use + set_handler_config(HandlerId,formatter, + {FormatterModule,FormatterConfig}).

+
+
+ + + + Update the formatter configuration for the specified handler. + +

Update the formatter configuration for the specified handler.

+

This is equivalent + to
+ update_formatter_config(HandlerId,#{Key=>Value})

+
+
+ Compare the severity of two log levels. diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml index 21b460e72a..522d0ce29d 100644 --- a/lib/kernel/doc/src/logger_chapter.xml +++ b/lib/kernel/doc/src/logger_chapter.xml @@ -157,7 +157,7 @@

A formatter is defined as a module exporting the following function:

- format(Log,Extra) -> unicode:chardata() + format(Log,FConfig) -> unicode:chardata()

The formatter callback is called by each handler, and the returned string can be printed to the handler's destination @@ -413,12 +413,12 @@ return ignore.

Default is log.

- formatter = {Module::module(),Extra::term()} + formatter = {FModule::module(),FConfig::map()}

See Formatter for more information.

The default module is - logger_formatter, and Extra is + logger_formatter, and FConfig is it's configuration map.

HandlerConfig, term() = term() diff --git a/lib/kernel/src/logger.erl b/lib/kernel/src/logger.erl index 51743822af..d60be180bc 100644 --- a/lib/kernel/src/logger.erl +++ b/lib/kernel/src/logger.erl @@ -41,6 +41,7 @@ set_logger_config/1, set_logger_config/2, set_handler_config/2, set_handler_config/3, update_logger_config/1, update_handler_config/2, + update_formatter_config/2, update_formatter_config/3, get_logger_config/0, get_handler_config/1, add_handlers/1]). @@ -92,7 +93,7 @@ -type config() :: #{level => level(), filter_default => log | stop, filters => [{filter_id(),filter()}], - formatter => {module(),term()}, + formatter => {module(),map()}, term() => term()}. -type timestamp() :: integer(). @@ -386,6 +387,21 @@ get_logger_config() -> get_handler_config(HandlerId) -> logger_config:get(?LOGGER_TABLE,HandlerId). +-spec update_formatter_config(HandlerId,FormatterConfig) -> + ok | {error,term()} when + HandlerId :: config(), + FormatterConfig :: map(). +update_formatter_config(HandlerId,FormatterConfig) -> + logger_server:update_formatter_config(HandlerId,FormatterConfig). + +-spec update_formatter_config(HandlerId,Key,Value) -> + ok | {error,term()} when + HandlerId :: config(), + Key :: atom(), + Value :: term(). +update_formatter_config(HandlerId,Key,Value) -> + logger_server:update_formatter_config(HandlerId,#{Key=>Value}). + -spec set_module_level(Module,Level) -> ok | {error,term()} when Module :: module(), Level :: level(). diff --git a/lib/kernel/src/logger_server.erl b/lib/kernel/src/logger_server.erl index 67befef156..18a784c8c2 100644 --- a/lib/kernel/src/logger_server.erl +++ b/lib/kernel/src/logger_server.erl @@ -27,7 +27,8 @@ add_filter/2, remove_filter/2, set_module_level/2, reset_module_level/1, cache_module_level/1, - set_config/2, set_config/3, update_config/2]). + set_config/2, set_config/3, update_config/2, + update_formatter_config/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -111,6 +112,13 @@ update_config(Owner, Config) -> Error end. +update_formatter_config(HandlerId, FormatterConfig) + when is_map(FormatterConfig) -> + call({update_formatter_config,HandlerId,FormatterConfig}); +update_formatter_config(_HandlerId, FormatterConfig) -> + {error,{invalid_formatter_config,FormatterConfig}}. + + %%%=================================================================== %%% gen_server callbacks %%%=================================================================== @@ -216,6 +224,22 @@ handle_call({set_config,HandlerId,Config}, From, #state{tid=Tid}=State) -> _ -> {reply,{error,{not_found,HandlerId}},State} end; +handle_call({update_formatter_config,HandlerId,NewFConfig},_From, + #state{tid=Tid}=State) -> + Reply = + case logger_config:get(Tid,HandlerId) of + {ok,{_Mod,#{formatter:={FMod,OldFConfig}}=Config}} -> + try + FConfig = maps:merge(OldFConfig,NewFConfig), + check_formatter({FMod,FConfig}), + do_set_config(Tid,HandlerId, + Config#{formatter=>{FMod,FConfig}}) + catch throw:Reason -> {error,Reason} + end; + _ -> + {error,{not_found,HandlerId}} + end, + {reply,Reply,State}; handle_call({set_module_level,Module,Level}, _From, #state{tid=Tid}=State) -> Reply = logger_config:set_module_level(Tid,Module,Level), {reply,Reply,State}; diff --git a/lib/kernel/test/logger_formatter_SUITE.erl b/lib/kernel/test/logger_formatter_SUITE.erl index c171165944..934fe4deef 100644 --- a/lib/kernel/test/logger_formatter_SUITE.erl +++ b/lib/kernel/test/logger_formatter_SUITE.erl @@ -68,7 +68,8 @@ all() -> level_or_msg_in_meta, faulty_log, faulty_config, - faulty_msg]. + faulty_msg, + update_config]. default(_Config) -> String1 = format(info,{"~p",[term]},#{},#{}), @@ -532,6 +533,54 @@ faulty_msg(_Config) -> #{})), ok. +%% Test that formatter config can be changed, and that the default +%% template is updated accordingly +update_config(_Config) -> + logger:add_handler_filter(default,silence,{fun(_,_) -> stop end,ok}), + ok = logger:add_handler(?MODULE,?MODULE,#{}), + D = lists:seq(1,1000), + logger:info("~p~n",[D]), + {Lines1,C1} = check_log(), + [ct:log(L) || L <- Lines1], + ct:log("~p",[C1]), + [Line1] = Lines1, + [_Time,"info: "++D1] = string:split(Line1," "), + true = length(D1)>3000, + true = #{}==C1, + + ok = logger:update_formatter_config(?MODULE,single_line,false), + logger:info("~p~n",[D]), + {Lines2,C2} = check_log(), + [ct:log(L) || L <- Lines2], + ct:log("~p",[C2]), + true = length(Lines2)>50, + true = #{single_line=>false}==C2, + + ok = logger:update_formatter_config(?MODULE,#{legacy_header=>true}), + logger:info("~p~n",[D]), + {Lines3,C3} = check_log(), + [ct:log(L) || L <- Lines3], + ct:log("~p",[C3]), + ["=INFO REPORT==== "++_|D3] = Lines3, + true = length(D3)>50, + true = #{legacy_header=>true,single_line=>false}==C3, + + ok = logger:update_formatter_config(?MODULE,single_line,true), + logger:info("~p~n",[D]), + {Lines4,C4} = check_log(), + [ct:log(L) || L <- Lines4], + ct:log("~p",[C4]), + ["=INFO REPORT==== "++_,D4] = Lines4, + true = length(D4)>3000, + true = #{legacy_header=>true,single_line=>true}==C4, + + ok. + +update_config(cleanup,_Config) -> + _ = logger:remove_handler(?MODULE), + _ = logger:remove_handler_filter(default,silence), + ok. + %%%----------------------------------------------------------------- %%% Internal format(Level,Msg,Meta,Config) -> @@ -575,3 +624,13 @@ add_time(#{time:=_}=Meta) -> Meta; add_time(Meta) -> Meta#{time=>timestamp()}. + +%%%----------------------------------------------------------------- +%%% handler callback +log(Log,#{formatter:={M,C}}) -> + put(log,{M:format(Log,C),C}), + ok. + +check_log() -> + {S,C} = erase(log), + {string:lexemes(S,"\n"),C}. -- cgit v1.2.3