Permalink
Browse files

Draft 0.2

  • Loading branch information...
1 parent 55b24c7 commit e12b4c684e7927f4e4f64970095c23ca3c3c4f3e @slfritchie slfritchie committed Oct 29, 2010
Showing with 298 additions and 1 deletion.
  1. +4 −1 ebin/riak_err.app
  2. +32 −0 src/riak_err_app.erl
  3. +98 −0 src/riak_err_handler.erl
  4. +119 −0 src/riak_err_monitor.erl
  5. +45 −0 src/riak_err_sup.erl
View
@@ -5,7 +5,10 @@
{description, "Custom error handler"},
{vsn, "0.1.0"},
{modules, [
- riak_err_app
+ riak_err_app,
+ riak_err_handler,
+ riak_err_monitor,
+ riak_err_sup
]},
{applications, [
kernel,
View
@@ -1 +1,33 @@
+%% Copyright (c) 2010 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+
-module(riak_err_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/0,
+ start/2,
+ stop/1]).
+
+start() ->
+ application:start(riak_err).
+
+start(_StartType, _StartArgs) ->
+ riak_err_sup:start_link().
+
+stop(_State) ->
+ ok.
View
@@ -0,0 +1,98 @@
+%% Copyright (c) 2010 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+
+%% @doc Replace the OTP default error_logger's event handler (which
+%% can cause memory use problems when handling very large messages)
+%% with a handler that will use a limited amount of RAM but is
+%% otherwise equivalent.
+
+-module(riak_err_handler).
+
+-behaviour(gen_event).
+
+%% External exports
+-export([start_link/0, add_handler/0]).
+
+%% gen_event callbacks
+-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2,
+ code_change/3]).
+
+-record(state, {}).
+
+%%%----------------------------------------------------------------------
+%%% API
+%%%----------------------------------------------------------------------
+start_link() ->
+ gen_event:start_link({local, riak_err_handler}).
+
+add_handler() ->
+ gen_event:add_handler(riak_err_handler, riak_err_handler, []).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_event
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% Other
+%%----------------------------------------------------------------------
+init([]) ->
+ {ok, #state{}}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_event/2
+%% Returns: {ok, State} |
+%% {swap_handler, Args1, State1, Mod2, Args2} |
+%% remove_handler
+%%----------------------------------------------------------------------
+handle_event(Event, State) ->
+ io:format("~s: event ~P\n", [?MODULE, Event, 10]),
+ {ok, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/2
+%% Returns: {ok, Reply, State} |
+%% {swap_handler, Reply, Args1, State1, Mod2, Args2} |
+%% {remove_handler, Reply}
+%%----------------------------------------------------------------------
+handle_call(_Request, State) ->
+ Reply = ok,
+ {ok, Reply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {ok, State} |
+%% {swap_handler, Args1, State1, Mod2, Args2} |
+%% remove_handler
+%%----------------------------------------------------------------------
+handle_info(_Info, State) ->
+ {ok, State}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any
+%%----------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%%----------------------------------------------------------------------
+%%% Internal functions
+%%%----------------------------------------------------------------------
View
@@ -0,0 +1,119 @@
+%% Copyright (c) 2010 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+
+-module(riak_err_monitor).
+
+-behaviour(gen_server).
+
+-define(NAME, ?MODULE).
+-define(Timeout, infinity).
+
+%% External exports
+-export([start_link/0, stop/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
+ code_change/3]).
+
+-record(state, {}).
+
+%%%----------------------------------------------------------------------
+%%% API
+%%%----------------------------------------------------------------------
+start_link() ->
+ gen_server:start_link({local, ?NAME}, ?MODULE, [], []).
+
+stop() ->
+ gen_event:call(?NAME, stop, infinity).
+
+%%%----------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+init([]) ->
+ %% Add our custom handler.
+ ok = gen_event:add_sup_handler(error_logger, riak_err_handler, []),
+
+ %% Disable the kernel default logger.
+ error_logger:tty(false),
+ %% Disable the SASL default logger.
+ gen_event:delete_handler(error_logger, sasl_report_tty_h,
+ {stop_please, ?MODULE}),
+ %% Same for the default error logger.
+ gen_event:delete_handler(error_logger, error_logger,
+ {stop_please, ?MODULE}),
+ {ok, #state{}}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_call(_Request, _From, State) ->
+ {reply, not_implemented, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_cast({gen_event_EXIT, Handler, Reason}, State) ->
+ %% Our handler ought to be bullet-proof ... but it wasn't, bummer.
+ %% We will stop now, and our supervisor will restart us and thus
+ %% reinstate the custom event handler.
+ io:format("~w: ~s: handler ~w exited for reason ~W\n",
+ [self(), ?MODULE, Handler, Reason, 20]),
+ {stop, gen_event_EXIT, State};
+handle_cast(Msg, State) ->
+ io:format("~w: ~s:handle_cast got ~w\n", [self(), ?MODULE, Msg]),
+ {noreply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%----------------------------------------------------------------------
+handle_info(Info, State) ->
+ io:format("~w: ~s:handle_info got ~w\n", [self(), ?MODULE, Info]),
+ {noreply, State}.
+
+%%----------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%----------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%%----------------------------------------------------------------------
+%%% Internal functions
+%%%----------------------------------------------------------------------
View
@@ -0,0 +1,45 @@
+%% Copyright (c) 2010 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+
+-module(riak_err_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+start_link() ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+init([]) ->
+ RestartStrategy = one_for_one,
+ MaxRestarts = 1000,
+ MaxSecondsBetweenRestarts = 3600,
+
+ SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},
+
+ Restart = permanent,
+ Shutdown = 5000,
+
+ Monitor = {riak_err_monitor, {riak_err_monitor, start_link, []},
+ Restart, Shutdown, worker, [riak_err_monitor]},
+
+ {ok, {SupFlags, [Monitor]}}.

0 comments on commit e12b4c6

Please sign in to comment.