比较提交

...

33 次代码提交

作者 SHA1 备注 提交日期
  Andrew Thompson 244463e954 logger_std_h supports file rotation better than disk_log, so use that 5 年前
  Andrew Thompson 67466436aa Rework logger configuration and add logger config generator 5 年前
  Andrew Thompson c62732dab3 WIP function to turn lager config into logger config 5 年前
  Andrew Thompson 0dff911051 Add some docs 5 年前
  Andrew Thompson 0803df0620 How the heck did this slip in? 5 年前
  Andrew Thompson 3c275e4399 Use better function 6 年前
  Andrew Thompson 3d38191cee Fix 6 年前
  Andrew Thompson 225990798f Fix 6 年前
  Andrew Thompson 60f6b38842 Typo 6 年前
  Andrew Thompson 566d0f386b Fix 6 年前
  Andrew Thompson 7af01ccab7 Try to supress log messages better 6 年前
  Andrew Thompson ce11e41ea9 Use report_cb from config or from metadata 6 年前
  Andrew Thompson 7b8d2c5424 More fighting with report_cb 6 年前
  Andrew Thompson 5667c95ba0 Try to switch to using a report_cb 6 年前
  Andrew Thompson 0e07296df7 Add application stops 6 年前
  Andrew Thompson 24651deb76 Use the right key names 6 年前
  Andrew Thompson 0ba40a2d40 Add application start 6 年前
  Andrew Thompson 7e247dc761 Typo: 6 年前
  Andrew Thompson 8ac924b748 Debugging 6 年前
  Andrew Thompson 9ed7ee8f69 Add supervisor error reports 6 年前
  Andrew Thompson 4f8d24513d Feh 6 年前
  Andrew Thompson 9b8ee2342c Honor supervisor message suppression config 6 年前
  Andrew Thompson c793c030d0 Tweak 6 年前
  Andrew Thompson 0176941b90 Fallback for unhandled reports 6 年前
  Andrew Thompson 8a2cf8d5a8 Add some formatters for the standard OTP reports 6 年前
  Andrew Thompson e53ecb0fe5 Typo 6 年前
  Andrew Thompson 0970513d2d Clear colors at end of line 6 年前
  Andrew Thompson 62d95d24f7 Add a module to convert logger formatters to lager formatters 6 年前
  Andrew Thompson ad25bf8311 Add an env var to stop lager actually booting 6 年前
  Andrew Thompson a68e456aa2 Backwards 6 年前
  Andrew Thompson 7aaad5ca15 Handle log messages with no format arguments 6 年前
  Andrew Thompson f1c7e3ad11 Couple fixes 6 年前
  Andrew Thompson e1c4ed1139 Add a `lager_use_logger` parse transform to rewrite lager calls to logger 6 年前
共有 6 个文件被更改,包括 401 次插入104 次删除
  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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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(_, _) ->

正在加载...
取消
保存