Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

274 wiersze
11 KiB

14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
14 lat temu
  1. %% Copyright (c) 2011-2012 Basho Technologies, Inc. All Rights Reserved.
  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. %% @doc Console backend for lager. Configured with a single option, the loglevel
  17. %% desired.
  18. -module(lager_console_backend).
  19. -behaviour(gen_event).
  20. -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2,
  21. code_change/3]).
  22. -record(state, {level, formatter,format_config}).
  23. -ifdef(TEST).
  24. -include_lib("eunit/include/eunit.hrl").
  25. -compile([{parse_transform, lager_transform}]).
  26. -endif.
  27. -include("lager.hrl").
  28. -define(TERSE_FORMAT,[time, " [", severity,"] ", message, "\r\n"]).
  29. %% @private
  30. init(Level) when is_atom(Level) ->
  31. init([Level,{lager_default_formatter,?TERSE_FORMAT}]);
  32. init([Level, true]) -> % for backwards compatibility
  33. init([Level,{lager_default_formatter,[{eol, "\r\n"}]}]);
  34. init([Level,false]) -> % for backwards compatibility
  35. init([Level,{lager_default_formatter,?TERSE_FORMAT}]);
  36. init([Level,{Formatter,FormatterConfig}]) when is_atom(Level), is_atom(Formatter)->
  37. case lists:member(Level, ?LEVELS) of
  38. true ->
  39. {ok, #state{level=lager_util:level_to_num(Level),
  40. formatter=Formatter,
  41. format_config=FormatterConfig}};
  42. _ ->
  43. {error, bad_log_level}
  44. end.
  45. %% @private
  46. handle_call(get_loglevel, #state{level=Level} = State) ->
  47. {ok, Level, State};
  48. handle_call({set_loglevel, Level}, State) ->
  49. case lists:member(Level, ?LEVELS) of
  50. true ->
  51. {ok, ok, State#state{level=lager_util:level_to_num(Level)}};
  52. _ ->
  53. {ok, {error, bad_log_level}, State}
  54. end;
  55. handle_call(_Request, State) ->
  56. {ok, ok, State}.
  57. %% @private
  58. handle_event({log, Message},
  59. #state{level=L,formatter=Formatter,format_config=FormatConfig} = State) ->
  60. case lager_util:is_loggable(Message, L, ?MODULE) of
  61. true ->
  62. io:put_chars(user, Formatter:format(Message,FormatConfig)),
  63. {ok, State};
  64. false ->
  65. {ok, State}
  66. end;
  67. handle_event(_Event, State) ->
  68. {ok, State}.
  69. %% @private
  70. handle_info(_Info, State) ->
  71. {ok, State}.
  72. %% @private
  73. terminate(_Reason, _State) ->
  74. ok.
  75. %% @private
  76. code_change(_OldVsn, State, _Extra) ->
  77. {ok, State}.
  78. -ifdef(TEST).
  79. console_log_test_() ->
  80. %% tiny recursive fun that pretends to be a group leader
  81. F = fun(Self) ->
  82. fun() ->
  83. YComb = fun(Fun) ->
  84. receive
  85. {io_request, From, ReplyAs, {put_chars, unicode, _Msg}} = Y ->
  86. From ! {io_reply, ReplyAs, ok},
  87. Self ! Y,
  88. Fun(Fun);
  89. Other ->
  90. ?debugFmt("unexpected message ~p~n", [Other]),
  91. Self ! Other
  92. end
  93. end,
  94. YComb(YComb)
  95. end
  96. end,
  97. {foreach,
  98. fun() ->
  99. error_logger:tty(false),
  100. application:load(lager),
  101. application:set_env(lager, handlers, []),
  102. application:set_env(lager, error_logger_redirect, false),
  103. application:start(compiler),
  104. application:start(syntax_tools),
  105. application:start(lager),
  106. whereis(user)
  107. end,
  108. fun(User) ->
  109. unregister(user),
  110. register(user, User),
  111. application:stop(lager),
  112. error_logger:tty(true)
  113. end,
  114. [
  115. {"regular console logging",
  116. fun() ->
  117. Pid = spawn(F(self())),
  118. gen_event:add_handler(lager_event, lager_console_backend, info),
  119. unregister(user),
  120. register(user, Pid),
  121. erlang:group_leader(Pid, whereis(lager_event)),
  122. lager_mochiglobal:put(loglevel, {?INFO, []}),
  123. lager:log(info, self(), "Test message"),
  124. receive
  125. {io_request, From, ReplyAs, {put_chars, unicode, Msg}} ->
  126. From ! {io_reply, ReplyAs, ok},
  127. ?assertMatch([_, "[info]", "Test message\r\n"], re:split(Msg, " ", [{return, list}, {parts, 3}]))
  128. after
  129. 500 ->
  130. ?assert(false)
  131. end
  132. end
  133. },
  134. {"verbose console logging",
  135. fun() ->
  136. Pid = spawn(F(self())),
  137. unregister(user),
  138. register(user, Pid),
  139. erlang:group_leader(Pid, whereis(lager_event)),
  140. gen_event:add_handler(lager_event, lager_console_backend, [info, true]),
  141. lager_mochiglobal:put(loglevel, {?INFO, []}),
  142. lager:info("Test message"),
  143. lager:info("Test message"),
  144. PidStr = pid_to_list(self()),
  145. receive
  146. {io_request, _, _, {put_chars, unicode, Msg}} ->
  147. ?assertMatch([_, _, "[info]", PidStr, _,"Test message\r\n"], re:split(Msg, "[ @]", [{return, list}, {parts, 6}]))
  148. after
  149. 500 ->
  150. ?assert(false)
  151. end
  152. end
  153. },
  154. {"tracing should work",
  155. fun() ->
  156. Pid = spawn(F(self())),
  157. unregister(user),
  158. register(user, Pid),
  159. gen_event:add_handler(lager_event, lager_console_backend, info),
  160. erlang:group_leader(Pid, whereis(lager_event)),
  161. lager_mochiglobal:put(loglevel, {?INFO, []}),
  162. lager:debug("Test message"),
  163. receive
  164. {io_request, From, ReplyAs, {put_chars, unicode, _Msg}} ->
  165. From ! {io_reply, ReplyAs, ok},
  166. ?assert(false)
  167. after
  168. 500 ->
  169. ?assert(true)
  170. end,
  171. {ok, _} = lager:trace_console([{module, ?MODULE}]),
  172. lager:debug("Test message"),
  173. receive
  174. {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
  175. From1 ! {io_reply, ReplyAs1, ok},
  176. ?assertMatch([_, "[debug]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
  177. after
  178. 500 ->
  179. ?assert(false)
  180. end
  181. end
  182. },
  183. {"tracing doesn't duplicate messages",
  184. fun() ->
  185. Pid = spawn(F(self())),
  186. unregister(user),
  187. register(user, Pid),
  188. gen_event:add_handler(lager_event, lager_console_backend, info),
  189. lager_mochiglobal:put(loglevel, {?INFO, []}),
  190. erlang:group_leader(Pid, whereis(lager_event)),
  191. lager:debug("Test message"),
  192. receive
  193. {io_request, From, ReplyAs, {put_chars, unicode, _Msg}} ->
  194. From ! {io_reply, ReplyAs, ok},
  195. ?assert(false)
  196. after
  197. 500 ->
  198. ?assert(true)
  199. end,
  200. {ok, _} = lager:trace_console([{module, ?MODULE}]),
  201. lager:error("Test message"),
  202. receive
  203. {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
  204. From1 ! {io_reply, ReplyAs1, ok},
  205. ?assertMatch([_, "[error]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
  206. after
  207. 1000 ->
  208. ?assert(false)
  209. end,
  210. %% make sure this event wasn't duplicated
  211. receive
  212. {io_request, From2, ReplyAs2, {put_chars, unicode, _Msg2}} ->
  213. From2 ! {io_reply, ReplyAs2, ok},
  214. ?assert(false)
  215. after
  216. 500 ->
  217. ?assert(true)
  218. end
  219. end
  220. }
  221. ]
  222. }.
  223. set_loglevel_test_() ->
  224. {foreach,
  225. fun() ->
  226. error_logger:tty(false),
  227. application:load(lager),
  228. application:set_env(lager, handlers, [{lager_console_backend, info}]),
  229. application:set_env(lager, error_logger_redirect, false),
  230. application:start(lager)
  231. end,
  232. fun(_) ->
  233. application:stop(lager),
  234. error_logger:tty(true)
  235. end,
  236. [
  237. {"Get/set loglevel test",
  238. fun() ->
  239. ?assertEqual(info, lager:get_loglevel(lager_console_backend)),
  240. lager:set_loglevel(lager_console_backend, debug),
  241. ?assertEqual(debug, lager:get_loglevel(lager_console_backend))
  242. end
  243. },
  244. {"Get/set invalid loglevel test",
  245. fun() ->
  246. ?assertEqual(info, lager:get_loglevel(lager_console_backend)),
  247. ?assertEqual({error, bad_log_level},
  248. lager:set_loglevel(lager_console_backend, fatfinger)),
  249. ?assertEqual(info, lager:get_loglevel(lager_console_backend))
  250. end
  251. }
  252. ]
  253. }.
  254. -endif.