Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 275 lines (254 sloc) 10.897 kB
12a784b @Vagabond Time makes fools of us all
Vagabond authored
1 %% Copyright (c) 2011-2012 Basho Technologies, Inc. All Rights Reserved.
7bcf044 @Vagabond Initial import
Vagabond authored
2 %%
3 %% This file is provided to you under the Apache License,
4 %% Version 2.0 (the "License"); you may not use this file
5 %% except in compliance with the License. You may obtain
6 %% a copy of the License at
7 %%
8 %% http://www.apache.org/licenses/LICENSE-2.0
9 %%
10 %% Unless required by applicable law or agreed to in writing,
11 %% software distributed under the License is distributed on an
12 %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 %% KIND, either express or implied. See the License for the
14 %% specific language governing permissions and limitations
15 %% under the License.
16
862a9cb @Vagabond Documentation!
Vagabond authored
17 %% @doc Console backend for lager. Configured with a single option, the loglevel
18 %% desired.
19
7bcf044 @Vagabond Initial import
Vagabond authored
20 -module(lager_console_backend).
21
22 -behaviour(gen_event).
23
24 -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2,
25 code_change/3]).
26
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
27 -record(state, {level, formatter,format_config}).
7bcf044 @Vagabond Initial import
Vagabond authored
28
bff8eb1 @Vagabond Console backend tests
Vagabond authored
29 -ifdef(TEST).
30 -include_lib("eunit/include/eunit.hrl").
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
31 -compile([{parse_transform, lager_transform}]).
bff8eb1 @Vagabond Console backend tests
Vagabond authored
32 -endif.
33
19f2339 @Vagabond Make console backend more robust against bad configuration
Vagabond authored
34 -include("lager.hrl").
35
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
36 -define(TERSE_FORMAT,[time, " [", severity,"] ", message, "\r\n"]).
37
862a9cb @Vagabond Documentation!
Vagabond authored
38 %% @private
40b0e2d @Vagabond Record milliseconds with timestamps, make console less verbose by def…
Vagabond authored
39 init(Level) when is_atom(Level) ->
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
40 init([Level,{lager_default_formatter,?TERSE_FORMAT}]);
41 init([Level, true]) -> % for backwards compatibility
82eda71 @Vagabond Update the console backend to use new default formatter for verbose mode
Vagabond authored
42 init([Level,{lager_default_formatter,[{eol, "\r\n"}]}]);
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
43 init([Level,false]) -> % for backwards compatibility
44 init([Level,{lager_default_formatter,?TERSE_FORMAT}]);
45 init([Level,{Formatter,FormatterConfig}]) when is_atom(Level), is_atom(Formatter)->
19f2339 @Vagabond Make console backend more robust against bad configuration
Vagabond authored
46 case lists:member(Level, ?LEVELS) of
47 true ->
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
48 {ok, #state{level=lager_util:level_to_num(Level),
49 formatter=Formatter,
50 format_config=FormatterConfig}};
19f2339 @Vagabond Make console backend more robust against bad configuration
Vagabond authored
51 _ ->
52 {error, bad_log_level}
53 end.
54
7bcf044 @Vagabond Initial import
Vagabond authored
55
862a9cb @Vagabond Documentation!
Vagabond authored
56 %% @private
7bcf044 @Vagabond Initial import
Vagabond authored
57 handle_call(get_loglevel, #state{level=Level} = State) ->
58 {ok, Level, State};
761642e @Vagabond Add ability to adjust loglevel per handler at runtime
Vagabond authored
59 handle_call({set_loglevel, Level}, State) ->
19f2339 @Vagabond Make console backend more robust against bad configuration
Vagabond authored
60 case lists:member(Level, ?LEVELS) of
61 true ->
62 {ok, ok, State#state{level=lager_util:level_to_num(Level)}};
63 _ ->
64 {ok, {error, bad_log_level}, State}
65 end;
7bcf044 @Vagabond Initial import
Vagabond authored
66 handle_call(_Request, State) ->
67 {ok, ok, State}.
68
862a9cb @Vagabond Documentation!
Vagabond authored
69 %% @private
e04830b @Vagabond Tag lager_msg messages with a {log, ...} tuple
Vagabond authored
70 handle_event({log, Message},
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
71 #state{level=L,formatter=Formatter,format_config=FormatConfig} = State) ->
e07c048 @Vagabond One function doesn't make a module
Vagabond authored
72 case lager_util:is_loggable(Message, L, ?MODULE) of
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
73 true ->
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
74 io:put_chars(user, Formatter:format(Message,FormatConfig)),
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
75 {ok, State};
76 false ->
77 {ok, State}
78 end;
7bcf044 @Vagabond Initial import
Vagabond authored
79 handle_event(_Event, State) ->
80 {ok, State}.
81
862a9cb @Vagabond Documentation!
Vagabond authored
82 %% @private
7bcf044 @Vagabond Initial import
Vagabond authored
83 handle_info(_Info, State) ->
84 {ok, State}.
85
862a9cb @Vagabond Documentation!
Vagabond authored
86 %% @private
7bcf044 @Vagabond Initial import
Vagabond authored
87 terminate(_Reason, _State) ->
88 ok.
89
862a9cb @Vagabond Documentation!
Vagabond authored
90 %% @private
7bcf044 @Vagabond Initial import
Vagabond authored
91 code_change(_OldVsn, State, _Extra) ->
92 {ok, State}.
bff8eb1 @Vagabond Console backend tests
Vagabond authored
93
94 -ifdef(TEST).
95 console_log_test_() ->
96 %% tiny recursive fun that pretends to be a group leader
97 F = fun(Self) ->
98 fun() ->
99 YComb = fun(Fun) ->
100 receive
101 {io_request, From, ReplyAs, {put_chars, unicode, _Msg}} = Y ->
102 From ! {io_reply, ReplyAs, ok},
103 Self ! Y,
104 Fun(Fun);
105 Other ->
106 ?debugFmt("unexpected message ~p~n", [Other]),
107 Self ! Other
108 end
109 end,
110 YComb(YComb)
111 end
112 end,
113 {foreach,
114 fun() ->
115 error_logger:tty(false),
116 application:load(lager),
117 application:set_env(lager, handlers, []),
118 application:set_env(lager, error_logger_redirect, false),
caad1f8 @Vagabond Fix eunit tests to "start" compiler and syntax_tools
Vagabond authored
119 application:start(compiler),
120 application:start(syntax_tools),
938d351 @thomasc Restore user process registration to it's original value in the conso…
thomasc authored
121 application:start(lager),
122 whereis(user)
bff8eb1 @Vagabond Console backend tests
Vagabond authored
123 end,
938d351 @thomasc Restore user process registration to it's original value in the conso…
thomasc authored
124 fun(User) ->
125 unregister(user),
126 register(user, User),
bff8eb1 @Vagabond Console backend tests
Vagabond authored
127 application:stop(lager),
128 error_logger:tty(true)
129 end,
130 [
131 {"regular console logging",
132 fun() ->
133 Pid = spawn(F(self())),
134 gen_event:add_handler(lager_event, lager_console_backend, info),
f9e36ed @thomasc Direct the console logger output to user
thomasc authored
135 unregister(user),
136 register(user, Pid),
bff8eb1 @Vagabond Console backend tests
Vagabond authored
137 erlang:group_leader(Pid, whereis(lager_event)),
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
138 lager_mochiglobal:put(loglevel, {?INFO, []}),
bff8eb1 @Vagabond Console backend tests
Vagabond authored
139 lager:log(info, self(), "Test message"),
140 receive
141 {io_request, From, ReplyAs, {put_chars, unicode, Msg}} ->
142 From ! {io_reply, ReplyAs, ok},
9f22054 Added CRs to the LFs in lager_console_backend
Joe DeVivo authored
143 ?assertMatch([_, "[info]", "Test message\r\n"], re:split(Msg, " ", [{return, list}, {parts, 3}]))
bff8eb1 @Vagabond Console backend tests
Vagabond authored
144 after
145 500 ->
146 ?assert(false)
147 end
148 end
149 },
150 {"verbose console logging",
151 fun() ->
152 Pid = spawn(F(self())),
f9e36ed @thomasc Direct the console logger output to user
thomasc authored
153 unregister(user),
154 register(user, Pid),
bff8eb1 @Vagabond Console backend tests
Vagabond authored
155 erlang:group_leader(Pid, whereis(lager_event)),
156 gen_event:add_handler(lager_event, lager_console_backend, [info, true]),
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
157 lager_mochiglobal:put(loglevel, {?INFO, []}),
158 lager:info("Test message"),
159 lager:info("Test message"),
bff8eb1 @Vagabond Console backend tests
Vagabond authored
160 PidStr = pid_to_list(self()),
161 receive
162 {io_request, _, _, {put_chars, unicode, Msg}} ->
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
163 ?assertMatch([_, _, "[info]", PidStr, _,"Test message\r\n"], re:split(Msg, "[ @]", [{return, list}, {parts, 6}]))
bff8eb1 @Vagabond Console backend tests
Vagabond authored
164 after
165 500 ->
166 ?assert(false)
167 end
168 end
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
169 },
170 {"tracing should work",
171 fun() ->
172 Pid = spawn(F(self())),
f9e36ed @thomasc Direct the console logger output to user
thomasc authored
173 unregister(user),
174 register(user, Pid),
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
175 gen_event:add_handler(lager_event, lager_console_backend, info),
176 erlang:group_leader(Pid, whereis(lager_event)),
177 lager_mochiglobal:put(loglevel, {?INFO, []}),
178 lager:debug("Test message"),
179 receive
180 {io_request, From, ReplyAs, {put_chars, unicode, _Msg}} ->
181 From ! {io_reply, ReplyAs, ok},
182 ?assert(false)
183 after
184 500 ->
185 ?assert(true)
186 end,
c619263 @Vagabond Cleanup unused handlers when a trace is removed, documentation
Vagabond authored
187 {ok, _} = lager:trace_console([{module, ?MODULE}]),
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
188 lager:debug("Test message"),
189 receive
190 {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
191 From1 ! {io_reply, ReplyAs1, ok},
9f22054 Added CRs to the LFs in lager_console_backend
Joe DeVivo authored
192 ?assertMatch([_, "[debug]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
193 after
194 500 ->
195 ?assert(false)
196 end
197 end
198 },
199 {"tracing doesn't duplicate messages",
200 fun() ->
201 Pid = spawn(F(self())),
f9e36ed @thomasc Direct the console logger output to user
thomasc authored
202 unregister(user),
203 register(user, Pid),
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
204 gen_event:add_handler(lager_event, lager_console_backend, info),
205 lager_mochiglobal:put(loglevel, {?INFO, []}),
206 erlang:group_leader(Pid, whereis(lager_event)),
207 lager:debug("Test message"),
208 receive
209 {io_request, From, ReplyAs, {put_chars, unicode, _Msg}} ->
210 From ! {io_reply, ReplyAs, ok},
211 ?assert(false)
212 after
213 500 ->
214 ?assert(true)
215 end,
c619263 @Vagabond Cleanup unused handlers when a trace is removed, documentation
Vagabond authored
216 {ok, _} = lager:trace_console([{module, ?MODULE}]),
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
217 lager:error("Test message"),
218 receive
219 {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
220 From1 ! {io_reply, ReplyAs1, ok},
9f22054 Added CRs to the LFs in lager_console_backend
Joe DeVivo authored
221 ?assertMatch([_, "[error]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
222 after
223 1000 ->
224 ?assert(false)
225 end,
226 %% make sure this event wasn't duplicated
227 receive
228 {io_request, From2, ReplyAs2, {put_chars, unicode, _Msg2}} ->
229 From2 ! {io_reply, ReplyAs2, ok},
230 ?assert(false)
231 after
232 500 ->
233 ?assert(true)
234 end
235 end
bff8eb1 @Vagabond Console backend tests
Vagabond authored
236 }
ac8fb19 @Vagabond Implement console tracing, don't generate duplicate messages
Vagabond authored
237
bff8eb1 @Vagabond Console backend tests
Vagabond authored
238 ]
239 }.
240
241 set_loglevel_test_() ->
242 {foreach,
243 fun() ->
244 error_logger:tty(false),
245 application:load(lager),
246 application:set_env(lager, handlers, [{lager_console_backend, info}]),
247 application:set_env(lager, error_logger_redirect, false),
248 application:start(lager)
249 end,
250 fun(_) ->
251 application:stop(lager),
252 error_logger:tty(true)
253 end,
254 [
255 {"Get/set loglevel test",
256 fun() ->
257 ?assertEqual(info, lager:get_loglevel(lager_console_backend)),
258 lager:set_loglevel(lager_console_backend, debug),
259 ?assertEqual(debug, lager:get_loglevel(lager_console_backend))
260 end
19f2339 @Vagabond Make console backend more robust against bad configuration
Vagabond authored
261 },
262 {"Get/set invalid loglevel test",
263 fun() ->
264 ?assertEqual(info, lager:get_loglevel(lager_console_backend)),
265 ?assertEqual({error, bad_log_level},
266 lager:set_loglevel(lager_console_backend, fatfinger)),
267 ?assertEqual(info, lager:get_loglevel(lager_console_backend))
268 end
bff8eb1 @Vagabond Console backend tests
Vagabond authored
269 }
19f2339 @Vagabond Make console backend more robust against bad configuration
Vagabond authored
270
bff8eb1 @Vagabond Console backend tests
Vagabond authored
271 ]
272 }.
273
274 -endif.
Something went wrong with that request. Please try again.