You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.7 KiB

  1. -module(lager_common_test_backend).
  2. -behavior(gen_event).
  3. %% gen_event callbacks
  4. -export([init/1,
  5. handle_call/2,
  6. handle_event/2,
  7. handle_info/2,
  8. terminate/2,
  9. code_change/3]).
  10. -export([get_logs/0,
  11. bounce/0,
  12. bounce/1]).
  13. %% holds the log messages for retreival on terminate
  14. -record(state, {level :: {mask, integer()},
  15. formatter :: atom(),
  16. format_config :: any(),
  17. log = [] :: list()}).
  18. -include("lager.hrl").
  19. -define(TERSE_FORMAT,[time, " ", color, "[", severity,"] ", message]).
  20. %% @doc Before every test, just
  21. %% lager_common_test_backend:bounce(Level) with the log level of your
  22. %% choice. Every message will be passed along to ct:pal for your
  23. %% viewing in the common_test reports. Also, you can call
  24. %% lager_common_test_backend:get_logs/0 to get a list of all log
  25. %% messages this backend has received during your test. You can then
  26. %% search that list for expected log messages.
  27. -spec get_logs() -> [iolist()] | {error, term()}.
  28. get_logs() ->
  29. gen_event:call(lager_event, ?MODULE, get_logs, infinity).
  30. bounce() ->
  31. bounce(error).
  32. bounce(Level) ->
  33. application:stop(lager),
  34. lager:start(),
  35. gen_event:add_handler(lager_event, lager_common_test_backend, [Level, false]),
  36. %lager:set_loglevel(lager_common_test_backend, Level),
  37. ok.
  38. -spec(init(integer()|atom()|[term()]) -> {ok, #state{}} | {error, atom()}).
  39. %% @private
  40. %% @doc Initializes the event handler
  41. init([Level, true]) -> % for backwards compatibility
  42. init([Level,{lager_default_formatter,[{eol, "\n"}]}]);
  43. init([Level,false]) -> % for backwards compatibility
  44. init([Level,{lager_default_formatter,?TERSE_FORMAT ++ ["\n"]}]);
  45. init([Level,{Formatter,FormatterConfig}]) when is_atom(Formatter) ->
  46. case lists:member(Level, ?LEVELS) of
  47. true ->
  48. {ok, #state{level=lager_util:config_to_mask(Level),
  49. formatter=Formatter,
  50. format_config=FormatterConfig}};
  51. _ ->
  52. {error, bad_log_level}
  53. end;
  54. init(Level) ->
  55. init([Level,{lager_default_formatter,?TERSE_FORMAT ++ ["\n"]}]).
  56. -spec(handle_event(tuple(), #state{}) -> {ok, #state{}}).
  57. %% @private
  58. handle_event({log, Message},
  59. #state{level=L,formatter=Formatter,format_config=FormatConfig,log=Logs} = State) ->
  60. case lager_util:is_loggable(Message,L,?MODULE) of
  61. true ->
  62. Log = Formatter:format(Message,FormatConfig),
  63. ct:pal(Log),
  64. {ok, State#state{log=[Log|Logs]}};
  65. false ->
  66. {ok, State}
  67. end;
  68. handle_event(Event, State) ->
  69. ct:pal(Event),
  70. {ok, State#state{log = [Event|State#state.log]}}.
  71. -spec(handle_call(any(), #state{}) -> {ok, any(), #state{}}).
  72. %% @private
  73. %% @doc gets and sets loglevel. This is part of the lager backend api.
  74. handle_call(get_loglevel, #state{level=Level} = State) ->
  75. {ok, Level, State};
  76. handle_call({set_loglevel, Level}, State) ->
  77. case lists:member(Level, ?LEVELS) of
  78. true ->
  79. {ok, ok, State#state{level=lager_util:level_to_num(Level)}};
  80. _ ->
  81. {ok, {error, bad_log_level}, State}
  82. end;
  83. handle_call(get_logs, #state{log = Logs} = State) ->
  84. {ok, lists:reverse(Logs), State};
  85. handle_call(_, State) ->
  86. {ok, ok, State}.
  87. -spec(handle_info(any(), #state{}) -> {ok, #state{}}).
  88. %% @private
  89. %% @doc gen_event callback, does nothing.
  90. handle_info(_, State) ->
  91. {ok, State}.
  92. -spec(code_change(any(), #state{}, any()) -> {ok, #state{}}).
  93. %% @private
  94. %% @doc gen_event callback, does nothing.
  95. code_change(_OldVsn, State, _Extra) ->
  96. {ok, State}.
  97. -spec(terminate(any(), #state{}) -> {ok, list()}).
  98. %% @doc gen_event callback, does nothing.
  99. terminate(_Reason, #state{log=Logs}) ->
  100. {ok, lists:reverse(Logs)}.