1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1997-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%%-----------------------------------------------------------------
22%%% Overload protection configuration
23
24%%! *** NOTE ***
25%%! It's important that:
26%%! SYNC_MODE_QLEN =< DROP_MODE_QLEN =< FLUSH_QLEN
27%%! and that DROP_MODE_QLEN >= 2.
28%%! Otherwise the process could end up in drop mode with no new
29%%! log requests to process. This would cause all future requests
30%%! to be dropped (no switch to async mode would ever take place).
31
32%% This specifies the message_queue_len value where the log
33%% requests switch from asynchronous casts to synchronous calls.
34-define(SYNC_MODE_QLEN, 10).
35%% Above this message_queue_len, log requests will be dropped,
36%% i.e. no log requests get sent to the process.
37-define(DROP_MODE_QLEN, 200).
38%% Above this message_queue_len, the process will flush its mailbox
39%% and only leave this number of messages in it.
40-define(FLUSH_QLEN, 1000).
41
42%% Never flush more than this number of messages in one go, or the
43%% process will be unresponsive for seconds (keep this number as large
44%% as possible or the mailbox could grow large).
45-define(FLUSH_MAX_N, 5000).
46
47%% BURST_LIMIT_MAX_COUNT is the max number of log requests allowed
48%% to be written within a BURST_LIMIT_WINDOW_TIME time frame.
49-define(BURST_LIMIT_ENABLE, true).
50-define(BURST_LIMIT_MAX_COUNT, 500).
51-define(BURST_LIMIT_WINDOW_TIME, 1000).
52
53%% This enables/disables the feature to automatically terminate the
54%% process if it gets too loaded (and can't keep up).
55-define(OVERLOAD_KILL_ENABLE, false).
56%% If the message_queue_len goes above this size even after
57%% flushing has been performed, the process is terminated.
58-define(OVERLOAD_KILL_QLEN, 20000).
59%% If the memory usage exceeds this level, the process is terminated.
60-define(OVERLOAD_KILL_MEM_SIZE, 3000000).
61
62%% This is the default time to wait before restarting and accepting
63%% new requests. The value 'infinity' disables restarts.
64-define(OVERLOAD_KILL_RESTART_AFTER, 5000).
65
66%% This is the time in milliseconds after last load message received
67%% that we notify the callback about being idle.
68-define(IDLE_DETECT_TIME, 100).
69
70%%%-----------------------------------------------------------------
71%%% Overload protection macros
72
73-define(timestamp(), erlang:monotonic_time(microsecond)).
74
75-define(max(X1, X2),
76        if
77            X2 == undefined -> X1;
78            X2 > X1 -> X2;
79            true -> X1
80        end).
81
82-define(diff_time(OS_T1, OS_T0), OS_T1-OS_T0).
83
84%%%-----------------------------------------------------------------
85%%% These macros enable statistics counters in the state of the
86%%% process, which is useful for analysing the overload protection
87%%% behaviour. These counters should not be included in code to be
88%%% officially released (as some counters will grow very large over
89%%% time).
90
91%% -define(SAVE_STATS, true).
92-ifdef(SAVE_STATS).
93  -define(merge_with_stats(STATE),
94          begin
95              TIME = ?timestamp(),
96              STATE#{start => TIME, time => {TIME,0},
97                     flushes => 0, flushed => 0, drops => 0,
98                     burst_drops => 0, casts => 0, calls => 0,
99                     writes => 0, max_qlen => 0, max_time => 0,
100                     max_mem => 0, freq => {TIME,0,0}} end).
101
102  -define(update_max_qlen(QLEN, STATE),
103          begin #{max_qlen := QLEN0} = STATE,
104                STATE#{max_qlen => ?max(QLEN0,QLEN)} end).
105
106  -define(update_max_mem(MEM, STATE),
107          begin #{max_mem := MEM0} = STATE,
108                STATE#{max_mem => ?max(MEM0,MEM)} end).
109
110  -define(update_calls_or_casts(CALL_OR_CAST, INC, STATE),
111          case CALL_OR_CAST of
112              cast ->
113                  #{casts := CASTS0} = STATE,
114                  STATE#{casts => CASTS0+INC};
115              call ->
116                  #{calls := CALLS0} = STATE,
117                  STATE#{calls => CALLS0+INC}
118          end).
119
120  -define(update_max_time(TIME, STATE),
121          begin #{max_time := TIME0} = STATE,
122                STATE#{max_time => ?max(TIME0,TIME)} end).
123
124  -define(update_other(OTHER, VAR, INCVAL, STATE),
125          begin #{OTHER := VAR} = STATE,
126                STATE#{OTHER => VAR+INCVAL} end).
127
128  -define(update_freq(TIME,STATE),
129          begin
130              case STATE of
131                  #{freq := {START, 49, _}} ->
132                      STATE#{freq => {TIME, 0, trunc(1000000*50/(?diff_time(TIME,START)))}};
133                  #{freq := {START, N, FREQ}} ->
134                      STATE#{freq => {START, N+1, FREQ}}
135              end end).
136
137  -define(update_time(TIME,STATE),
138          begin #{start := START} = STATE,
139                STATE#{time => {TIME,trunc((?diff_time(TIME,START))/1000000)}} end).
140
141-else.                                          % DEFAULT!
142  -define(merge_with_stats(STATE), STATE).
143  -define(update_max_qlen(_QLEN, STATE), STATE).
144  -define(update_max_mem(_MEM, STATE), STATE).
145  -define(update_calls_or_casts(_CALL_OR_CAST, _INC, STATE), STATE).
146  -define(update_max_time(_TIME, STATE), STATE).
147  -define(update_other(_OTHER, _VAR, _INCVAL, STATE), STATE).
148  -define(update_freq(_TIME, STATE), STATE).
149  -define(update_time(_TIME, STATE), STATE).
150-endif.
151
152%%%-----------------------------------------------------------------
153%%% These macros enable callbacks that make it possible to analyse the
154%%% overload protection behaviour from outside the process (including
155%%% dropped requests on the client side). An external callback module
156%%% (?OBSERVER_MOD) is required which is not part of the kernel
157%%% application. For this reason, these callbacks should not be
158%%% included in code to be officially released.
159
160%%-define(OBSERVER_MOD, logger_test).
161-ifdef(OBSERVER_MOD).
162  -define(start_observation(NAME), ?OBSERVER:start_observation(NAME)).
163  -define(observe(NAME,EVENT), ?OBSERVER:observe(NAME,EVENT)).
164
165-else.                                          % DEFAULT!
166  -define(start_observation(_NAME), ok).
167  -define(observe(_NAME,_EVENT), ok).
168-endif.
169