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