1%% -*- erlang -*-
2
3-ifndef(__HUT_HRL__).
4-define(__HUT_HRL__, true).
5
6%% Supported logging levels (taken from lager):
7-define(log_levels, [debug, info, notice, warning, error, critical, alert, emergency]).
8-define(default_log_level, info).
9-define(default_use_log_level_gate, true).
10
11%% Helper macros
12-define(__fmt(__Fmt, __Args), lists:flatten(io_lib:format(__Fmt, __Args))).
13
14-define(__maybe_log(__Level, __Fun),
15        ((fun() ->
16                   __UseGate = application:get_env(hut, use_log_level_gate, ?default_use_log_level_gate),
17                  case __UseGate of
18                      true ->
19                          __CurrentLevel = application:get_env(hut, level, ?default_log_level),
20                          __AllowedLevels = lists:dropwhile(fun(__Element) -> __Element =/= __CurrentLevel end, ?log_levels),
21                          __IsEnabled = lists:member(__Level, __AllowedLevels),
22                          case __IsEnabled of
23                              true ->
24                                  __Fun();
25                              _ ->
26                                  ok
27                          end;
28                      _ ->
29                          __Fun()
30                  end
31          end)())).
32
33%% Lager support
34
35-ifdef(HUT_LAGER).
36-define(log_type, "lager").
37
38-ifndef(HUT_LAGER_SINK).
39-define(HUT_LAGER_SINK, lager).
40-endif.
41
42-define(log(__Level, __Fmt),
43        ?HUT_LAGER_SINK:__Level([], __Fmt, [])).
44-define(log(__Level, __Fmt, __Args),
45        ?HUT_LAGER_SINK:__Level([], __Fmt, __Args)).
46-define(log(__Level, __Fmt, __Args, __Opts),
47        ?HUT_LAGER_SINK:__Level(__Opts, __Fmt, __Args)).
48
49-else.
50
51% Using plain `io:format/2`.
52
53-ifdef(HUT_IOFORMAT).
54-define(log_type, "ioformat").
55
56-define(log(__Level, __Fmt),
57        ?__maybe_log(__Level, fun() -> io:format("~p: " ++ __Fmt ++ "~n", [__Level]) end)).
58-define(log(__Level, __Fmt, __Args),
59        ?__maybe_log(__Level, fun() -> io:format("~p: " ++ __Fmt ++ "~n", [__Level] ++ __Args) end)).
60-define(log(__Level, __Fmt, __Args, __Opts),
61        ?__maybe_log(__Level, fun() -> io:format("~p: " ++ __Fmt ++ "; Opts: ~p~n", [__Level] ++ __Args ++ [__Opts]) end)).
62
63-else.
64
65% All logging calls are passed into a custom logging callback module given by `HUT_CUSTOM_CB`.
66
67-ifdef(HUT_CUSTOM).
68-ifdef(HUT_CUSTOM_CB).
69-define(log_type, "custom").
70
71-define(log(__Level, __Fmt),
72        ?__maybe_log(__Level, fun() -> ?HUT_CUSTOM_CB:log(__Level, __Fmt, [], []) end)).
73-define(log(__Level, __Fmt, __Args),
74        ?__maybe_log(__Level, fun() -> ?HUT_CUSTOM_CB:log(__Level, __Fmt, __Args, []) end)).
75-define(log(__Level, __Fmt, __Args, __Opts),
76        ?__maybe_log(__Level, fun() -> ?HUT_CUSTOM_CB:log(__Level, __Fmt, __Args, __Opts) end)).
77
78-endif.
79-else.
80
81% All logging calls are ignored.
82
83-ifdef(HUT_NOOP).
84-define(log_type, "noop").
85
86-define(log(__Level, __Fmt), true).
87-define(log(__Level, __Fmt, __Args), true).
88-define(log(__Level, __Fmt, __Args, __Opts), true).
89
90-else.
91
92% If none of the above options was defined, we default to using OTP sasl's error_logger.
93-define(log_type, "default").
94
95-define(__log_error_logger(__Level, __Fmt, __Args, __Opts),
96        ((fun() ->
97                  case __Level of
98                      info ->
99                          error_logger:info_report([{msg, ?__fmt(__Fmt, __Args)}, {options, __Opts}]);
100                      warning ->
101                          error_logger:warning_report([{msg, ?__fmt(__Fmt, __Args)}, {options, __Opts}]);
102                      error ->
103                          error_logger:error_report([{msg, ?__fmt(__Fmt, __Args)}, {options, __Opts}]);
104                      _ when __Level =:= debug; __Level =:= notice ->
105                          error_logger:info_report([{sublevel, __Level}, {msg, ?__fmt(__Fmt, __Args)}, {options, __Opts}]);
106                      _ when __Level =:= critical; __Level =:= alert; __Level =:= emergency ->
107                          error_logger:error_report([{sublevel, __Level}, {msg, ?__fmt(__Fmt, __Args)}, {options, __Opts}]);
108                      _ ->
109                          ok
110                  end
111          end)())).
112
113-define(log(__Level, __Fmt),
114        ?__maybe_log(__Level, fun() -> ?__log_error_logger(__Level, __Fmt, [], []) end)).
115-define(log(__Level, __Fmt, __Args),
116        ?__maybe_log(__Level, fun() -> ?__log_error_logger(__Level, __Fmt, __Args, []) end)).
117-define(log(__Level, __Fmt, __Args, __Opts),
118        ?__maybe_log(__Level, fun() -> ?__log_error_logger(__Level, __Fmt, __Args, __Opts) end)).
119
120% End of all actual log implementation switches.
121-endif.
122-endif.
123-endif.
124-endif.
125
126% End of log declarations
127-endif.
128