blob: be44af8ffe0c465a84b1c70b9882e584b5237fe8 [file] [log] [blame]
% Licensed 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(couch_log_server).
-behavior(gen_server).
-export([
start_link/0,
reconfigure/0,
log/1
]).
-export([
init/1,
terminate/2,
handle_call/3,
handle_cast/2,
handle_info/2,
code_change/3
]).
-include("couch_log.hrl").
-record(st, {
writer
}).
-ifdef(TEST).
-define(SEND(Entry), gen_server:call(?MODULE, {log, Entry})).
-else.
-define(SEND(Entry), gen_server:cast(?MODULE, {log, Entry})).
-endif.
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
reconfigure() ->
gen_server:call(?MODULE, reconfigure).
log(Entry) ->
?SEND(Entry).
init(_) ->
process_flag(trap_exit, true),
{ok, #st{
writer = couch_log_writer:init()
}}.
terminate(Reason, St) ->
ok = couch_log_writer:terminate(Reason, St#st.writer).
handle_call(reconfigure, _From, St) ->
ok = couch_log_writer:terminate(reconfiguring, St#st.writer),
{reply, ok, St#st{
writer = couch_log_writer:init()
}};
handle_call({log, Entry}, _From, St) ->
% We re-check if we should log here in case an operator
% adjusted the log level and then realized it was a bad
% idea because it filled our message queue.
case couch_log_util:should_log(Entry) of
true ->
NewWriter = couch_log_writer:write(Entry, St#st.writer),
{reply, ok, St#st{writer = NewWriter}};
false ->
{reply, ok, St}
end;
handle_call(Ignore, From, St) ->
Args = [?MODULE, Ignore],
Entry = couch_log_formatter:format(error, ?MODULE, "~s ignored ~p", Args),
handle_call({log, Entry}, From, St).
handle_cast(Msg, St) ->
{reply, ok, NewSt} = handle_call(Msg, nil, St),
{noreply, NewSt}.
handle_info(Msg, St) ->
{reply, ok, NewSt} = handle_call(Msg, nil, St),
{noreply, NewSt}.
code_change(_Vsn, St, _Extra) ->
{ok, St}.