next major version. uses the latest CouchDb PHP Library. Lots of interface goodies...
[couchdbimport.git] / CouchProjects / CouchDb / couch_log.erl
blob49a5886b780378267c16d89944e3ae37fa1b58c8
1 %% CouchDb
2 %% Copyright (C) 2006 Damien Katz
3 %%
4 %% This program is free software; you can redistribute it and/or
5 %% modify it under the terms of the GNU General Public License
6 %% as published by the Free Software Foundation; either version 2
7 %% of the License, or (at your option) any later version.
8 %%
9 %% This program is distributed in the hope that it will be useful,
10 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
11 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 %% GNU General Public License for more details.
13 %%
14 %% You should have received a copy of the GNU General Public License
15 %% along with this program; if not, write to the Free Software
16 %% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 -module(couch_log).
19 -behaviour(gen_event).
21 -export([start/2, stop/0]).
22 -export([error/1,error/2,info/1,info/2,debug/1,debug/2]).
23 -export([init/1, handle_event/2, terminate/2, code_change/3, handle_info/2, handle_call/2]).
25 -define(LEVEL_ERROR, 3).
26 -define(LEVEL_INFO, 2).
27 -define(LEVEL_DEBUG, 1).
28 -define(LEVEL_TMI, 0).
30 level_integer(error) -> ?LEVEL_ERROR;
31 level_integer(info) -> ?LEVEL_INFO;
32 level_integer(debug) -> ?LEVEL_DEBUG;
33 level_integer(tmi) -> ?LEVEL_TMI;
34 level_integer(_Else) -> ?LEVEL_ERROR. % anything else default to ERROR level
37 start(Filename, Level) ->
38 % delete first so we don't wind up with multiple if called multiple times
39 % (happens during debugging)
40 error_logger:delete_report_handler(couch_log),
41 error_logger:add_report_handler(couch_log, {Filename, Level}).
43 stop() ->
44 error_logger:delete_report_handler(couch_log).
46 init({Filename, Level}) ->
47 {ok, Fd} = file:open(Filename, [append]),
48 {ok, {Fd, level_integer(Level)}}.
50 get_level_integer() ->
51 catch gen_event:call(error_logger, couch_log, get_level_integer).
53 error(Msg) ->
54 error("~s", [Msg]).
56 error(Format, Args) ->
57 error_logger:error_report(couch_error, {Format, Args}).
59 info(Msg) ->
60 info("~s", [Msg]).
62 info(Format, Args) ->
63 case get_level_integer() =< ?LEVEL_INFO of
64 true ->
65 error_logger:info_report(couch_info, {Format, Args});
66 false ->
68 end.
70 debug(Msg) ->
71 debug("~s", [Msg]).
73 debug(Format, Args) ->
74 case get_level_integer() =< ?LEVEL_DEBUG of
75 true ->
76 error_logger:info_report(couch_debug, {Format, Args});
77 false ->
79 end.
81 handle_event({error_report, _, {Pid, couch_error, {Format, Args}}}, {Fd, _LogLevel}=State) ->
82 log(Fd, Pid, error, Format, Args),
83 {ok, State};
84 handle_event({error_report, _, {Pid, _, _}}=Event, {Fd, _LogLevel}=State) ->
85 log(Fd, Pid, error, "~p", [Event]),
86 {ok, State};
87 handle_event({error, _, {Pid, Format, Args}}, {Fd, _LogLevel}=State) ->
88 log(Fd, Pid, error, Format, Args),
89 {ok, State};
90 handle_event({info_report, _, {Pid, couch_info, {Format, Args}}}, {Fd, LogLevel}=State)
91 when LogLevel =< ?LEVEL_INFO ->
92 log(Fd, Pid, info, Format, Args),
93 {ok, State};
94 handle_event({info_report, _, {Pid, couch_debug, {Format, Args}}}, {Fd, LogLevel}=State)
95 when LogLevel =< ?LEVEL_DEBUG ->
96 log(Fd, Pid, debug, Format, Args),
97 {ok, State};
98 handle_event({_, _, {Pid, _, _}}=Event, {Fd, LogLevel}=State)
99 when LogLevel =< ?LEVEL_TMI ->
100 % log every remaining event if tmi!
101 log(Fd, Pid, tmi, "~p", [Event]),
102 {ok, State};
103 handle_event(_Event, State) ->
104 {ok, State}.
106 handle_call(get_level_integer, {_Fd, LogLevel}=State) ->
107 {ok, LogLevel, State}.
109 handle_info(_Info, State) ->
110 {ok, State}.
112 code_change(_OldVsn, State, _Extra) ->
113 {ok, State}.
115 terminate(_Arg, {Fd, _LoggingLevel}) ->
116 file:close(Fd).
118 log(Fd, Pid, Level, Format, Args) ->
119 case (catch log_guts(Fd, Pid, Level, Format, Args)) of
120 ok -> ok;
121 Error ->
122 ErrorFormat = "\r~n***************** ERROR OCCURED DURING LOGGING: *****************\r~n~p\r~n",
123 io:format(ErrorFormat, [Error]),
124 io:format(Fd, ErrorFormat, [Error])
125 end.
127 log_guts(Fd, Pid, Level, Format, Args) ->
128 Msg = io_lib:format(Format, Args),
129 ok = io:format("[~s] [~p] ~s~n", [Level, Pid, Msg]), % dump to console too
130 {ok, Msg2, _} = regexp:gsub(lists:flatten(Msg),"\\r\\n|\\r|\\n", "\r\n"),
131 ok = io:format(Fd, "[~s] [~s] [~p] ~s\r~n\r~n", [httpd_util:rfc1123_date(), Level, Pid, Msg2]).