./ct_report/coverage/mongoose_deprecations.COVER.html

1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 %% File : mongoose_deprecations.erl
3 %% Author : Dominik Stanaszek <dominik.stanaszek@erlang-solutions.com>
4 %% Purpose : More generic deprecation handling
5 %% Created : 10 Oct 2017
6 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 %% @doc This module is responsible for initialising
8 %% and stopping stuff needed to handle different deprecation
9 %% warnings as well as for exposing API for logging these
10 %% deprecations.
11 %% It checks whether a specific deprecation warning is not exceeding
12 %% given frequency of logging.
13 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
15 -module(mongoose_deprecations).
16 -author("dominik.stanaszek@erlang-solutions.com").
17
18 -export([start/0, stop/0, log/2, log/3]).
19
20 %% Test API
21 -export([log_with_lvl/2]).
22
23 -ignore_xref([log/2]).
24
25 -include("mongoose.hrl").
26
27 -define(DEPRECATION_TAB, deprecations). % ETS table name
28 -define(DEFAULT_COOLDOWN_HOURS, 6). % default cooldown time
29
30 -type deprecation_tag() :: any(). % Specifies the deprecation
31 -type log_level() :: warning | error.
32 -type unix_timestamp() :: mod_mam:unix_timestamp().
33 -type log_map() :: map().
34
35
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 %%% Public API
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39
40 %% @doc Should be called before using the module. Sets everything
41 %% needed up
42 -spec start() -> ok.
43 start() ->
44 4 prepare_ets(),
45 4 ok.
46
47 %% @doc Used after using the module, when we won't log deprecation
48 %% messages again.
49 -spec stop() -> ok.
50 stop() ->
51 4 destroy_ets(),
52 4 ok.
53
54 %% @doc Should be used to log deprecation messages. It logs
55 %% keeping proper frequency. Opts can be:
56 %% * cooldown - the minimal interval (in milliseconds)
57 %% to be held between logs. Default: 6 hours
58 %% It is internally represented in microseconds
59 %% but API requires milliseconds.
60 %% * log_level - 'warning' or 'error'
61 -spec log(deprecation_tag(), log_map(), proplists:proplist()) -> ok.
62 log(Tag, Msg, Opts) ->
63 2 Ms = proplists:get_value(cooldown, Opts, default_cooldown()),
64 2 Cooldown = milliseconds_to_microseconds(Ms),
65 2 LogLvl = proplists:get_value(log_level, Opts, default_log_lvl()),
66 2 maybe_log(Tag, Msg, LogLvl, Cooldown).
67
68 -spec log(deprecation_tag(), log_map()) -> ok.
69 log(Tag, Msg) ->
70
:-(
log(Tag, Msg, []).
71
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 %%% Private functions
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75
76
77 %% @doc Deprecation table will hold pairs in form:
78 %% {deprecation_tag(), unix_timestamp()}
79 %% and will indicate at what (unix) time last deprecation
80 %% warning was logged concerning a deprecation connected to
81 %% the deprecation tag specified in a key
82 -spec prepare_ets() -> ok.
83 prepare_ets() ->
84 4 ets:new(?DEPRECATION_TAB, [{read_concurrency, true}, named_table, public]),
85 4 ok.
86
87 -spec destroy_ets() -> ok.
88 destroy_ets() ->
89 4 ets:delete(?DEPRECATION_TAB),
90 4 ok.
91
92 -spec maybe_log(deprecation_tag(), log_map(), log_level(), unix_timestamp()) -> ok.
93 maybe_log(Tag, Msg, Lvl, Cooldown) ->
94 2 Timestamp = case ets:lookup(?DEPRECATION_TAB, Tag) of
95 [] ->
96 1 not_logged;
97 [{Tag, LastLogged}] ->
98 1 LastLogged
99 end,
100 2 case did_cooldown_elapse(Timestamp, Cooldown) of
101 true ->
102 1 ?MODULE:log_with_lvl(Msg, Lvl), % ?MODULE lets meck mock it
103 1 ets:insert(?DEPRECATION_TAB, {Tag, os:timestamp()}),
104 1 ok;
105 false ->
106 1 ok
107 end.
108
109 -spec did_cooldown_elapse(unix_timestamp() | 'not_logged', unix_timestamp())
110 -> boolean().
111 1 did_cooldown_elapse(not_logged, _) -> true;
112 did_cooldown_elapse(LastLogged, Cooldown) ->
113 1 Now = os:timestamp(),
114 1 timer:now_diff(Now, LastLogged) > Cooldown.
115
116 -spec default_cooldown() -> unix_timestamp().
117 2 default_cooldown() -> ?DEFAULT_COOLDOWN_HOURS * 3600000000.
118
119 -spec default_log_lvl() -> log_level().
120 2 default_log_lvl() -> error.
121
122 -spec log_with_lvl(log_map(), log_level()) -> ok.
123 log_with_lvl(Msg, error) ->
124
:-(
?LOG_ERROR(Msg);
125 log_with_lvl(Msg, warning) ->
126 1 ?LOG_WARNING(Msg).
127
128 -spec milliseconds_to_microseconds(Milliseconds :: integer())
129 -> unix_timestamp().
130 2 milliseconds_to_microseconds(N) -> N * 1000.
Line Hits Source