Browse Source

Add `async_threshold_window` option. #147

pull/150/head
Sergey Prokhorov 12 years ago
parent
commit
73d286e2b0
4 changed files with 28 additions and 9 deletions
  1. +4
    -2
      README.md
  2. +4
    -1
      src/lager.app.src
  3. +14
    -1
      src/lager_app.erl
  4. +6
    -5
      src/lager_backend_throttle.erl

+ 4
- 2
README.md View File

@ -154,11 +154,13 @@ polls its own mailbox size and toggles the messaging between synchronous and
asynchronous depending on mailbox size. asynchronous depending on mailbox size.
```erlang ```erlang
{async_threshold, 20}
{async_threshold, 20},
{async_threshold_window, 5}
``` ```
This will use async messaging until the mailbox exceeds 20 messages, at which This will use async messaging until the mailbox exceeds 20 messages, at which
point synchronous messaging will be used.
point synchronous messaging will be used, and switch back to asynchronous, when
size reduces to `20 - 5 = 15`.
If you wish to disable this behaviour, simply set it to 'undefined'. It defaults If you wish to disable this behaviour, simply set it to 'undefined'. It defaults
to a low number to prevent the mailbox growing rapidly beyond the limit and causing to a low number to prevent the mailbox growing rapidly beyond the limit and causing

+ 4
- 1
src/lager.app.src View File

@ -53,6 +53,9 @@
%% How many messages per second to allow from error_logger before we start dropping them %% How many messages per second to allow from error_logger before we start dropping them
{error_logger_hwm, 50}, {error_logger_hwm, 50},
%% How big the gen_event mailbox can get before it is switched into sync mode %% How big the gen_event mailbox can get before it is switched into sync mode
{async_threshold, 20}
{async_threshold, 20},
%% Switch back to async mode, when gen_event mailbox size decrease from `async_threshold'
%% to async_threshold - async_threshold_window
{async_threshold_window, 5}
]} ]}
]}. ]}.

+ 14
- 1
src/lager_app.erl View File

@ -42,7 +42,20 @@ start(_StartType, _StartArgs) ->
{ok, undefined} -> {ok, undefined} ->
undefined; undefined;
{ok, Threshold} when is_integer(Threshold), Threshold >= 0 -> {ok, Threshold} when is_integer(Threshold), Threshold >= 0 ->
_ = supervisor:start_child(lager_handler_watcher_sup, [lager_event, lager_backend_throttle, Threshold]),
DefWindow = erlang:trunc(Threshold * 0.2), % maybe 0?
ThresholdWindow =
case application:get_env(lager, async_threshold_window) of
undefined ->
DefWindow;
{ok, Window} when is_integer(Window), Window < Threshold, Window >= 0 ->
Window;
{ok, BadWindow} ->
error_logger:error_msg(
"Invalid value for 'async_threshold_window': ~p~n", [BadWindow]),
throw({error, bad_config})
end,
_ = supervisor:start_child(lager_handler_watcher_sup,
[lager_event, lager_backend_throttle, [Threshold, ThresholdWindow]]),
ok; ok;
{ok, BadThreshold} -> {ok, BadThreshold} ->
error_logger:error_msg("Invalid value for 'async_threshold': ~p~n", [BadThreshold]), error_logger:error_msg("Invalid value for 'async_threshold': ~p~n", [BadThreshold]),

+ 6
- 5
src/lager_backend_throttle.erl View File

@ -31,12 +31,13 @@
-record(state, { -record(state, {
hwm, hwm,
window_min,
async = true async = true
}). }).
init(Hwm) ->
init([Hwm, Window]) ->
lager_config:set(async, true), lager_config:set(async, true),
{ok, #state{hwm=Hwm}}.
{ok, #state{hwm=Hwm, window_min=Hwm - Window}}.
handle_call(get_loglevel, State) -> handle_call(get_loglevel, State) ->
@ -48,12 +49,12 @@ handle_call(_Request, State) ->
handle_event({log, _Message},State) -> handle_event({log, _Message},State) ->
{message_queue_len, Len} = erlang:process_info(self(), message_queue_len), {message_queue_len, Len} = erlang:process_info(self(), message_queue_len),
case {Len > State#state.hwm, State#state.async} of
{true, true} ->
case {Len > State#state.hwm, Len < State#state.window_min, State#state.async} of
{true, _, true} ->
%% need to flip to sync mode %% need to flip to sync mode
lager_config:set(async, false), lager_config:set(async, false),
{ok, State#state{async=false}}; {ok, State#state{async=false}};
{false, false} ->
{_, true, false} ->
%% need to flip to async mode %% need to flip to async mode
lager_config:set(async, true), lager_config:set(async, true),
{ok, State#state{async=true}}; {ok, State#state{async=true}};

Loading…
Cancel
Save