Confronta commit

...

Autore SHA1 Messaggio Data
  Andrew Thompson 244463e954 logger_std_h supports file rotation better than disk_log, so use that 5 anni fa
  Andrew Thompson 67466436aa Rework logger configuration and add logger config generator 5 anni fa
  Andrew Thompson c62732dab3 WIP function to turn lager config into logger config 5 anni fa
  Andrew Thompson 0dff911051 Add some docs 5 anni fa
  Andrew Thompson 0803df0620 How the heck did this slip in? 5 anni fa
  Andrew Thompson 3c275e4399 Use better function 6 anni fa
  Andrew Thompson 3d38191cee Fix 6 anni fa
  Andrew Thompson 225990798f Fix 6 anni fa
  Andrew Thompson 60f6b38842 Typo 6 anni fa
  Andrew Thompson 566d0f386b Fix 6 anni fa
  Andrew Thompson 7af01ccab7 Try to supress log messages better 6 anni fa
  Andrew Thompson ce11e41ea9 Use report_cb from config or from metadata 6 anni fa
  Andrew Thompson 7b8d2c5424 More fighting with report_cb 6 anni fa
  Andrew Thompson 5667c95ba0 Try to switch to using a report_cb 6 anni fa
  Andrew Thompson 0e07296df7 Add application stops 6 anni fa
  Andrew Thompson 24651deb76 Use the right key names 6 anni fa
  Andrew Thompson 0ba40a2d40 Add application start 6 anni fa
  Andrew Thompson 7e247dc761 Typo: 6 anni fa
  Andrew Thompson 8ac924b748 Debugging 6 anni fa
  Andrew Thompson 9ed7ee8f69 Add supervisor error reports 6 anni fa
  Andrew Thompson 4f8d24513d Feh 6 anni fa
  Andrew Thompson 9b8ee2342c Honor supervisor message suppression config 6 anni fa
  Andrew Thompson c793c030d0 Tweak 6 anni fa
  Andrew Thompson 0176941b90 Fallback for unhandled reports 6 anni fa
  Andrew Thompson 8a2cf8d5a8 Add some formatters for the standard OTP reports 6 anni fa
  Andrew Thompson e53ecb0fe5 Typo 6 anni fa
  Andrew Thompson 0970513d2d Clear colors at end of line 6 anni fa
  Andrew Thompson 62d95d24f7 Add a module to convert logger formatters to lager formatters 6 anni fa
  Andrew Thompson ad25bf8311 Add an env var to stop lager actually booting 6 anni fa
  Andrew Thompson a68e456aa2 Backwards 6 anni fa
  Andrew Thompson 7aaad5ca15 Handle log messages with no format arguments 6 anni fa
  Andrew Thompson f1c7e3ad11 Couple fixes 6 anni fa
  Andrew Thompson e1c4ed1139 Add a `lager_use_logger` parse transform to rewrite lager calls to logger 6 anni fa
6 ha cambiato i file con 401 aggiunte e 104 eliminazioni
  1. +63
    -0
      README.md
  2. +61
    -1
      src/lager.erl
  3. +21
    -6
      src/lager_app.erl
  4. +119
    -0
      src/lager_logger_formatter.erl
  5. +23
    -18
      src/lager_sup.erl
  6. +114
    -79
      src/lager_transform.erl

+ 63
- 0
README.md Vedi File

@ -1138,6 +1138,69 @@ Example Usage:
:lager.warning('Some message with a term: ~p', [term])
```
Integration with OTP's Logger
-----------------------------
Now that OTP includes a modern log event pipeline, the Lager project has decided
to work on winding down Lager development in favor of unifying the Erlang
ecosystem behind Logger. To that end, Lager now supports being configured to use
its parse transform to rewrite lager calls into logger calls. To enable this
mode, the following changes are required:
In sys.config:
```
[
{kernel,
[{logger,
[{handler, default, logger_std_h,
#{formatter => {lager_logger_formatter, #{report_cb => fun lager_logger_formatter:report_cb/1}}}},
]}]},
...
{lager, [
{lager_use_logger, true},
...
]}
]
```
The logger stanza changes are not needed if you wish to use logger's default
formatter.
In your applications top level rebar.config (probably requires rebar3):
```
{overrides, [{add, [{erl_opts, [{lager_use_logger, true}]}]}]}.
```
This will force the parse transform configuration to apply to all the
dependencies as well. Make sure you've defined the lager version in your
toplevel application's rebar.config and that the version is high enough to
support these options. A toplevel dependency will override any lager
dependencies in any of your application's dependencies and thus ensure the parse
transform is the right version.
To generate a logger configuration from your lager configuration you can do:
```
lager:generate_logger_configuration()
```
If you wish to simply use your existing lager configuration as is, and have
lager configure logger you can, in your sys.config in the lager stanza:
```
{lager, [
{configure_logger, true},
...
]}
```
Alternatively you can use:
```
lager:configure_logger()
```
3.x Changelog
-------------
3.6.8 - 21 December 2018

+ 61
- 1
src/lager.erl Vedi File

@ -36,7 +36,8 @@
get_loglevel/1, get_loglevel/2, set_loglevel/2, set_loglevel/3, set_loglevel/4, get_loglevels/1,
update_loglevel_config/1, posix_error/1, set_loghwm/2, set_loghwm/3, set_loghwm/4,
safe_format/3, safe_format_chop/3, unsafe_format/2, dispatch_log/5, dispatch_log/7, dispatch_log/9,
do_log/9, do_log/10, do_log_unsafe/10, pr/2, pr/3, pr_stacktrace/1, pr_stacktrace/2]).
do_log/9, do_log/10, do_log_unsafe/10, pr/2, pr/3, pr_stacktrace/1, pr_stacktrace/2,
generate_logger_config/0, configure_logger/0]).
-type log_level() :: none | debug | info | notice | warning | error | critical | alert | emergency.
-type log_level_number() :: 0..7.
@ -689,6 +690,65 @@ rotate_handler(Handler) ->
rotate_handler(Handler, Sink) ->
gen_event:call(Sink, Handler, rotate, ?ROTATE_TIMEOUT).
generate_logger_config() ->
Handlers = application:get_env(lager, handlers, lager_app:default_handlers()),
{Level, NewHandlers} = generate_logger_handlers(Handlers, {notice, []}),
{kernel, [{logger_level, Level}, {logger, NewHandlers}]}.
configure_logger() ->
Handlers = application:get_env(lager, handlers, lager_app:default_handlers()),
WhitelistedLoggerHandlers = application:get_env(lager, whitelisted_logger_handlers, []),
[ ok = logger:remove_handler(Id) || #{id := Id} <- logger:get_handler_config(), not lists:member(Id, WhitelistedLoggerHandlers) ],
{Level, NewHandlers} = generate_logger_handlers(Handlers, {notice, []}),
logger:set_primary_config(maps:merge(logger:get_primary_config(), #{level => Level})),
[ ok = logger:add_handler(HandlerId, HandlerModule, HandlerConfig) || {handler, HandlerId, HandlerModule, HandlerConfig} <- NewHandlers ],
ok.
generate_logger_handlers([], Acc) ->
Acc;
generate_logger_handlers([{lager_console_backend, Config}|Tail], {CurrentLevel, Acc}) ->
Level = proplists:get_value(level, Config, info),
Formatter = proplists:get_value(formatter, Config, lager_default_formatter),
FormatterConfig = proplists:get_value(formatter_config, Config, []),
Handler = {handler, console, logger_std_h, #{level => Level, formatter =>
{lager_logger_formatter, #{report_cb => fun lager_logger_formatter:report_cb/1,
formatter => Formatter,
formatter_config => FormatterConfig}}}},
NewLevel = case lager_util:level_to_num(Level) > lager_util:level_to_num(CurrentLevel) of
true ->
Level;
false ->
CurrentLevel
end,
generate_logger_handlers(Tail, {NewLevel, [Handler|Acc]});
generate_logger_handlers([{lager_file_backend, Config}|Tail], {CurrentLevel, Acc}) ->
Level = proplists:get_value(level, Config, info),
File = proplists:get_value(file, Config),
LogRoot = application:get_env(lager, log_root, ""),
Size = proplists:get_value(size, Config, 10485760),
Count = proplists:get_value(count, Config, 5),
Formatter = proplists:get_value(formatter, Config, lager_default_formatter),
FormatterConfig = proplists:get_value(formatter_config, Config, []),
%% the standard log handler has a file mode with size based rotation support that is much saner than
%% disk_log's, so use that here
Handler = {handler, list_to_atom(File), logger_std_h, #{level => Level,
config => #{type => file,
file => filename:join(LogRoot, File),
max_no_files => Count,
max_no_bytes => Size},
formatter =>
{lager_logger_formatter, #{report_cb => fun lager_logger_formatter:report_cb/1,
formatter => Formatter,
formatter_config => FormatterConfig}}}},
NewLevel = case lager_util:level_to_num(Level) > lager_util:level_to_num(CurrentLevel) of
true ->
Level;
false ->
CurrentLevel
end,
generate_logger_handlers(Tail, {NewLevel, [Handler|Acc]}).
%% @private
trace_func(#trace_func_state_v1{pid=Pid, level=Level, format_string=Fmt}=FuncState, Event, ProcState) ->
lager:log(Level, Pid, Fmt, [Event, ProcState]),

+ 21
- 6
src/lager_app.erl Vedi File

@ -31,7 +31,8 @@
start_handler/3,
configure_sink/2,
stop/1,
boot/1]).
boot/1,
default_handlers/0]).
%% The `application:get_env/3` compatibility wrapper was useful
%% for other modules in r15 and before
@ -226,11 +227,22 @@ get_env(Application, Key, Default) ->
start(_StartType, _StartArgs) ->
{ok, Pid} = lager_sup:start_link(),
SavedHandlers = boot(),
_ = boot('__all_extra'),
_ = boot('__traces'),
clean_up_config_checks(),
{ok, Pid, SavedHandlers}.
case application:get_env(lager, lager_use_logger, false) of
false ->
SavedHandlers = boot(),
_ = boot('__all_extra'),
_ = boot('__traces'),
clean_up_config_checks(),
{ok, Pid, SavedHandlers};
true ->
case application:get_env(lager, configure_logger, false) of
true ->
ok = lager:configure_logger();
false ->
ok
end,
{ok, Pid}
end.
boot() ->
%% Handle the default sink.
@ -276,6 +288,9 @@ stop(Handlers) ->
error_logger:add_report_handler(Handler)
end, Handlers).
default_handlers() ->
?DEFAULT_HANDLER_CONF.
expand_handlers([]) ->
[];
expand_handlers([{lager_file_backend, [{Key, _Value}|_]=Config}|T]) when is_atom(Key) ->

+ 119
- 0
src/lager_logger_formatter.erl Vedi File

@ -0,0 +1,119 @@
-module(lager_logger_formatter).
%% convert logger formatter calls into lager formatter ones
-export([report_cb/1, format/2]).%, check_config/1]).
report_cb(#{label := {gen_server, terminate}, name := Name, reason := Reason}) ->
Formatted = error_logger_lager_h:format_reason(Reason),
{"gen_server ~w terminated with reason: ~s", [Name, Formatted]};
report_cb(#{label := {gen_fsm, terminate}, name := Name, state_name := StateName, reason := Reason}) ->
Formatted = error_logger_lager_h:format_reason(Reason),
{"gen_fsm ~w in state ~w terminated with reason: ~s", [Name, StateName, Formatted]};
report_cb(#{label := {gen_event, terminate}, name := Name, handler := Handler, reason := Reason}) ->
Formatted = error_logger_lager_h:format_reason(Reason),
{"gen_event ~w installed in ~w terminated with reason: ~s", [Handler, Name, Formatted]};
report_cb(#{label := {gen_statem, terminate}, name := Name, reason := Reason}) ->
Formatted = error_logger_lager_h:format_reason(Reason),
%% XXX I can't find the FSM statename in the error report, maybe it should be added
{"gen_statem ~w terminated with reason: ~s", [Name, Formatted]};
report_cb(#{msg := {report, #{label := {Behaviour, no_handle_info}, mod := Mod, msg := Msg}}}) ->
{"undefined handle_info for ~p in ~s ~p", [Msg, Behaviour, Mod]};
report_cb(#{label := {supervisor, progress}, report := Report}) ->
case application:get_env(lager, suppress_supervisor_start_stop, false) of
true ->
{"", []};
false ->
{supervisor, Name} = lists:keyfind(supervisor, 1, Report),
{started, Started} = lists:keyfind(started, 1, Report),
case lists:keyfind(id, 1, Started) of
false ->
%% supervisor itself starting
{mfa, {Module, Function, Args}} = lists:keyfind(mfa, 1, Started),
{pid, Pid} = lists:keyfind(pid, 1, Started),
{"Supervisor ~w started as ~p at pid ~w", [Name, error_logger_lager_h:format_mfa({Module, Function, Args}), Pid]};
{id, ChildID} ->
case lists:keyfind(pid, 1, Started) of
{pid, Pid} ->
{"Supervisor ~w started child ~p at pid ~w", [Name, ChildID, Pid]};
false ->
%% children is a list of pids for some reason? and we only get the count
{nb_children, ChildCount} = lists:keyfind(nb_children, 1, Started),
{"Supervisor ~w started ~b children ~p", [Name, ChildCount, ChildID]}
end
end
end;
report_cb(#{label := {supervisor, _Error}, report := Report}) ->
{supervisor, Name} = lists:keyfind(supervisor, 1, Report),
{reason, Reason} = lists:keyfind(reason, 1, Report),
Formatted = error_logger_lager_h:format_reason(Reason),
{errorContext, ErrorContext} = lists:keyfind(errorContext, 1, Report),
{offender, Offender} = lists:keyfind(offender, 1, Report),
case lists:keyfind(mod, 1, Offender) of
{mod, _Mod} ->
{pid, Pid} = lists:keyfind(pid, 1, Offender),
%% this comes from supervisor_bridge
{"Supervisor ~w had ~p ~p with reason ~s", [Name, Pid, ErrorContext, Formatted]};
false ->
{id, ChildID} = lists:keyfind(id, 1, Offender),
case lists:keyfind(pid, 1, Offender) of
{pid, Pid} ->
{"Supervisor ~w had ~p ~p ~p with reason ~s", [Name, ChildID, Pid, ErrorContext, Formatted]};
false ->
{"Supervisor ~w had ~p ~p with reason ~s", [Name, ChildID, ErrorContext, Formatted]}
end
end;
report_cb(#{label := {application_controller, progress}, report := Report}) ->
case application:get_env(lager, suppress_application_start_stop, false) of
true -> {"", []};
false ->
{application, Name} = lists:keyfind(application, 1, Report),
{started_at, Node} = lists:keyfind(started_at, 1, Report),
{"Application ~w started on node ~w", [Name, Node]}
end;
report_cb(#{label := {application_controller, exit}, report := Report}) ->
{exited, Reason} = lists:keyfind(exited, 1, Report),
case application:get_env(lager, suppress_application_start_stop) of
{ok, true} when Reason == stopped ->
{"", []};
_ ->
{application, Name} = lists:keyfind(application, 1, Report),
Formatted = error_logger_lager_h:format_reason(Reason),
{"Application ~w exited with reason: ~s", [Name, Formatted]}
end.
%% TODO handle proc_lib crash
format(#{msg := {report, _Report}, meta := Metadata} = Event, #{report_cb := Fun} = Config) when is_function(Fun, 1); is_function(Fun, 2) ->
format(Event#{meta => Metadata#{report_cb => Fun}}, maps:remove(report_cb, Config));
format(#{level := _Level, msg := {report, Report}, meta := #{report_cb := Fun}} = Event, Config) when is_function(Fun, 1) ->
case Fun(Report) of
{"", []} -> "";
{Format, Args} when is_list(Format), is_list(Args) ->
format(Event#{msg => {Format, Args}}, Config)
end;
format(#{level := Level, msg := {string, String}, meta := Metadata}, Config) ->
do_format(Level, String, Metadata, Config);
format(#{level := Level, msg := {FmtStr, FmtArgs}, meta := Metadata}, Config) ->
Msg = lager_format:format(FmtStr, FmtArgs, maps:get(max_size, Config, 1024)),
do_format(Level, Msg, Metadata, Config).
do_format(Level, Msg, Metadata, Config) ->
FormatModule = maps:get(formatter, Config, lager_default_formatter),
Timestamp = maps:get(time, Metadata),
MegaSecs = Timestamp div 1000000000000,
Secs = (Timestamp rem 1000000000000) div 1000000,
MicroSecs = (Timestamp rem 1000000000000) rem 1000000,
{Colors, End} = case maps:get(colors, Config, false) of
true ->
{application:get_env(lager, colors, []), "\e[0m"};
false ->
{[], ""}
end,
[FormatModule:format(lager_msg:new(Msg, {MegaSecs, Secs, MicroSecs}, Level, convert_metadata(Metadata), []), maps:get(formatter_config, Config, []), Colors), End].
convert_metadata(Metadata) ->
maps:fold(fun(mfa, {Module, Function, Arity}, Acc) ->
[{module, Module}, {function, Function}, {arity, Arity}|Acc];
(K, V, Acc) ->
[{K, V}|Acc]
end, [], Metadata).

+ 23
- 18
src/lager_sup.erl Vedi File

@ -32,24 +32,29 @@ start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
%% set up the config, is safe even during relups
lager_config:new(),
%% TODO:
%% Always start lager_event as the default and make sure that
%% other gen_event stuff can start up as needed
%%
%% Maybe a new API to handle the sink and its policy?
Children = [
{lager, {gen_event, start_link, [{local, lager_event}]},
permanent, 5000, worker, dynamic},
{lager_handler_watcher_sup, {lager_handler_watcher_sup, start_link, []},
permanent, 5000, supervisor, [lager_handler_watcher_sup]}],
CrashLog = decide_crash_log(application:get_env(lager, crash_log, false)),
{ok, {{one_for_one, 10, 60},
Children ++ CrashLog
}}.
case application:get_env(lager, lager_use_logger, false) of
true ->
{ok, {{one_for_one, 10, 60}, []}};
false ->
%% set up the config, is safe even during relups
lager_config:new(),
%% TODO:
%% Always start lager_event as the default and make sure that
%% other gen_event stuff can start up as needed
%%
%% Maybe a new API to handle the sink and its policy?
Children = [
{lager, {gen_event, start_link, [{local, lager_event}]},
permanent, 5000, worker, dynamic},
{lager_handler_watcher_sup, {lager_handler_watcher_sup, start_link, []},
permanent, 5000, supervisor, [lager_handler_watcher_sup]}],
CrashLog = decide_crash_log(application:get_env(lager, crash_log, false)),
{ok, {{one_for_one, 10, 60},
Children ++ CrashLog
}}
end.
validate_positive({ok, Val}, _Default) when is_integer(Val) andalso Val >= 0 ->
Val;

+ 114
- 79
src/lager_transform.erl Vedi File

@ -33,10 +33,12 @@ parse_transform(AST, Options) ->
Enable = proplists:get_value(lager_print_records_flag, Options, true),
Sinks = [lager] ++ proplists:get_value(lager_extra_sinks, Options, []),
Functions = proplists:get_value(lager_function_transforms, Options, []),
UseLogger = proplists:get_value(lager_use_logger, Options, false),
put(print_records_flag, Enable),
put(truncation_size, TruncSize),
put(sinks, Sinks),
put(functions, lists:keysort(1, Functions)),
put(use_logger, UseLogger),
erlang:put(records, []),
%% .app file should either be in the outdir, or the same dir as the source file
guess_application(proplists:get_value(outdir, Options), hd(AST)),
@ -63,6 +65,7 @@ walk_ast(Acc, [{attribute, _, lager_function_transforms, FromModule }=H|T]) ->
walk_ast([H|Acc], T);
walk_ast(Acc, [{function, Line, Name, Arity, Clauses}|T]) ->
put(function, Name),
put(arity, Arity),
walk_ast([{function, Line, Name, Arity,
walk_clauses([], Clauses)}|Acc], T);
walk_ast(Acc, [{attribute, _, record, {Name, Fields}}=H|T]) ->
@ -140,24 +143,40 @@ do_transform(Line, SinkName, Severity, Arguments0) ->
do_transform(Line, SinkName, Severity, Arguments0, safe).
do_transform(Line, SinkName, Severity, Arguments0, Safety) ->
SeverityAsInt=lager_util:level_to_num(Severity),
DefaultAttrs0 = {cons, Line, {tuple, Line, [
{atom, Line, module}, {atom, Line, get(module)}]},
{cons, Line, {tuple, Line, [
{atom, Line, function}, {atom, Line, get(function)}]},
{cons, Line, {tuple, Line, [
{atom, Line, line},
{integer, Line, Line}]},
{cons, Line, {tuple, Line, [
{atom, Line, pid},
{call, Line, {atom, Line, pid_to_list}, [
{call, Line, {atom, Line ,self}, []}]}]},
{cons, Line, {tuple, Line, [
{atom, Line, node},
{call, Line, {atom, Line, node}, []}]},
%% get the metadata with lager:md(), this will always return a list so we can use it as the tail here
{call, Line, {remote, Line, {atom, Line, lager}, {atom, Line, md}}, []}}}}}},
%{nil, Line}}}}}}},
DefaultAttrs0 = case get(use_logger) of
true ->
{cons, Line, {tuple, Line, [
{atom, Line, pid}, {call, Line, {atom, Line, self}, []}]},
{cons, Line, {tuple, Line, [
{atom, Line, gl}, {call, Line, {atom, Line, group_leader}, []}]},
{cons, Line, {tuple, Line, [
{atom, Line, time}, {call, Line, {remote, Line, {atom, Line, erlang}, {atom, Line, system_time}}, [{atom, Line, microsecond}]}]},
{cons, Line, {tuple, Line, [
{atom, Line, mfa}, {tuple, Line, [{atom, Line, get(module)}, {atom, Line, get(function)}, {atom, Line, get(arity)}]}]},
{cons, Line, {tuple, Line, [
{atom, Line, file}, {string, Line, get(filename)}]},
{cons, Line, {tuple, Line, [
{atom, Line, line}, {integer, Line, Line}]},
%% get the metadata with lager:md(), this will always return a list so we can use it as the tail here
{call, Line, {remote, Line, {atom, Line, lager}, {atom, Line, md}}, []}}}}}}};
false ->
{cons, Line, {tuple, Line, [
{atom, Line, module}, {atom, Line, get(module)}]},
{cons, Line, {tuple, Line, [
{atom, Line, function}, {atom, Line, get(function)}]},
{cons, Line, {tuple, Line, [
{atom, Line, line},
{integer, Line, Line}]},
{cons, Line, {tuple, Line, [
{atom, Line, pid},
{call, Line, {atom, Line, pid_to_list}, [
{call, Line, {atom, Line ,self}, []}]}]},
{cons, Line, {tuple, Line, [
{atom, Line, node},
{call, Line, {atom, Line, node}, []}]},
%% get the metadata with lager:md(), this will always return a list so we can use it as the tail here
{call, Line, {remote, Line, {atom, Line, lager}, {atom, Line, md}}, []}}}}}}
end,
Functions = get(functions),
DefaultAttrs1 = add_function_transforms(Line, DefaultAttrs0, Functions),
DefaultAttrs = case erlang:get(application) of
@ -171,67 +190,82 @@ do_transform(Line, SinkName, Severity, Arguments0, Safety) ->
{nil, Line}}, DefaultAttrs1)
end,
{Meta, Message, Arguments} = handle_args(DefaultAttrs, Line, Arguments0),
%% Generate some unique variable names so we don't accidentally export from case clauses.
%% Note that these are not actual atoms, but the AST treats variable names as atoms.
LevelVar = make_varname("__Level", Line),
TracesVar = make_varname("__Traces", Line),
PidVar = make_varname("__Pid", Line),
LogFun = case Safety of
safe ->
do_log;
unsafe ->
do_log_unsafe
end,
%% Wrap the call to lager:dispatch_log/6 in case that will avoid doing any work if this message is not elegible for logging
%% See lager.erl (lines 89-100) for lager:dispatch_log/6
%% case {whereis(Sink), whereis(?DEFAULT_SINK), lager_config:get({Sink, loglevel}, {?LOG_NONE, []})} of
{'case',Line,
{tuple,Line,
[{call,Line,{atom,Line,whereis},[{atom,Line,SinkName}]},
{call,Line,{atom,Line,whereis},[{atom,Line,?DEFAULT_SINK}]},
{call,Line,
{remote,Line,{atom,Line,lager_config},{atom,Line,get}},
[{tuple,Line,[{atom,Line,SinkName},{atom,Line,loglevel}]},
{tuple,Line,[{integer,Line,0},{nil,Line}]}]}]},
%% {undefined, undefined, _} -> {error, lager_not_running};
[{clause,Line,
[{tuple,Line,
[{atom,Line,undefined},{atom,Line,undefined},{var,Line,'_'}]}],
[],
%% trick the linter into avoiding a 'term constructed but not used' error:
%% (fun() -> {error, lager_not_running} end)()
[{call, Line, {'fun', Line, {clauses, [{clause, Line, [],[], [{tuple, Line, [{atom, Line, error},{atom, Line, lager_not_running}]}]}]}}, []}]
},
%% {undefined, _, _} -> {error, {sink_not_configured, Sink}};
{clause,Line,
[{tuple,Line,
[{atom,Line,undefined},{var,Line,'_'},{var,Line,'_'}]}],
[],
%% same trick as above to avoid linter error
[{call, Line, {'fun', Line, {clauses, [{clause, Line, [],[], [{tuple,Line, [{atom,Line,error}, {tuple,Line,[{atom,Line,sink_not_configured},{atom,Line,SinkName}]}]}]}]}}, []}]
},
%% {SinkPid, _, {Level, Traces}} when ... -> lager:do_log/9;
{clause,Line,
[{tuple,Line,
[{var,Line,PidVar},
{var,Line,'_'},
{tuple,Line,[{var,Line,LevelVar},{var,Line,TracesVar}]}]}],
[[{op, Line, 'orelse',
{op, Line, '/=', {op, Line, 'band', {var, Line, LevelVar}, {integer, Line, SeverityAsInt}}, {integer, Line, 0}},
{op, Line, '/=', {var, Line, TracesVar}, {nil, Line}}}]],
[{call,Line,{remote, Line, {atom, Line, lager}, {atom, Line, LogFun}},
[{atom,Line,Severity},
Meta,
Message,
Arguments,
{integer, Line, get(truncation_size)},
{integer, Line, SeverityAsInt},
{var, Line, LevelVar},
{var, Line, TracesVar},
{atom, Line, SinkName},
{var, Line, PidVar}]}]},
%% _ -> ok
{clause,Line,[{var,Line,'_'}],[],[{atom,Line,ok}]}]}.
case get(use_logger) of
true ->
case Arguments of
{atom, _, none} ->
%% logger:log(Level, Format, Args, Metadata)
{call,Line,{remote, Line, {atom, Line, logger}, {atom, Line, log}},
[{atom,Line,Severity}, Message, {call, Line, {remote, Line, {atom, Line, maps}, {atom, Line, from_list}}, [Meta]}]};
_ ->
%% logger:log(Level, String, Metadata)
{call,Line,{remote, Line, {atom, Line, logger}, {atom, Line, log}},
[{atom,Line,Severity}, Message, Arguments, {call, Line, {remote, Line, {atom, Line, maps}, {atom, Line, from_list}}, [Meta]}]}
end;
false ->
SeverityAsInt=lager_util:level_to_num(Severity),
%% Generate some unique variable names so we don't accidentally export from case clauses.
%% Note that these are not actual atoms, but the AST treats variable names as atoms.
LevelVar = make_varname("__Level", Line),
TracesVar = make_varname("__Traces", Line),
PidVar = make_varname("__Pid", Line),
LogFun = case Safety of
safe ->
do_log;
unsafe ->
do_log_unsafe
end,
%% Wrap the call to lager:dispatch_log/6 in case that will avoid doing any work if this message is not elegible for logging
%% See lager.erl (lines 89-100) for lager:dispatch_log/6
%% case {whereis(Sink), whereis(?DEFAULT_SINK), lager_config:get({Sink, loglevel}, {?LOG_NONE, []})} of
{'case',Line,
{tuple,Line,
[{call,Line,{atom,Line,whereis},[{atom,Line,SinkName}]},
{call,Line,{atom,Line,whereis},[{atom,Line,?DEFAULT_SINK}]},
{call,Line,
{remote,Line,{atom,Line,lager_config},{atom,Line,get}},
[{tuple,Line,[{atom,Line,SinkName},{atom,Line,loglevel}]},
{tuple,Line,[{integer,Line,0},{nil,Line}]}]}]},
%% {undefined, undefined, _} -> {error, lager_not_running};
[{clause,Line,
[{tuple,Line,
[{atom,Line,undefined},{atom,Line,undefined},{var,Line,'_'}]}],
[],
%% trick the linter into avoiding a 'term constructed but not used' error:
%% (fun() -> {error, lager_not_running} end)()
[{call, Line, {'fun', Line, {clauses, [{clause, Line, [],[], [{tuple, Line, [{atom, Line, error},{atom, Line, lager_not_running}]}]}]}}, []}]
},
%% {undefined, _, _} -> {error, {sink_not_configured, Sink}};
{clause,Line,
[{tuple,Line,
[{atom,Line,undefined},{var,Line,'_'},{var,Line,'_'}]}],
[],
%% same trick as above to avoid linter error
[{call, Line, {'fun', Line, {clauses, [{clause, Line, [],[], [{tuple,Line, [{atom,Line,error}, {tuple,Line,[{atom,Line,sink_not_configured},{atom,Line,SinkName}]}]}]}]}}, []}]
},
%% {SinkPid, _, {Level, Traces}} when ... -> lager:do_log/9;
{clause,Line,
[{tuple,Line,
[{var,Line,PidVar},
{var,Line,'_'},
{tuple,Line,[{var,Line,LevelVar},{var,Line,TracesVar}]}]}],
[[{op, Line, 'orelse',
{op, Line, '/=', {op, Line, 'band', {var, Line, LevelVar}, {integer, Line, SeverityAsInt}}, {integer, Line, 0}},
{op, Line, '/=', {var, Line, TracesVar}, {nil, Line}}}]],
[{call,Line,{remote, Line, {atom, Line, lager}, {atom, Line, LogFun}},
[{atom,Line,Severity},
Meta,
Message,
Arguments,
{integer, Line, get(truncation_size)},
{integer, Line, SeverityAsInt},
{var, Line, LevelVar},
{var, Line, TracesVar},
{atom, Line, SinkName},
{var, Line, PidVar}]}]},
%% _ -> ok
{clause,Line,[{var,Line,'_'}],[],[{atom,Line,ok}]}]}
end.
handle_args(DefaultAttrs, Line, [{cons, LineNum, {tuple, _, _}, _} = Attrs]) ->
{concat_lists(DefaultAttrs, Attrs), {string, LineNum, ""}, {atom, Line, none}};
@ -317,6 +351,7 @@ guess_application(Dirname, Attr) when Dirname /= undefined ->
ok
end;
guess_application(undefined, {attribute, _, file, {Filename, _}}) ->
put(filename, Filename),
Dir = filename:dirname(Filename),
find_app_file(Dir);
guess_application(_, _) ->

Caricamento…
Annulla
Salva