aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2018-05-24 15:56:07 +0200
committerSiri Hansen <[email protected]>2018-05-24 15:56:07 +0200
commit4f91c8a34f4cc2c728a63e8d218566b3b3795b10 (patch)
tree689a206967ccdbf98e2ecf3d67ffa9ab2fcf0a35 /lib/kernel/src
parent5c1d8ed81e66ef4977b7b68f573862bcbb9da7ca (diff)
parent53539ee751da408029c9dfae80384fdec6c7a552 (diff)
downloadotp-4f91c8a34f4cc2c728a63e8d218566b3b3795b10.tar.gz
otp-4f91c8a34f4cc2c728a63e8d218566b3b3795b10.tar.bz2
otp-4f91c8a34f4cc2c728a63e8d218566b3b3795b10.zip
Merge branch 'siri/logger-fix'
* siri/logger-fix: Update documentation of logger and error_logger Change type name logger:log() to logger:log_event() Update preloaded Update primary bootstrap Rename module logger_simple to logger_simple_h Change env var logger_log_progress to logger_progress_reports Remove HandlerId from handler callback functions and add it to Config Change handler id for sasl handler from sasl_h to sasl Change Compare parameter to logger_filters:domain/2 Update Logger documentation Rename reset_module_level to unset_module_level Allow chars_limit to limit strings Add logger:update_formatter_config/2,3 Set legacy_header=true for kernel's default handler only Improve documentation of logger and error_logger Use system_time instead of monotonic_time as timestamp in logger
Diffstat (limited to 'lib/kernel/src')
-rw-r--r--lib/kernel/src/Makefile4
-rw-r--r--lib/kernel/src/code_server.erl4
-rw-r--r--lib/kernel/src/error_logger.erl12
-rw-r--r--lib/kernel/src/kernel.app.src4
-rw-r--r--lib/kernel/src/logger.erl84
-rw-r--r--lib/kernel/src/logger_backend.erl4
-rw-r--r--lib/kernel/src/logger_config.erl4
-rw-r--r--lib/kernel/src/logger_disk_log_h.erl33
-rw-r--r--lib/kernel/src/logger_filters.erl74
-rw-r--r--lib/kernel/src/logger_formatter.erl42
-rw-r--r--lib/kernel/src/logger_h_common.erl10
-rw-r--r--lib/kernel/src/logger_internal.hrl7
-rw-r--r--lib/kernel/src/logger_server.erl60
-rw-r--r--lib/kernel/src/logger_simple_h.erl (renamed from lib/kernel/src/logger_simple.erl)15
-rw-r--r--lib/kernel/src/logger_std_h.erl33
15 files changed, 217 insertions, 173 deletions
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index eeb8c6ab2f..f265fdd272 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -118,7 +118,7 @@ MODULES = \
logger_filters \
logger_formatter \
logger_server \
- logger_simple \
+ logger_simple_h \
logger_sup \
net \
net_adm \
@@ -279,7 +279,7 @@ $(EBIN)/logger_disk_log_h.beam: logger_h_common.hrl logger_internal.hrl ../inclu
$(EBIN)/logger_filters.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_formatter.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_server.beam: logger_internal.hrl ../include/logger.hrl
-$(EBIN)/logger_simple.beam: logger_internal.hrl ../include/logger.hrl
+$(EBIN)/logger_simple_h.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_std_h.beam: logger_h_common.hrl logger_internal.hrl ../include/logger.hrl ../include/file.hrl
$(EBIN)/logger_h_common.beam: logger_h_common.hrl logger_internal.hrl ../include/logger.hrl
$(EBIN)/net_kernel.beam: ../include/net_address.hrl
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index bbfa2a995d..1a7677295b 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1437,7 +1437,7 @@ error_msg(Format, Args) ->
logger ! {log,error,Format,Args,
#{pid=>self(),
gl=>group_leader(),
- time=>erlang:monotonic_time(microsecond),
+ time=>erlang:system_time(microsecond),
error_logger=>#{tag=>error}}},
ok.
@@ -1446,7 +1446,7 @@ info_msg(Format, Args) ->
logger ! {log,info,Format,Args,
#{pid=>self(),
gl=>group_leader(),
- time=>erlang:monotonic_time(microsecond),
+ time=>erlang:system_time(microsecond),
error_logger=>#{tag=>info_msg}}},
ok.
diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl
index 6c3b308308..b3957d0c7e 100644
--- a/lib/kernel/src/error_logger.erl
+++ b/lib/kernel/src/error_logger.erl
@@ -32,7 +32,7 @@
which_report_handlers/0]).
%% logger callbacks
--export([adding_handler/2, removing_handler/2, log/2]).
+-export([adding_handler/1, removing_handler/1, log/2]).
-export([get_format_depth/0, limit_term/1]).
@@ -101,9 +101,9 @@ stop() ->
%%%-----------------------------------------------------------------
%%% Callbacks for logger
--spec adding_handler(logger:handler_id(),logger:config()) ->
+-spec adding_handler(logger:config()) ->
{ok,logger:config()} | {error,term()}.
-adding_handler(?MODULE,Config) ->
+adding_handler(#{id:=?MODULE}=Config) ->
case start() of
ok ->
{ok,Config};
@@ -111,12 +111,12 @@ adding_handler(?MODULE,Config) ->
Error
end.
--spec removing_handler(logger:handler_id(),logger:config()) -> ok.
-removing_handler(?MODULE,_Config) ->
+-spec removing_handler(logger:config()) -> ok.
+removing_handler(#{id:=?MODULE}) ->
stop(),
ok.
--spec log(logger:log(),logger:config()) -> ok.
+-spec log(logger:log_event(),logger:config()) -> ok.
log(#{level:=Level,msg:=Msg,meta:=Meta},_Config) ->
do_log(Level,Msg,Meta).
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 23ac5b3444..d873178f55 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -68,7 +68,7 @@
logger_formatter,
logger_h_common,
logger_server,
- logger_simple,
+ logger_simple_h,
logger_std_h,
logger_sup,
net,
@@ -142,7 +142,7 @@
{applications, []},
{env, [{logger_level, info},
{logger_sasl_compatible, false},
- {logger_log_progress, false}
+ {logger_progress_reports, stop}
]},
{mod, {kernel, []}},
{runtime_dependencies, ["erts-10.0", "stdlib-3.5", "sasl-3.0"]}
diff --git a/lib/kernel/src/logger.erl b/lib/kernel/src/logger.erl
index a839f97e62..3beb3102fa 100644
--- a/lib/kernel/src/logger.erl
+++ b/lib/kernel/src/logger.erl
@@ -37,10 +37,11 @@
-export([add_handler/3, remove_handler/1,
add_logger_filter/2, add_handler_filter/3,
remove_logger_filter/1, remove_handler_filter/2,
- set_module_level/2, reset_module_level/1,
+ set_module_level/2, unset_module_level/1,
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]).
@@ -63,11 +64,11 @@
%%%-----------------------------------------------------------------
%%% Types
--type log() :: #{level:=level(),
- msg:={io:format(),[term()]} |
- {report,report()} |
- {string,unicode:chardata()},
- meta:=metadata()}.
+-type log_event() :: #{level:=level(),
+ msg:={io:format(),[term()]} |
+ {report,report()} |
+ {string,unicode:chardata()},
+ meta:=metadata()}.
-type level() :: emergency | alert | critical | error |
warning | notice | info | debug.
-type report() :: map() | [{atom(),term()}].
@@ -80,26 +81,32 @@
mfa => {module(),atom(),non_neg_integer()},
file => file:filename(),
line => non_neg_integer(),
- term() => term()}.
+ domain => [atom()],
+ report_cb => fun((report()) -> {io:format(),[term()]}),
+ atom() => term()}.
-type location() :: #{mfa := {module(),atom(),non_neg_integer()},
file := file:filename(),
line := non_neg_integer()}.
-type handler_id() :: atom().
-type filter_id() :: atom().
--type filter() :: {fun((log(),filter_arg()) -> filter_return()),filter_arg()}.
+-type filter() :: {fun((log_event(),filter_arg()) ->
+ filter_return()),filter_arg()}.
-type filter_arg() :: term().
--type filter_return() :: stop | ignore | log().
--type config() :: #{level => level(),
+-type filter_return() :: stop | ignore | log_event().
+-type config() :: #{id => handler_id(),
+ level => level(),
filter_default => log | stop,
filters => [{filter_id(),filter()}],
- formatter => {module(),term()},
- term() => term()}.
+ formatter => {module(),formatter_config()},
+ atom() => term()}.
-type timestamp() :: integer().
+-type formatter_config() :: #{atom() => term()}.
-type config_handler() :: {handler, handler_id(), module(), config()}.
--export_type([log/0,level/0,report/0,msg_fun/0,metadata/0,config/0,handler_id/0,
- filter_id/0,filter/0,filter_arg/0,filter_return/0, config_handler/0]).
+-export_type([log_event/0,level/0,report/0,msg_fun/0,metadata/0,config/0,
+ handler_id/0,filter_id/0,filter/0,filter_arg/0,filter_return/0,
+ config_handler/0,formatter_config/0]).
%%%-----------------------------------------------------------------
%%% API
@@ -386,16 +393,31 @@ 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 :: formatter_config().
+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().
set_module_level(Module,Level) ->
logger_server:set_module_level(Module,Level).
--spec reset_module_level(Module) -> ok | {error,term()} when
+-spec unset_module_level(Module) -> ok | {error,term()} when
Module :: module().
-reset_module_level(Module) ->
- logger_server:reset_module_level(Module).
+unset_module_level(Module) ->
+ logger_server:unset_module_level(Module).
%%%-----------------------------------------------------------------
%%% Misc
@@ -542,10 +564,10 @@ internal_init_logger() ->
end || Module <- Modules]
|| {module_level, Level, Modules} <- get_logger_env()],
- case logger:set_handler_config(logger_simple,filters,
+ case logger:set_handler_config(simple,filters,
get_default_handler_filters()) of
ok -> ok;
- {error,{not_found,logger_simple}} -> ok
+ {error,{not_found,simple}} -> ok
end,
init_kernel_handlers()
@@ -561,7 +583,7 @@ init_kernel_handlers() ->
try
case get_logger_type() of
{ok,silent} ->
- ok = logger:remove_handler(logger_simple);
+ ok = logger:remove_handler(simple);
{ok,false} ->
ok;
{ok,Type} ->
@@ -602,9 +624,9 @@ add_handlers(HandlerConfig) ->
%% If a default handler was added we try to remove the simple_logger
%% If the simple logger exists it will replay its log events
%% to the handler(s) added in the fold above.
- _ = [case logger:remove_handler(logger_simple) of
+ _ = [case logger:remove_handler(simple) of
ok -> ok;
- {error,{not_found,logger_simple}} -> ok
+ {error,{not_found,simple}} -> ok
end || DefaultAdded],
ok
catch throw:Reason ->
@@ -677,7 +699,8 @@ init_default_config(Type) when Type==standard_io;
Type==standard_error;
element(1,Type)==file ->
Env = get_logger_env(),
- DefaultConfig = #{logger_std_h=>#{type=>Type}},
+ DefaultFormatter = #{formatter=>{?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}},
+ DefaultConfig = DefaultFormatter#{logger_std_h=>#{type=>Type}},
NewLoggerEnv =
case lists:keyfind(default, 2, Env) of
{handler, default, Module, Config} ->
@@ -687,6 +710,13 @@ init_default_config(Type) when Type==standard_io;
%% if not configured by user AND the default
%% handler is still the logger_std_h.
{handler, default, Module, maps:merge(DefaultConfig,Config)};
+ ({handler, default, logger_disk_log_h, _}) ->
+ %% Add default formatter. The point of this
+ %% is to get the expected formatter config
+ %% for the default handler, since this
+ %% differs from the default values that
+ %% logger_formatter itself adds.
+ {handler, default, logger_disk_log_h, maps:merge(DefaultFormatter,Config)};
(Other) ->
Other
end, Env);
@@ -704,10 +734,10 @@ get_default_handler_filters() ->
?DEFAULT_HANDLER_FILTERS([beam,erlang,otp]);
false ->
Extra =
- case application:get_env(kernel, logger_log_progress, false) of
- true ->
+ case application:get_env(kernel, logger_progress_reports, stop) of
+ log ->
[];
- false ->
+ stop ->
[{stop_progress,
{fun logger_filters:progress/2,stop}}]
end,
@@ -833,7 +863,7 @@ proc_meta() ->
default(pid) -> self();
default(gl) -> group_leader();
-default(time) -> erlang:monotonic_time(microsecond).
+default(time) -> erlang:system_time(microsecond).
%% Remove everything upto and including this module from the stacktrace
filter_stacktrace(Module,[{Module,_,_,_}|_]) ->
diff --git a/lib/kernel/src/logger_backend.erl b/lib/kernel/src/logger_backend.erl
index d9f5aa6faf..b3cf7d67dd 100644
--- a/lib/kernel/src/logger_backend.erl
+++ b/lib/kernel/src/logger_backend.erl
@@ -58,7 +58,7 @@ call_handlers(#{level:=Level}=Log,[Id|Handlers],Tid) ->
debug,
[{logger,removed_failing_handler},
{handler,{Id,Module}},
- {log,Log1},
+ {log_event,Log1},
{config,Config1},
{reason,{C,R,filter_stacktrace(S)}}]);
{error,{not_found,_}} ->
@@ -122,7 +122,7 @@ handle_filter_failed({Id,_}=Filter,Owner,Log,Reason) ->
[{logger,removed_failing_filter},
{filter,Filter},
{owner,Owner},
- {log,Log},
+ {log_event,Log},
{reason,Reason}]);
_ ->
ok
diff --git a/lib/kernel/src/logger_config.erl b/lib/kernel/src/logger_config.erl
index 40dc1b1e1b..1d35c2e068 100644
--- a/lib/kernel/src/logger_config.erl
+++ b/lib/kernel/src/logger_config.erl
@@ -24,7 +24,7 @@
allow/2,allow/3,
get/2, get/3, get/1,
create/3, create/4, set/3,
- set_module_level/3,reset_module_level/2,
+ set_module_level/3,unset_module_level/2,
cache_module_level/2,
level_to_int/1]).
@@ -109,7 +109,7 @@ set_module_level(Tid,Module,Level) ->
ets:insert(Tid,{Module,level_to_int(Level)}),
ok.
-reset_module_level(Tid,Module) ->
+unset_module_level(Tid,Module) ->
ets:delete(Tid,Module), % should possibley overwrite instead of delete?
ok.
diff --git a/lib/kernel/src/logger_disk_log_h.erl b/lib/kernel/src/logger_disk_log_h.erl
index 57c54ce27e..773aa75bc6 100644
--- a/lib/kernel/src/logger_disk_log_h.erl
+++ b/lib/kernel/src/logger_disk_log_h.erl
@@ -34,8 +34,8 @@
%% logger callbacks
-export([log/2,
- adding_handler/2, removing_handler/2,
- changing_config/3, swap_buffer/2]).
+ adding_handler/1, removing_handler/1,
+ changing_config/2, swap_buffer/2]).
%%%===================================================================
%%% API
@@ -108,8 +108,8 @@ reset(Name) ->
%%%-----------------------------------------------------------------
%%% Handler being added
-adding_handler(Name, Config) ->
- case check_config(adding, Name, Config) of
+adding_handler(#{id:=Name}=Config) ->
+ case check_config(adding, Config) of
{ok, Config1} ->
%% create initial handler state by merging defaults with config
HConfig = maps:get(?MODULE, Config1, #{}),
@@ -136,10 +136,9 @@ adding_handler(Name, Config) ->
%%%-----------------------------------------------------------------
%%% Updating handler config
-changing_config(Name,
- OldConfig=#{id:=Id, disk_log_opts:=DLOpts},
- NewConfig=#{id:=Id, disk_log_opts:=DLOpts}) ->
- case check_config(changing, Name, NewConfig) of
+changing_config(OldConfig=#{id:=Name, disk_log_opts:=DLOpts},
+ NewConfig=#{id:=Name, disk_log_opts:=DLOpts}) ->
+ case check_config(changing, NewConfig) of
Result = {ok,NewConfig1} ->
try gen_server:call(Name, {change_config,OldConfig,NewConfig1},
?DEFAULT_CALL_TIMEOUT) of
@@ -151,12 +150,10 @@ changing_config(Name,
Error ->
Error
end;
-changing_config(_Name, OldConfig, NewConfig) ->
+changing_config(OldConfig, NewConfig) ->
{error,{illegal_config_change,OldConfig,NewConfig}}.
-check_config(adding, Name, Config0) ->
- %% Merge in defaults on top level
- Config = maps:merge(#{id => Name}, Config0),
+check_config(adding, #{id:=Name}=Config) ->
%% Merge in defaults on handler level
LogOpts0 = maps:get(disk_log_opts, Config, #{}),
LogOpts = merge_default_logopts(Name, LogOpts0),
@@ -173,7 +170,7 @@ check_config(adding, Name, Config0) ->
Error ->
Error
end;
-check_config(changing, _Name, Config) ->
+check_config(changing, Config) ->
MyConfig = maps:get(?MODULE, Config, #{}),
case check_my_config(maps:to_list(MyConfig)) of
ok -> {ok,Config};
@@ -223,7 +220,7 @@ check_my_config([]) ->
%%%-----------------------------------------------------------------
%%% Handler being removed
-removing_handler(Name, _Config) ->
+removing_handler(#{id:=Name}) ->
stop(Name).
%%%-----------------------------------------------------------------
@@ -238,15 +235,15 @@ swap_buffer(Name,Buffer) ->
%%%-----------------------------------------------------------------
%%% Log a string or report
--spec log(Log, Config) -> ok | dropped when
- Log :: logger:log(),
+-spec log(LogEvent, Config) -> ok | dropped when
+ LogEvent :: logger:log_event(),
Config :: logger:config().
-log(Log,Config=#{id:=Name}) ->
+log(LogEvent,Config=#{id:=Name}) ->
%% if the handler has crashed, we must drop this request
%% and hope the handler restarts so we can try again
true = is_pid(whereis(Name)),
- Bin = logger_h_common:log_to_binary(Log,Config),
+ Bin = logger_h_common:log_to_binary(LogEvent,Config),
logger_h_common:call_cast_or_drop(Name, Bin).
diff --git a/lib/kernel/src/logger_filters.erl b/lib/kernel/src/logger_filters.erl
index 592ff28cc2..7359b3b4b7 100644
--- a/lib/kernel/src/logger_filters.erl
+++ b/lib/kernel/src/logger_filters.erl
@@ -27,31 +27,31 @@
-include("logger_internal.hrl").
-define(IS_ACTION(A), (A==log orelse A==stop)).
--spec domain(Log,Extra) -> logger:filter_return() when
- Log :: logger:log(),
+-spec domain(LogEvent,Extra) -> logger:filter_return() when
+ LogEvent :: logger:log_event(),
Extra :: {Action,Compare,MatchDomain},
Action :: log | stop,
- Compare :: prefix_of | starts_with | equals | no_domain,
+ Compare :: super | sub | equal | not_equal | undefined,
MatchDomain :: list(atom()).
-domain(#{meta:=Meta}=Log,{Action,Compare,MatchDomain})
+domain(#{meta:=Meta}=LogEvent,{Action,Compare,MatchDomain})
when ?IS_ACTION(Action) andalso
- (Compare==prefix_of orelse
- Compare==starts_with orelse
- Compare==equals orelse
- Compare==differs orelse
- Compare==no_domain) andalso
+ (Compare==super orelse
+ Compare==sub orelse
+ Compare==equal orelse
+ Compare==not_equal orelse
+ Compare==undefined) andalso
is_list(MatchDomain) ->
- filter_domain(Compare,Meta,MatchDomain,on_match(Action,Log));
-domain(Log,Extra) ->
- erlang:error(badarg,[Log,Extra]).
+ filter_domain(Compare,Meta,MatchDomain,on_match(Action,LogEvent));
+domain(LogEvent,Extra) ->
+ erlang:error(badarg,[LogEvent,Extra]).
--spec level(Log,Extra) -> logger:filter_return() when
- Log :: logger:log(),
+-spec level(LogEvent,Extra) -> logger:filter_return() when
+ LogEvent :: logger:log_event(),
Extra :: {Action,Operator,MatchLevel},
Action :: log | stop,
Operator :: neq | eq | lt | gt | lteq | gteq,
MatchLevel :: logger:level().
-level(#{level:=L1}=Log,{Action,Op,L2})
+level(#{level:=L1}=LogEvent,{Action,Op,L2})
when ?IS_ACTION(Action) andalso
(Op==neq orelse
Op==eq orelse
@@ -60,40 +60,40 @@ level(#{level:=L1}=Log,{Action,Op,L2})
Op==lteq orelse
Op==gteq) andalso
?IS_LEVEL(L2) ->
- filter_level(Op,L1,L2,on_match(Action,Log));
-level(Log,Extra) ->
- erlang:error(badarg,[Log,Extra]).
+ filter_level(Op,L1,L2,on_match(Action,LogEvent));
+level(LogEvent,Extra) ->
+ erlang:error(badarg,[LogEvent,Extra]).
--spec progress(Log,Extra) -> logger:filter_return() when
- Log :: logger:log(),
+-spec progress(LogEvent,Extra) -> logger:filter_return() when
+ LogEvent :: logger:log_event(),
Extra :: log | stop.
-progress(Log,Action) when ?IS_ACTION(Action) ->
- filter_progress(Log,on_match(Action,Log));
-progress(Log,Action) ->
- erlang:error(badarg,[Log,Action]).
+progress(LogEvent,Action) when ?IS_ACTION(Action) ->
+ filter_progress(LogEvent,on_match(Action,LogEvent));
+progress(LogEvent,Action) ->
+ erlang:error(badarg,[LogEvent,Action]).
--spec remote_gl(Log,Extra) -> logger:filter_return() when
- Log :: logger:log(),
+-spec remote_gl(LogEvent,Extra) -> logger:filter_return() when
+ LogEvent :: logger:log_event(),
Extra :: log | stop.
-remote_gl(Log,Action) when ?IS_ACTION(Action) ->
- filter_remote_gl(Log,on_match(Action,Log));
-remote_gl(Log,Action) ->
- erlang:error(badarg,[Log,Action]).
+remote_gl(LogEvent,Action) when ?IS_ACTION(Action) ->
+ filter_remote_gl(LogEvent,on_match(Action,LogEvent));
+remote_gl(LogEvent,Action) ->
+ erlang:error(badarg,[LogEvent,Action]).
%%%-----------------------------------------------------------------
%%% Internal
-filter_domain(prefix_of,#{domain:=Domain},MatchDomain,OnMatch) ->
+filter_domain(super,#{domain:=Domain},MatchDomain,OnMatch) ->
is_prefix(Domain,MatchDomain,OnMatch);
-filter_domain(starts_with,#{domain:=Domain},MatchDomain,OnMatch) ->
+filter_domain(sub,#{domain:=Domain},MatchDomain,OnMatch) ->
is_prefix(MatchDomain,Domain,OnMatch);
-filter_domain(equals,#{domain:=Domain},Domain,OnMatch) ->
+filter_domain(equal,#{domain:=Domain},Domain,OnMatch) ->
OnMatch;
-filter_domain(differs,#{domain:=Domain},MatchDomain,OnMatch)
+filter_domain(not_equal,#{domain:=Domain},MatchDomain,OnMatch)
when Domain=/=MatchDomain ->
OnMatch;
-filter_domain(Action,Meta,_,OnMatch) ->
+filter_domain(Compare,Meta,_,OnMatch) ->
case maps:is_key(domain,Meta) of
- false when Action==no_domain; Action==differs -> OnMatch;
+ false when Compare==undefined; Compare==not_equal -> OnMatch;
_ -> ignore
end.
@@ -123,5 +123,5 @@ filter_remote_gl(#{meta:=#{gl:=GL}},OnMatch) when node(GL)=/=node() ->
filter_remote_gl(_,_) ->
ignore.
-on_match(log,Log) -> Log;
+on_match(log,LogEvent) -> LogEvent;
on_match(stop,_) -> stop.
diff --git a/lib/kernel/src/logger_formatter.erl b/lib/kernel/src/logger_formatter.erl
index 602c666cc7..4d727b3da0 100644
--- a/lib/kernel/src/logger_formatter.erl
+++ b/lib/kernel/src/logger_formatter.erl
@@ -26,21 +26,22 @@
%%%-----------------------------------------------------------------
%%% Types
+-type config() :: #{chars_limit=>pos_integer()| unlimited,
+ depth=>pos_integer() | unlimited,
+ legacy_header=>boolean(),
+ max_size=>pos_integer() | unlimited,
+ report_cb=>fun((logger:report()) -> {io:format(),[term()]}),
+ single_line=>boolean(),
+ template=>template(),
+ time_designator=>byte(),
+ time_offset=>integer()|[byte()]}.
-type template() :: [atom()|tuple()|string()].
%%%-----------------------------------------------------------------
%%% API
--spec format(Log,Config) -> unicode:chardata() when
- Log :: logger:log(),
- Config :: #{single_line=>boolean(),
- legacy_header=>boolean(),
- report_cb=>fun((logger:report()) -> {io:format(),[term()]}),
- chars_limit=>pos_integer()| unlimited,
- max_size=>pos_integer() | unlimited,
- depth=>pos_integer() | unlimited,
- template=>template(),
- time_designator=>byte(),
- time_offset=>integer()|[byte()]}.
+-spec format(LogEvent,Config) -> unicode:chardata() when
+ LogEvent :: logger:log_event(),
+ Config :: config().
format(#{level:=Level,msg:=Msg0,meta:=Meta},Config0)
when is_map(Config0) ->
Config = add_default_config(Config0),
@@ -85,8 +86,6 @@ format(#{level:=Level,msg:=Msg0,meta:=Meta},Config0)
do_format(Level,Msg,Data,[level|Format],Config) ->
[to_string(level,Level,Config)|do_format(Level,Msg,Data,Format,Config)];
-do_format(Level,Msg,Data,[msg|Format],Config) ->
- [Msg|do_format(Level,Msg,Data,Format,Config)];
do_format(Level,Msg,Data,[Key|Format],Config) when is_atom(Key); is_tuple(Key) ->
Value = value(Key,Data),
[to_string(Key,Value,Config)|do_format(Level,Msg,Data,Format,Config)];
@@ -130,9 +129,7 @@ to_string(X) ->
io_lib:format("~tp",[X]).
format_msg({string,Chardata},Meta,Config) ->
- try unicode:characters_to_list(Chardata)
- catch _:_ -> format_msg({"INVALID STRING: ~tp",[Chardata]},Meta,Config)
- end;
+ format_msg({"~ts",[Chardata]},Meta,Config);
format_msg({report,_}=Msg,Meta,#{report_cb:=Fun}=Config) when is_function(Fun,1) ->
format_msg(Msg,Meta#{report_cb=>Fun},maps:remove(report_cb,Config));
format_msg({report,Report},#{report_cb:=Fun}=Meta,Config) when is_function(Fun,1) ->
@@ -197,16 +194,15 @@ truncate(String,Size) ->
String
end.
-format_time(Timestamp,#{time_offset:=Offset,time_designator:=Des})
- when is_integer(Timestamp) ->
- SysTime = Timestamp + erlang:time_offset(microsecond),
+%% SysTime is the system time in microseconds
+format_time(SysTime,#{time_offset:=Offset,time_designator:=Des})
+ when is_integer(SysTime) ->
calendar:system_time_to_rfc3339(SysTime,[{unit,microsecond},
{offset,Offset},
{time_designator,Des}]).
-%% Assuming this is monotonic time in microseconds
-timestamp_to_datetimemicro(Timestamp,Config) when is_integer(Timestamp) ->
- SysTime = Timestamp + erlang:time_offset(microsecond),
+%% SysTime is the system time in microseconds
+timestamp_to_datetimemicro(SysTime,Config) when is_integer(SysTime) ->
Micro = SysTime rem 1000000,
Sec = SysTime div 1000000,
UniversalTime = erlang:posixtime_to_universaltime(Sec),
@@ -327,6 +323,8 @@ offset_to_utc([$+|Tz]) ->
offset_to_utc(_) ->
false.
+-spec check_config(Config) -> ok | {error,term()} when
+ Config :: config().
check_config(Config) when is_map(Config) ->
do_check_config(maps:to_list(Config));
check_config(Config) ->
diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl
index 901c4c0dad..336398cd4a 100644
--- a/lib/kernel/src/logger_h_common.erl
+++ b/lib/kernel/src/logger_h_common.erl
@@ -39,8 +39,8 @@
%%%-----------------------------------------------------------------
%%% Covert log data on any form to binary
--spec log_to_binary(Log,Config) -> LogString when
- Log :: logger:log(),
+-spec log_to_binary(LogEvent,Config) -> LogString when
+ LogEvent :: logger:log_event(),
Config :: logger:config(),
LogString :: binary().
log_to_binary(#{msg:={report,_},meta:=#{report_cb:=_}}=Log,Config) ->
@@ -58,7 +58,7 @@ do_log_to_binary(Log,Config) ->
catch _:_ ->
?LOG_INTERNAL(debug,[{formatter_error,Formatter},
{config,FormatterConfig},
- {log,Log},
+ {log_event,Log},
{bad_return_value,String}]),
<<"FORMATTER ERROR: bad_return_value">>
end.
@@ -69,10 +69,10 @@ try_format(Log,Formatter,FormatterConfig) ->
C:R:S ->
?LOG_INTERNAL(debug,[{formatter_crashed,Formatter},
{config,FormatterConfig},
- {log,Log},
+ {log_event,Log},
{reason,
{C,R,logger:filter_stacktrace(?MODULE,S)}}]),
- case {?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG} of
+ case {?DEFAULT_FORMATTER,#{}} of
{Formatter,FormatterConfig} ->
"DEFAULT FORMATTER CRASHED";
{DefaultFormatter,DefaultConfig} ->
diff --git a/lib/kernel/src/logger_internal.hrl b/lib/kernel/src/logger_internal.hrl
index f9377259f3..fedd6db370 100644
--- a/lib/kernel/src/logger_internal.hrl
+++ b/lib/kernel/src/logger_internal.hrl
@@ -27,12 +27,11 @@
?DEFAULT_HANDLER_FILTERS([beam,erlang,otp])).
-define(DEFAULT_HANDLER_FILTERS(Domain),
[{remote_gl,{fun logger_filters:remote_gl/2,stop}},
- {domain,{fun logger_filters:domain/2,{log,prefix_of,Domain}}},
- {no_domain,{fun logger_filters:domain/2,{log,no_domain,[]}}}]).
+ {domain,{fun logger_filters:domain/2,{log,super,Domain}}},
+ {no_domain,{fun logger_filters:domain/2,{log,undefined,[]}}}]).
-define(DEFAULT_FORMATTER,logger_formatter).
-define(DEFAULT_FORMAT_CONFIG,#{legacy_header=>true,
- single_line=>false,
- template=>?DEFAULT_FORMAT_TEMPLATE_HEADER}).
+ single_line=>false}).
-define(DEFAULT_FORMAT_TEMPLATE_HEADER,
[{logger_formatter,header},"\n",msg,"\n"]).
-define(DEFAULT_FORMAT_TEMPLATE_SINGLE,
diff --git a/lib/kernel/src/logger_server.erl b/lib/kernel/src/logger_server.erl
index 275b9c476f..47010c9fa5 100644
--- a/lib/kernel/src/logger_server.erl
+++ b/lib/kernel/src/logger_server.erl
@@ -25,9 +25,10 @@
-export([start_link/0,
add_handler/3, remove_handler/1,
add_filter/2, remove_filter/2,
- set_module_level/2, reset_module_level/1,
+ set_module_level/2, unset_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,
@@ -82,9 +83,9 @@ set_module_level(Module,Level) when is_atom(Module) ->
set_module_level(Module,_) ->
{error,{not_a_module,Module}}.
-reset_module_level(Module) when is_atom(Module) ->
- call({reset_module_level,Module});
-reset_module_level(Module) ->
+unset_module_level(Module) when is_atom(Module) ->
+ call({unset_module_level,Module});
+unset_module_level(Module) ->
{error,{not_a_module,Module}}.
cache_module_level(Module) ->
@@ -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
%%%===================================================================
@@ -119,15 +127,14 @@ init([]) ->
process_flag(trap_exit, true),
Tid = logger_config:new(?LOGGER_TABLE),
LoggerConfig = maps:merge(default_config(logger),
- #{handlers=>[logger_simple]}),
+ #{handlers=>[simple]}),
logger_config:create(Tid,logger,LoggerConfig),
- SimpleConfig0 = maps:merge(default_config(logger_simple),
+ SimpleConfig0 = maps:merge(default_config(simple),
#{filter_default=>stop,
filters=>?DEFAULT_HANDLER_FILTERS}),
%% If this fails, then the node should crash
- {ok,SimpleConfig} =
- logger_simple:adding_handler(logger_simple,SimpleConfig0),
- logger_config:create(Tid,logger_simple,logger_simple,SimpleConfig),
+ {ok,SimpleConfig} = logger_simple_h:adding_handler(SimpleConfig0),
+ logger_config:create(Tid,simple,logger_simple_h,SimpleConfig),
{ok, #state{tid=Tid, async_req_queue = queue:new()}}.
handle_call({add_handler,Id,Module,HConfig}, From, #state{tid=Tid}=State) ->
@@ -138,7 +145,7 @@ handle_call({add_handler,Id,Module,HConfig}, From, #state{tid=Tid}=State) ->
call_h_async(
fun() ->
%% inform the handler
- call_h(Module,adding_handler,[Id,HConfig],{ok,HConfig})
+ call_h(Module,adding_handler,[HConfig],{ok,HConfig})
end,
fun({ok,HConfig1}) ->
%% We know that the call_h would have loaded the module
@@ -169,7 +176,7 @@ handle_call({remove_handler,HandlerId}, From, #state{tid=Tid}=State) ->
call_h_async(
fun() ->
%% inform the handler
- call_h(Module,removing_handler,[HandlerId,HConfig],ok)
+ call_h(Module,removing_handler,[HConfig],ok)
end,
fun(_Res) ->
do_set_config(Tid,logger,Config#{handlers=>Handlers}),
@@ -205,7 +212,7 @@ handle_call({set_config,HandlerId,Config}, From, #state{tid=Tid}=State) ->
{ok,{Module,OldConfig}} ->
call_h_async(
fun() ->
- call_h(Module,changing_config,[HandlerId,OldConfig,Config],
+ call_h(Module,changing_config,[OldConfig,Config],
{ok,Config})
end,
fun({ok,Config1}) ->
@@ -216,11 +223,27 @@ 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};
-handle_call({reset_module_level,Module}, _From, #state{tid=Tid}=State) ->
- Reply = logger_config:reset_module_level(Tid,Module),
+handle_call({unset_module_level,Module}, _From, #state{tid=Tid}=State) ->
+ Reply = logger_config:unset_module_level(Tid,Module),
{reply,Reply,State}.
handle_cast({async_req_reply,_Ref,_Reply} = Reply,State) ->
@@ -324,11 +347,12 @@ default_config(logger) ->
#{level=>info,
filters=>[],
filter_default=>log};
-default_config(_) ->
- #{level=>info,
+default_config(Id) ->
+ #{id=>Id,
+ level=>info,
filters=>[],
filter_default=>log,
- formatter=>{?DEFAULT_FORMATTER,?DEFAULT_FORMAT_CONFIG}}.
+ formatter=>{?DEFAULT_FORMATTER,#{}}}.
sanity_check(Owner,Key,Value) ->
sanity_check_1(Owner,[{Key,Value}]).
diff --git a/lib/kernel/src/logger_simple.erl b/lib/kernel/src/logger_simple_h.erl
index 5272455a2d..19fb3b54ba 100644
--- a/lib/kernel/src/logger_simple.erl
+++ b/lib/kernel/src/logger_simple_h.erl
@@ -17,9 +17,9 @@
%%
%% %CopyrightEnd%
%%
--module(logger_simple).
+-module(logger_simple_h).
--export([adding_handler/2, removing_handler/2, log/2]).
+-export([adding_handler/1, removing_handler/1, log/2]).
%% This module implements a simple handler for logger. It is the
%% default used during system start.
@@ -27,7 +27,7 @@
%%%-----------------------------------------------------------------
%%% Logger callback
-adding_handler(?MODULE,Config) ->
+adding_handler(#{id:=simple}=Config) ->
Me = self(),
case whereis(?MODULE) of
undefined ->
@@ -44,7 +44,7 @@ adding_handler(?MODULE,Config) ->
{error,{handler_process_name_already_exists,?MODULE}}
end.
-removing_handler(?MODULE,_Config) ->
+removing_handler(#{id:=simple}) ->
case whereis(?MODULE) of
undefined ->
ok;
@@ -70,7 +70,7 @@ log(#{msg:=_,meta:=#{time:=_}}=Log,_Config) ->
do_log(
#{level=>error,
msg=>{report,{error,simple_handler_process_dead}},
- meta=>#{time=>erlang:monotonic_time(microsecond)}}),
+ meta=>#{time=>erlang:system_time(microsecond)}}),
do_log(Log);
_ ->
?MODULE ! {log,Log}
@@ -126,7 +126,7 @@ drop_msg(0) ->
drop_msg(N) ->
[#{level=>info,
msg=>{"Simple handler buffer full, dropped ~w messages",[N]},
- meta=>#{time=>erlang:monotonic_time(microsecond)}}].
+ meta=>#{time=>erlang:system_time(microsecond)}}].
%%%-----------------------------------------------------------------
%%% Internal
@@ -141,8 +141,7 @@ do_log(#{msg:=Msg,meta:=#{time:=T}}) ->
display_date(T),
display(Msg).
-display_date(Timestamp0) when is_integer(Timestamp0) ->
- Timestamp = Timestamp0 + erlang:time_offset(microsecond),
+display_date(Timestamp) when is_integer(Timestamp) ->
Micro = Timestamp rem 1000000,
Sec = Timestamp div 1000000,
{{Y,Mo,D},{H,Mi,S}} = erlang:universaltime_to_localtime(
diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl
index e5e0febc88..63c3ab2dac 100644
--- a/lib/kernel/src/logger_std_h.erl
+++ b/lib/kernel/src/logger_std_h.erl
@@ -35,8 +35,8 @@
terminate/2, code_change/3]).
%% logger callbacks
--export([log/2, adding_handler/2, removing_handler/2,
- changing_config/3, swap_buffer/2]).
+-export([log/2, adding_handler/1, removing_handler/1,
+ changing_config/2, swap_buffer/2]).
%%%===================================================================
%%% API
@@ -109,8 +109,8 @@ reset(Name) ->
%%%-----------------------------------------------------------------
%%% Handler being added
-adding_handler(Name, Config) ->
- case check_config(adding, Name, Config) of
+adding_handler(#{id:=Name}=Config) ->
+ case check_config(adding, Config) of
{ok, Config1} ->
%% create initial handler state by merging defaults with config
HConfig = maps:get(?MODULE, Config1, #{}),
@@ -137,9 +137,8 @@ adding_handler(Name, Config) ->
%%%-----------------------------------------------------------------
%%% Updating handler config
-changing_config(Name,
- OldConfig=#{id:=Id, ?MODULE:=#{type:=Type}},
- NewConfig=#{id:=Id}) ->
+changing_config(OldConfig=#{id:=Name, ?MODULE:=#{type:=Type}},
+ NewConfig=#{id:=Name}) ->
MyConfig = maps:get(?MODULE, NewConfig, #{}),
case maps:get(type, MyConfig, Type) of
Type ->
@@ -149,11 +148,11 @@ changing_config(Name,
_ ->
{error,{illegal_config_change,OldConfig,NewConfig}}
end;
-changing_config(_Name, OldConfig, NewConfig) ->
+changing_config(OldConfig, NewConfig) ->
{error,{illegal_config_change,OldConfig,NewConfig}}.
changing_config1(Name, OldConfig, NewConfig) ->
- case check_config(changing, Name, NewConfig) of
+ case check_config(changing, NewConfig) of
Result = {ok,NewConfig1} ->
try gen_server:call(Name, {change_config,OldConfig,NewConfig1},
?DEFAULT_CALL_TIMEOUT) of
@@ -166,9 +165,7 @@ changing_config1(Name, OldConfig, NewConfig) ->
Error
end.
-check_config(adding, Name, Config0) ->
- %% Merge in defaults on top level
- Config = maps:merge(#{id => Name}, Config0),
+check_config(adding, Config) ->
%% Merge in defaults on handler level
MyConfig0 = maps:get(?MODULE, Config, #{}),
MyConfig = maps:merge(#{type => standard_io},
@@ -179,7 +176,7 @@ check_config(adding, Name, Config0) ->
Error ->
Error
end;
-check_config(changing, _Name, Config) ->
+check_config(changing, Config) ->
MyConfig = maps:get(?MODULE, Config, #{}),
case check_my_config(maps:to_list(MyConfig)) of
ok -> {ok,Config};
@@ -207,7 +204,7 @@ check_my_config([]) ->
%%%-----------------------------------------------------------------
%%% Handler being removed
-removing_handler(Name,_Config) ->
+removing_handler(#{id:=Name}) ->
stop(Name).
%%%-----------------------------------------------------------------
@@ -222,15 +219,15 @@ swap_buffer(Name,Buffer) ->
%%%-----------------------------------------------------------------
%%% Log a string or report
--spec log(Log, Config) -> ok | dropped when
- Log :: logger:log(),
+-spec log(LogEvent, Config) -> ok | dropped when
+ LogEvent :: logger:log_event(),
Config :: logger:config().
-log(Log,Config=#{id:=Name}) ->
+log(LogEvent,Config=#{id:=Name}) ->
%% if the handler has crashed, we must drop this request
%% and hope the handler restarts so we can try again
true = is_pid(whereis(Name)),
- Bin = logger_h_common:log_to_binary(Log,Config),
+ Bin = logger_h_common:log_to_binary(LogEvent,Config),
logger_h_common:call_cast_or_drop(Name, Bin).
%%%===================================================================