From 6211cead7be6f0871cfcccccdfc00dbeb466bcf2 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 14 Dec 2018 13:05:32 +0100 Subject: [logger] Add API function for configuring logger proxy --- lib/kernel/doc/src/logger.xml | 61 ++++++++++++++++++++++++++++++++-- lib/kernel/doc/src/logger_chapter.xml | 55 ++++++++++++++++++++++++++++-- lib/kernel/src/logger.erl | 41 ++++++++++++++++++++++- lib/kernel/src/logger_olp.erl | 11 +----- lib/kernel/src/logger_proxy.erl | 15 +++++---- lib/kernel/test/logger_proxy_SUITE.erl | 43 +++++++++++++++++++++++- 6 files changed, 204 insertions(+), 22 deletions(-) (limited to 'lib/kernel') diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml index e09c5db5e3..0668676096 100644 --- a/lib/kernel/doc/src/logger.xml +++ b/lib/kernel/doc/src/logger.xml @@ -244,6 +244,12 @@ logger:error("error happened because: ~p", [Reason]). % Without macro

+ + + +

+
+
@@ -597,8 +603,8 @@ start(_, []) -> Look up the current Logger configuration -

Look up all current Logger configuration, including primary - and handler configuration, and module level settings.

+

Look up all current Logger configuration, including primary, + handler, and proxy configuration, and module level settings.

@@ -635,6 +641,17 @@ start(_, []) ->
+ + + Look up the current configuration for the Logger proxy. + +

Look up the current configuration for the Logger proxy.

+

For more information about the proxy, see + section Logger + Proxy in the Kernel User's Guide.

+
+
+ Look up all current module levels. @@ -800,6 +817,27 @@ start(_, []) -> + + + Set configuration data for the Logger proxy. + +

Set configuration data for the Logger proxy. This + overwrites the current proxy configuration. Keys that are not + specified in the Config map gets default + values.

+

To modify the existing configuration, + use + update_proxy_config/1, or, if a more + complex merge is needed, read the current configuration + with get_proxy_config/0 + , then do the merge before writing the new + configuration back with this function.

+

For more information about the proxy, see + section Logger + Proxy in the Kernel User's Guide.

+
+
+ Set the log level for the specified modules. @@ -1013,6 +1051,25 @@ logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)). .

+ + + + Update configuration data for the Logger proxy. + +

Update configuration data for the Logger proxy. This function + behaves as if it was implemented as follows:

+ +Old = logger:get_proxy_config(), +logger:set_proxy_config(maps:merge(Old, Config)). + +

To overwrite the existing configuration without any merge, + use set_proxy_config/1 + .

+

For more information about the proxy, see + section Logger + Proxy in the Kernel User's Guide.

+
+
diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml index 458e61cef5..5ed7397135 100644 --- a/lib/kernel/doc/src/logger_chapter.xml +++ b/lib/kernel/doc/src/logger_chapter.xml @@ -693,8 +693,10 @@ logger:debug(#{got => connection_request, id => Id, state => State}, with logger_sasl_compatible.

With this parameter, you can modify or disable the default - handler, add custom handlers and primary logger filters, and - set log levels per module.

+ handler, add custom handlers and primary logger filters, set + log levels per module, and modify + the proxy + configuration.

Config is any (zero or more) of the following:

{handler, default, undefined} @@ -746,6 +748,14 @@ logger:debug(#{got => connection_request, id => Id, state => State},

for each Module.

Multiple entries of this type are allowed.

+ {proxy, ProxyConfig} + +

Sets the proxy configuration, equivalent to calling

+

+		logger:set_proxy_config(ProxyConfig)
+	    
+

Only one entry of this type is allowed.

+

See section Configuration @@ -1333,10 +1343,51 @@ logger:add_handler(my_disk_log_h, logger_disk_log_h,

+
+ + Logger Proxy +

The Logger proxy is an Erlang process which is part of the + Kernel application's supervision tree. During startup, the proxy + process registers itself as the system_logger, meaning + that log events produced by the emulator are sent to this + process.

+

When a log event is issued on a process which has its group + leader on a remote node, Logger automatically forwards the log + event to the group leader's node. To achieve this, it first + sends the log event as an Erlang message from the original + client process to the proxy on the local node, and the proxy in + turn forwards the event to the proxy on the remote node.

+

When receiving a log event, either from the emulator or from a + remote node, the proxy calls the Logger API to log the event.

+

The proxy process is overload protected in the same way as + described in + section Protecting the + Handler from Overload, but with the following default + values:

+ + #{sync_mode_qlen => 500, + drop_mode_qlen => 1000, + flush_qlen => 5000, + burst_limit_enable => false, + overload_kill_enable => false} +

For log events from the emulator, synchronous message passing + mode is not applicable, since all messages are passed + asynchronously by the emulator. Drop mode is achieved by setting + the system_logger to undefined, forcing the + emulator to drop events until it is set back to the proxy pid + again.

+

The proxy uses + erlang:send_nosuspend/2 when sending log + events to a remote node. If the message could not be sent + without suspending the sender, it is dropped. This is to avoid + blocking the proxy process.

+
+
See Also

disk_log(3), + erlang(3), error_logger(3), logger(3), logger_disk_log_h(3), diff --git a/lib/kernel/src/logger.erl b/lib/kernel/src/logger.erl index 1611d489e6..0ab3addfef 100644 --- a/lib/kernel/src/logger.erl +++ b/lib/kernel/src/logger.erl @@ -43,11 +43,14 @@ get_module_level/0, get_module_level/1, set_primary_config/1, set_primary_config/2, set_handler_config/2, set_handler_config/3, + set_proxy_config/1, update_primary_config/1, update_handler_config/2, update_handler_config/3, + update_proxy_config/1, update_formatter_config/2, update_formatter_config/3, get_primary_config/0, get_handler_config/1, get_handler_config/0, get_handler_ids/0, get_config/0, + get_proxy_config/0, add_handlers/1]). %% Private configuration @@ -122,6 +125,18 @@ {filters,log | stop,[{filter_id(),filter()}]} | {module_level,level(),[module()]}]. +-type olp_config() :: #{sync_mode_qlen => non_neg_integer(), + drop_mode_qlen => pos_integer(), + flush_qlen => pos_integer(), + burst_limit_enable => boolean(), + burst_limit_max_count => pos_integer(), + burst_limit_window_time => pos_integer(), + overload_kill_enable => boolean(), + overload_kill_qlen => pos_integer(), + overload_kill_mem_size => pos_integer(), + overload_kill_restart_after => + non_neg_integer() | infinity}. + -export_type([log_event/0, level/0, report/0, @@ -137,7 +152,8 @@ filter_arg/0, filter_return/0, config_handler/0, - formatter_config/0]). + formatter_config/0, + olp_config/0]). %%%----------------------------------------------------------------- %%% API @@ -390,6 +406,7 @@ set_primary_config(Key,Value) -> set_primary_config(Config) -> logger_server:set_config(primary,Config). + -spec set_handler_config(HandlerId,level,Level) -> Return when HandlerId :: handler_id(), Level :: level() | all | none, @@ -419,6 +436,14 @@ set_handler_config(HandlerId,Key,Value) -> set_handler_config(HandlerId,Config) -> logger_server:set_config(HandlerId,Config). +-spec set_proxy_config(Config) -> ok | {error,term()} when + Config :: olp_config(). +set_proxy_config(Config) when is_map(Config) -> + Defaults = logger_proxy:get_default_config(), + logger_olp:set_opts(logger_proxy,maps:merge(Defaults,Config)); +set_proxy_config(Config) -> + {error,{invalid_config,Config}}. + -spec update_primary_config(Config) -> ok | {error,term()} when Config :: primary_config(). update_primary_config(Config) -> @@ -453,6 +478,13 @@ update_handler_config(HandlerId,Key,Value) -> update_handler_config(HandlerId,Config) -> logger_server:update_config(HandlerId,Config). +-spec update_proxy_config(Config) -> ok | {error,term()} when + Config :: olp_config(). +update_proxy_config(Config) when is_map(Config) -> + logger_olp:set_opts(logger_proxy,Config); +update_proxy_config(Config) -> + {error,{invalid_config,Config}}. + -spec get_primary_config() -> Config when Config :: primary_config(). get_primary_config() -> @@ -486,6 +518,11 @@ get_handler_ids() -> {ok,#{handlers:=HandlerIds}} = logger_config:get(?LOGGER_TABLE,primary), HandlerIds. +-spec get_proxy_config() -> Config when + Config :: olp_config(). +get_proxy_config() -> + logger_olp:get_opts(logger_proxy). + -spec update_formatter_config(HandlerId,FormatterConfig) -> ok | {error,term()} when HandlerId :: handler_id(), @@ -606,10 +643,12 @@ unset_process_metadata() -> -spec get_config() -> #{primary=>primary_config(), handlers=>[handler_config()], + proxy=>olp_config(), module_levels=>[{module(),level() | all | none}]}. get_config() -> #{primary=>get_primary_config(), handlers=>get_handler_config(), + proxy=>get_proxy_config(), module_levels=>lists:keysort(1,get_module_level())}. -spec internal_init_logger() -> ok | {error,term()}. diff --git a/lib/kernel/src/logger_olp.erl b/lib/kernel/src/logger_olp.erl index 013cc6ce37..fbc2e81882 100644 --- a/lib/kernel/src/logger_olp.erl +++ b/lib/kernel/src/logger_olp.erl @@ -47,16 +47,7 @@ -opaque olp_ref() :: {atom(),pid(),ets:tid()}. --type options() :: #{sync_mode_qlen => integer(), - drop_mode_qlen => integer(), - flush_qlen => integer(), - burst_limit_enable => boolean(), - burst_limit_max_count => integer(), - burst_limit_window_time => integer(), - overload_kill_enable => boolean(), - overload_kill_qlen => integer(), - overload_kill_mem_size => integer(), - overload_kill_restart_after => integer()}. +-type options() :: logger:olp_config(). %%%----------------------------------------------------------------- %%% API diff --git a/lib/kernel/src/logger_proxy.erl b/lib/kernel/src/logger_proxy.erl index f89891bff0..45a3011828 100644 --- a/lib/kernel/src/logger_proxy.erl +++ b/lib/kernel/src/logger_proxy.erl @@ -20,7 +20,7 @@ -module(logger_proxy). %% API --export([start_link/0, restart/0, log/2, child_spec/0]). +-export([start_link/0, restart/0, log/2, child_spec/0, get_default_config/0]). %% logger_olp callbacks -export([init/1, handle_load/2, handle_info/2, terminate/2, @@ -69,11 +69,7 @@ start_link() -> %% %% Burst limit is disabled, since this is only a proxy and we %% don't want to limit bursts twice (here and in the handler). - Opts = #{sync_mode_qlen=>500, - drop_mode_qlen=>1000, - flush_qlen=>5000, - burst_limit_enable=>false}, - logger_olp:start_link(?SERVER,?MODULE,[],Opts). + logger_olp:start_link(?SERVER,?MODULE,[],get_default_config()). %% Fun used for restarting this process after it has been killed due %% to overload (must set overload_kill_enable=>true in opts) @@ -97,6 +93,13 @@ child_spec() -> type => worker, modules => [?MODULE]}. +get_default_config() -> + OlpDefault = logger_olp:get_default_opts(), + OlpDefault#{sync_mode_qlen=>500, + drop_mode_qlen=>1000, + flush_qlen=>5000, + burst_limit_enable=>false}. + %%%=================================================================== %%% gen_server callbacks %%%=================================================================== diff --git a/lib/kernel/test/logger_proxy_SUITE.erl b/lib/kernel/test/logger_proxy_SUITE.erl index 3197cf35de..2a76eec0fd 100644 --- a/lib/kernel/test/logger_proxy_SUITE.erl +++ b/lib/kernel/test/logger_proxy_SUITE.erl @@ -128,7 +128,48 @@ remote_emulator(cleanup,_Config) -> ok = logger:remove_handler(?HNAME). config(_Config) -> - {skip,not_yet_implemented}. + C1 = #{sync_mode_qlen:=SQ, + drop_mode_qlen:=DQ} = logger:get_proxy_config(), + + %% Update the existing config with these two values + SQ1 = SQ+1, + DQ1 = DQ+1, + ok = logger:update_proxy_config(#{sync_mode_qlen=>SQ1, + drop_mode_qlen=>DQ1}), + C2 = logger:get_proxy_config(), + C2 = C1#{sync_mode_qlen:=SQ1, + drop_mode_qlen:=DQ1}, + + %% Update the existing again with only one value + SQ2 = SQ+2, + ok = logger:update_proxy_config(#{sync_mode_qlen=>SQ2}), + C3 = logger:get_proxy_config(), + C3 = C2#{sync_mode_qlen:=SQ2}, + + %% Set the config, i.e. merge with defaults + ok = logger:set_proxy_config(#{sync_mode_qlen=>SQ1}), + C4 = logger:get_proxy_config(), + C4 = C1#{sync_mode_qlen:=SQ1}, + + %% Reset to default + ok = logger:set_proxy_config(#{}), + C5 = logger:get_proxy_config(), + C5 = logger_proxy:get_default_config(), + + %% Errors + {error,{invalid_olp_config,_}} = + logger:set_proxy_config(#{faulty_key=>1}), + {error,{invalid_olp_config,_}} = + logger:set_proxy_config(#{sync_mode_qlen=>infinity}), + {error,{invalid_config,[]}} = logger:set_proxy_config([]), + + {error,{invalid_olp_config,_}} = + logger:update_proxy_config(#{faulty_key=>1}), + {error,{invalid_olp_config,_}} = + logger:update_proxy_config(#{sync_mode_qlen=>infinity}), + {error,{invalid_config,[]}} = logger:update_proxy_config([]), + + ok. config(cleanup,_Config) -> ok. -- cgit v1.2.3