From 224a42d658d3c08e3ce080fa8041c161e16f3863 Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Thu, 20 Sep 2018 16:56:26 +0200
Subject: [logger] Add SetOrUpdate parameter to handler callback
changing_config
Since logger has now knowledge of the handler specific data ('config'
field in the handler configuration map), it can not merge this data
structure with default or old values upon configuration
change. Instead, the handler callback changing_config must do
this. Earlier, this callback did not reflect if the configuration
change was initiated by a call to set_handler_config or
update_handler_config, so the handler did not know if unspecified
fields should get default values or the values from the existing
configuration.
To overcome this problem, the new parameter SetOrUpdate is added to
this callback. If SetOrUpdate equals set, then default values should
be used. If SetOrUpdate equals update, then existing configuration
values should be used.
---
lib/kernel/doc/src/logger.xml | 26 ++++++++++----
lib/kernel/doc/src/logger_chapter.xml | 6 ++--
lib/kernel/src/logger_server.erl | 64 ++++++++++++++++++++++++-----------
3 files changed, 67 insertions(+), 29 deletions(-)
(limited to 'lib/kernel')
diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml
index 464c65ba76..8f54d0e54f 100644
--- a/lib/kernel/doc/src/logger.xml
+++ b/lib/kernel/doc/src/logger.xml
@@ -1041,10 +1041,11 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)).
- HModule:changing_config(Config1, Config2) -> {ok, Config3} | {error, Reason}
+ HModule:changing_config(SetOrUpdate, OldConfig, NewConfig) -> {ok, Config} | {error, Reason}
The configuration for this handler is about to change.
- Config1 = Config2 = Config3 =
+ SetOrUpdate = set | update
+ OldConfig = NewConfig = Config =
handler_config()
Reason = term()
@@ -1053,12 +1054,25 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)).
The function is called on a temporary process when the
configuration for a handler is about to change. The purpose
is to verify and act on the new configuration.
- Config1 is the existing configuration
- and Config2 is the new configuration.
+ OldConfig is the existing configuration
+ and NewConfig is the new configuration.
The handler identity is associated with the id key
- in Config1.
+ in OldConfig.
+ SetOrUpdate has the value set if the
+ configuration change originates from a call to
+
+ set_handler_config/2,3, and update
+ if it originates from
+ update_handler_config/2. The handler can
+ use this parameteter to decide how to update the value of
+ the config field, that is, the handler specific
+ configuration data. Typically, if SetOrUpdate
+ equals set, values that are not specified must be
+ given their default values. If SetOrUpdate
+ equals update, the values found in OldConfig
+ must be used instead.
If everything succeeds, the callback function must return a
- possibly adjusted configuration in {ok,Config3}.
+ possibly adjusted configuration in {ok,Config}.
If the configuration is faulty, the callback function must
return {error,Reason}.
diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml
index 4a81cfa34a..7e88f82dad 100644
--- a/lib/kernel/doc/src/logger_chapter.xml
+++ b/lib/kernel/doc/src/logger_chapter.xml
@@ -384,7 +384,7 @@ logger:debug(#{got => connection_request, id => Id, state => State},
In addition to the mandatory callback function log/2, a
handler module can export the optional callback
- functions adding_handler/1, changing_config/2
+ functions adding_handler/1, changing_config/3
and removing_handler/1. See
section Handler
Callback Functions in the logger(3) manual page for
@@ -1024,7 +1024,7 @@ ok
- adding_handler(Config)
- removing_handler(Config)
- - changing_config(OldConfig, NewConfig)
+ - changing_config(SetOrUpdate, OldConfig, NewConfig)
When a handler is added, by for example a call
to
@@ -1045,7 +1045,7 @@ ok
or
logger:update_handler_config/2 is called,
Logger
- calls HModule:changing_config(OldConfig, NewConfig). If
+ calls HModule:changing_config(SetOrUpdate, OldConfig, NewConfig). If
this function returns {ok,NewConfig1}, Logger
writes NewConfig1 to the configuration database.
diff --git a/lib/kernel/src/logger_server.erl b/lib/kernel/src/logger_server.erl
index a1d40f1123..a14de2664e 100644
--- a/lib/kernel/src/logger_server.erl
+++ b/lib/kernel/src/logger_server.erl
@@ -105,12 +105,17 @@ cache_module_level(Module) ->
gen_server:cast(?SERVER,{cache_module_level,Module}).
set_config(Owner,Key,Value) ->
- update_config(Owner,#{Key=>Value}).
+ case sanity_check(Owner,Key,Value) of
+ ok ->
+ call({change_config,set,Owner,Key,Value});
+ Error ->
+ Error
+ end.
set_config(Owner,Config) ->
case sanity_check(Owner,Config) of
ok ->
- call({set_config,Owner,Config});
+ call({change_config,set,Owner,Config});
Error ->
Error
end.
@@ -118,7 +123,7 @@ set_config(Owner,Config) ->
update_config(Owner, Config) ->
case sanity_check(Owner,Config) of
ok ->
- call({update_config,Owner,Config});
+ call({change_config,update,Owner,Config});
Error ->
Error
end.
@@ -204,17 +209,35 @@ handle_call({add_filter,Id,Filter}, _From,#state{tid=Tid}=State) ->
handle_call({remove_filter,Id,FilterId}, _From, #state{tid=Tid}=State) ->
Reply = do_remove_filter(Tid,Id,FilterId),
{reply,Reply,State};
-handle_call({update_config,primary,NewConfig}, _From, #state{tid=Tid}=State) ->
+handle_call({change_config,SetOrUpd,primary,Config0}, _From,
+ #state{tid=Tid}=State) ->
+ {ok,#{handlers:=Handlers}=OldConfig} = logger_config:get(Tid,primary),
+ Default =
+ case SetOrUpd of
+ set -> default_config(primary);
+ update -> OldConfig
+ end,
+ Config = maps:merge(Default,Config0),
+ Reply = logger_config:set(Tid,primary,Config#{handlers=>Handlers}),
+ {reply,Reply,State};
+handle_call({change_config,_SetOrUpd,primary,Key,Value}, _From,
+ #state{tid=Tid}=State) ->
{ok,OldConfig} = logger_config:get(Tid,primary),
- Config = maps:merge(OldConfig,NewConfig),
- {reply,logger_config:set(Tid,primary,Config),State};
-handle_call({update_config,HandlerId,NewConfig}, From, #state{tid=Tid}=State) ->
+ Reply = logger_config:set(Tid,primary,OldConfig#{Key=>Value}),
+ {reply,Reply,State};
+handle_call({change_config,SetOrUpd,HandlerId,Config0}, From,
+ #state{tid=Tid}=State) ->
case logger_config:get(Tid,HandlerId) of
{ok,#{module:=Module}=OldConfig} ->
- Config = maps:merge(OldConfig,NewConfig),
+ Default =
+ case SetOrUpd of
+ set -> default_config(HandlerId,Module);
+ update -> OldConfig
+ end,
+ Config = maps:merge(Default,Config0),
call_h_async(
fun() ->
- call_h(Module,changing_config,[OldConfig,Config],
+ call_h(Module,changing_config,[SetOrUpd,OldConfig,Config],
{ok,Config})
end,
fun({ok,Config1}) ->
@@ -222,21 +245,17 @@ handle_call({update_config,HandlerId,NewConfig}, From, #state{tid=Tid}=State) ->
(Error) ->
Error
end,From,State);
- Error ->
- {reply,Error,State}
+ _ ->
+ {reply,{error,{not_found,HandlerId}},State}
end;
-handle_call({set_config,primary,Config0}, _From, #state{tid=Tid}=State) ->
- Config = maps:merge(default_config(primary),Config0),
- {ok,#{handlers:=Handlers}} = logger_config:get(Tid,primary),
- Reply = logger_config:set(Tid,primary,Config#{handlers=>Handlers}),
- {reply,Reply,State};
-handle_call({set_config,HandlerId,Config0}, From, #state{tid=Tid}=State) ->
+handle_call({change_config,SetOrUpd,HandlerId,Key,Value}, From,
+ #state{tid=Tid}=State) ->
case logger_config:get(Tid,HandlerId) of
{ok,#{module:=Module}=OldConfig} ->
- Config = maps:merge(default_config(HandlerId,Module),Config0),
+ Config = OldConfig#{Key=>Value},
call_h_async(
fun() ->
- call_h(Module,changing_config,[OldConfig,Config],
+ call_h(Module,changing_config,[SetOrUpd,OldConfig,Config],
{ok,Config})
end,
fun({ok,Config1}) ->
@@ -320,7 +339,7 @@ call(Request) ->
true when
Action == add_handler; Action == remove_handler;
Action == add_filter; Action == remove_filter;
- Action == update_config; Action == set_config ->
+ Action == change_config ->
{error,{attempting_syncronous_call_to_self,Request}};
_ ->
gen_server:call(?SERVER,Request,?DEFAULT_LOGGER_CALL_TIMEOUT)
@@ -466,6 +485,11 @@ call_h(Module, Function, Args, DefRet) ->
catch
C:R:S ->
case {C,R,S} of
+ {error,undef,[{Module,Function=changing_config,Args,_}|_]}
+ when length(Args)=:=3 ->
+ %% Backwards compatible call, if changing_config/3
+ %% did not exist.
+ call_h(Module, Function, tl(Args), DefRet);
{error,undef,[{Module,Function,Args,_}|_]} ->
DefRet;
_ ->
--
cgit v1.2.3