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.

121 lines
4.0 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. application:set_env(lager, suppress_application_start_stop, true),
  35. application:set_env(lager, handlers,
  36. [
  37. {lager_common_test_backend, [Level, false]}
  38. ]),
  39. ok = lager:start(),
  40. %% we care more about getting all of our messages here than being
  41. %% careful with the amount of memory that we're using.
  42. error_logger_lager_h:set_high_water(100000),
  43. ok.
  44. -spec(init(integer()|atom()|[term()]) -> {ok, #state{}} | {error, atom()}).
  45. %% @private
  46. %% @doc Initializes the event handler
  47. init([Level, true]) -> % for backwards compatibility
  48. init([Level,{lager_default_formatter,[{eol, "\n"}]}]);
  49. init([Level,false]) -> % for backwards compatibility
  50. init([Level,{lager_default_formatter,?TERSE_FORMAT ++ ["\n"]}]);
  51. init([Level,{Formatter,FormatterConfig}]) when is_atom(Formatter) ->
  52. case lists:member(Level, ?LEVELS) of
  53. true ->
  54. {ok, #state{level=lager_util:config_to_mask(Level),
  55. formatter=Formatter,
  56. format_config=FormatterConfig}};
  57. _ ->
  58. {error, bad_log_level}
  59. end;
  60. init(Level) ->
  61. init([Level,{lager_default_formatter,?TERSE_FORMAT ++ ["\n"]}]).
  62. -spec(handle_event(tuple(), #state{}) -> {ok, #state{}}).
  63. %% @private
  64. handle_event({log, Message},
  65. #state{level=L,formatter=Formatter,format_config=FormatConfig,log=Logs} = State) ->
  66. case lager_util:is_loggable(Message,L,?MODULE) of
  67. true ->
  68. Log = Formatter:format(Message,FormatConfig),
  69. ct:pal(Log),
  70. {ok, State#state{log=[Log|Logs]}};
  71. false ->
  72. {ok, State}
  73. end;
  74. handle_event(Event, State) ->
  75. ct:pal(Event),
  76. {ok, State#state{log = [Event|State#state.log]}}.
  77. -spec(handle_call(any(), #state{}) -> {ok, any(), #state{}}).
  78. %% @private
  79. %% @doc gets and sets loglevel. This is part of the lager backend api.
  80. handle_call(get_loglevel, #state{level=Level} = State) ->
  81. {ok, Level, State};
  82. handle_call({set_loglevel, Level}, State) ->
  83. case lists:member(Level, ?LEVELS) of
  84. true ->
  85. {ok, ok, State#state{level=lager_util:config_to_mask(Level)}};
  86. _ ->
  87. {ok, {error, bad_log_level}, State}
  88. end;
  89. handle_call(get_logs, #state{log = Logs} = State) ->
  90. {ok, lists:reverse(Logs), State};
  91. handle_call(_, State) ->
  92. {ok, ok, State}.
  93. -spec(handle_info(any(), #state{}) -> {ok, #state{}}).
  94. %% @private
  95. %% @doc gen_event callback, does nothing.
  96. handle_info(_, State) ->
  97. {ok, State}.
  98. -spec(code_change(any(), #state{}, any()) -> {ok, #state{}}).
  99. %% @private
  100. %% @doc gen_event callback, does nothing.
  101. code_change(_OldVsn, State, _Extra) ->
  102. {ok, State}.
  103. -spec(terminate(any(), #state{}) -> {ok, list()}).
  104. %% @doc gen_event callback, does nothing.
  105. terminate(_Reason, #state{log=Logs}) ->
  106. {ok, lists:reverse(Logs)}.