Permalink
Browse files

Merge pull request #121 from basho/adt-pdict-metadata

Allow storage of persistant per-process lager metadata
  • Loading branch information...
2 parents 7af4330 + 98143ae commit 997f8e9b312fa4240eb79ede5e92c360f1a20b5c @Vagabond Vagabond committed Mar 19, 2013
Showing with 59 additions and 2 deletions.
  1. +28 −0 src/lager.erl
  2. +4 −2 src/lager_transform.erl
  3. +27 −0 test/lager_test_backend.erl
View
@@ -20,9 +20,12 @@
-include("lager.hrl").
+-define(LAGER_MD_KEY, '__lager_metadata').
+
%% API
-export([start/0,
log/3, log/4,
+ md/0, md/1,
trace/2, trace/3, trace_file/2, trace_file/3, trace_console/1, trace_console/2,
clear_all_traces/0, stop_trace/1, status/0,
get_loglevel/1, set_loglevel/2, set_loglevel/3, get_loglevels/0,
@@ -51,6 +54,31 @@ start_ok(App, {error, {not_started, Dep}}) ->
start_ok(App, {error, Reason}) ->
erlang:error({app_start_failed, App, Reason}).
+%% @doc Get lager metadata for current process
+-spec md() -> [{atom(), any()}].
+md() ->
+ case erlang:get(?LAGER_MD_KEY) of
+ undefined -> [];
+ MD -> MD
+ end.
+
+%% @doc Set lager metadata for current process.
+%% Will badarg if you don't supply a list of {key, value} tuples keyed by atoms.
+-spec md([{atom(), any()},...]) -> ok.
+md(NewMD) when is_list(NewMD) ->
+ %% make sure its actually a real proplist
+ case lists:all(
+ fun({Key, _Value}) when is_atom(Key) -> true;
+ (_) -> false
+ end, NewMD) of
+ true ->
+ erlang:put(?LAGER_MD_KEY, NewMD),
+ ok;
+ false ->
+ erlang:error(badarg)
+ end;
+md(_) ->
+ erlang:error(badarg).
-spec dispatch_log(log_level(), list(), string(), list() | none, pos_integer()) -> ok | {error, lager_not_running}.
%% this is the same check that the parse transform bakes into the module at compile time
View
@@ -89,7 +89,9 @@ transform_statement({call, Line, {remote, _Line1, {atom, _Line2, lager},
{cons, Line, {tuple, Line, [
{atom, Line, node},
{call, Line, {atom, Line, node}, []}]},
- {nil, 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}}, []}}}}}},
+ %{nil, Line}}}}}}},
DefaultAttrs = case erlang:get(application) of
undefined ->
DefaultAttrs0;
@@ -151,7 +153,7 @@ transform_statement({call, Line, {remote, _Line1, {atom, _Line2, lager},
[],
%% trick the linter into avoiding a 'term constructed by not used' error:
%% (fun() -> {error, lager_not_running} end)();
- [{call,9, {'fun',9, {clauses, [{clause,9,[],[], [{tuple,9,[{atom,9,error},{atom,9,lager_not_running}]}]}]}}, []}]},
+ [{call, Line, {'fun', Line, {clauses, [{clause, Line, [],[], [{tuple, Line, [{atom, Line, error},{atom, Line, lager_not_running}]}]}]}}, []}]},
%% If we care about the loglevel, or there's any traces installed, we have do more checking
%% {Level, Traces} when (Level band SeverityAsInt) /= 0 orelse Traces /= [] ->
{clause, Line,
@@ -424,6 +424,33 @@ lager_test_() ->
?assertEqual({?DEBUG bor ?INFO bor ?NOTICE bor ?WARNING bor ?ERROR bor ?CRITICAL bor ?ALERT bor ?EMERGENCY, []}, lager_config:get(loglevel)),
ok
end
+ },
+ {"metadata in the process dictionary works",
+ fun() ->
+ lager:md([{platypus, gravid}, {sloth, hirsute}, {duck, erroneous}]),
+ lager:info("I sing the animal kingdom electric!"),
+ {_Level, _Time, _Message, Metadata} = pop(),
+ ?assertEqual(gravid, proplists:get_value(platypus, Metadata)),
+ ?assertEqual(hirsute, proplists:get_value(sloth, Metadata)),
+ ?assertEqual(erroneous, proplists:get_value(duck, Metadata)),
+ ?assertEqual(undefined, proplists:get_value(eagle, Metadata)),
+ lager:md([{platypus, gravid}, {sloth, hirsute}, {eagle, superincumbent}]),
+ lager:info("I sing the animal kingdom dielectric!"),
+ {_Level2, _Time2, _Message2, Metadata2} = pop(),
+ ?assertEqual(gravid, proplists:get_value(platypus, Metadata2)),
+ ?assertEqual(hirsute, proplists:get_value(sloth, Metadata2)),
+ ?assertEqual(undefined, proplists:get_value(duck, Metadata2)),
+ ?assertEqual(superincumbent, proplists:get_value(eagle, Metadata2)),
+ ok
+ end
+ },
+ {"can't store invalid metadata",
+ fun() ->
+ ?assertEqual(ok, lager:md([{platypus, gravid}, {sloth, hirsute}, {duck, erroneous}])),
+ ?assertError(badarg, lager:md({flamboyant, flamingo})),
+ ?assertError(badarg, lager:md("zookeeper zephyr")),
+ ok
+ end
}
]
}.

0 comments on commit 997f8e9

Please sign in to comment.