diff options
author | Alexey Shchepin <alexey@process-one.net> | 2003-10-23 19:20:56 +0000 |
---|---|---|
committer | Alexey Shchepin <alexey@process-one.net> | 2003-10-23 19:20:56 +0000 |
commit | e91a755fd9d8121be863ec43cb6ef0b8873d12ac (patch) | |
tree | 9266dfa7f0e4a56e58c7577ea3e347d131b5d54e /src | |
parent | * src/Makefile.in: Added install rule (diff) |
* src/ejabberd_logger_h.erl: New error_logger handler
* src/ejabberd_app.erl: Now uses ejabberd_logger_h.erl
SVN Revision: 158
Diffstat (limited to 'src')
-rw-r--r-- | src/ejabberd_app.erl | 3 | ||||
-rw-r--r-- | src/ejabberd_logger_h.erl | 180 |
2 files changed, 182 insertions, 1 deletions
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index c4908c73b..81640a602 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -50,7 +50,8 @@ start() -> init() -> register(ejabberd, self()), %erlang:system_flag(fullsweep_after, 0), - error_logger:logfile({open, ?LOG_PATH}), + %error_logger:logfile({open, ?LOG_PATH}), + error_logger:add_report_handler(ejabberd_logger_h, ?LOG_PATH), %timer:apply_interval(3600000, ?MODULE, dump_ports, []), ok = erl_ddll:load_driver(".", expat_erl), Port = open_port({spawn, expat_erl}, [binary]), diff --git a/src/ejabberd_logger_h.erl b/src/ejabberd_logger_h.erl new file mode 100644 index 000000000..213f8fed5 --- /dev/null +++ b/src/ejabberd_logger_h.erl @@ -0,0 +1,180 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_logger_h.erl +%%% Author : Alexey Shchepin <alexey@sevcom.net> +%%% Purpose : +%%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@sevcom.net> +%%%---------------------------------------------------------------------- + +-module(ejabberd_logger_h). +-author('alexey@sevcom.net'). + +%%-compile(export_all). +%%-export([Function/Arity, ...]). + +-behaviour(gen_event). + +%% gen_event callbacks +-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, + code_change/3]). + +-record(state, {fd, file}). + +%%%---------------------------------------------------------------------- +%%% Callback functions from gen_event +%%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Func: init/1 +%% Returns: {ok, State} | +%% Other +%%---------------------------------------------------------------------- +init(File) -> + case file:open(File, [append]) of + {ok, Fd} -> + {ok, #state{fd = Fd, file = File}}; + Error -> + Error + end. + +%%---------------------------------------------------------------------- +%% Func: handle_event/2 +%% Returns: {ok, State} | +%% {swap_handler, Args1, State1, Mod2, Args2} | +%% remove_handler +%%---------------------------------------------------------------------- +handle_event(Event, State) -> + write_event(State#state.fd, {erlang:localtime(), Event}), + {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({'EXIT', _Fd, _Reason}, _State) -> + remove_handler; +handle_info({emulator, GL, Chars}, State) -> + write_event(State#state.fd, {erlang:localtime(), {emulator, GL, Chars}}), + {ok, State}; +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 +%%%---------------------------------------------------------------------- + +% Copied from erlang_logger_file_h.erl +write_event(Fd, {Time, {error, _GL, {Pid, Format, Args}}}) -> + T = write_time(Time), + case catch io_lib:format(add_node(Format,Pid), Args) of + S when list(S) -> + io:format(Fd, T ++ S, []); + _ -> + F = add_node("ERROR: ~p - ~p~n", Pid), + io:format(Fd, T ++ F, [Format,Args]) + end; +write_event(Fd, {Time, {emulator, _GL, Chars}}) -> + T = write_time(Time), + case catch io_lib:format(Chars, []) of + S when list(S) -> + io:format(Fd, T ++ S, []); + _ -> + io:format(Fd, T ++ "ERROR: ~p ~n", [Chars]) + end; +write_event(Fd, {Time, {info, _GL, {Pid, Info, _}}}) -> + T = write_time(Time), + io:format(Fd, T ++ add_node("~p~n",Pid),[Info]); +write_event(Fd, {Time, {error_report, _GL, {Pid, std_error, Rep}}}) -> + T = write_time(Time), + S = format_report(Rep), + io:format(Fd, T ++ S ++ add_node("", Pid), []); +write_event(Fd, {Time, {info_report, _GL, {Pid, std_info, Rep}}}) -> + T = write_time(Time, "INFO REPORT"), + S = format_report(Rep), + io:format(Fd, T ++ S ++ add_node("", Pid), []); +write_event(Fd, {Time, {info_msg, _GL, {Pid, Format, Args}}}) -> + T = write_time(Time, "INFO REPORT"), + case catch io_lib:format(add_node(Format,Pid), Args) of + S when list(S) -> + io:format(Fd, T ++ S, []); + _ -> + F = add_node("ERROR: ~p - ~p~n", Pid), + io:format(Fd, T ++ F, [Format,Args]) + end; +write_event(_, _) -> + ok. + +format_report(Rep) when list(Rep) -> + case string_p(Rep) of + true -> + io_lib:format("~s~n",[Rep]); + _ -> + format_rep(Rep) + end; +format_report(Rep) -> + io_lib:format("~p~n",[Rep]). + +format_rep([{Tag,Data}|Rep]) -> + io_lib:format(" ~p: ~p~n",[Tag,Data]) ++ format_rep(Rep); +format_rep([Other|Rep]) -> + io_lib:format(" ~p~n",[Other]) ++ format_rep(Rep); +format_rep(_) -> + []. + +add_node(X, Pid) when atom(X) -> + add_node(atom_to_list(X), Pid); +add_node(X, Pid) when node(Pid) /= node() -> + lists:concat([X,"** at node ",node(Pid)," **~n"]); +add_node(X, _) -> + X. + +string_p([]) -> + false; +string_p(Term) -> + string_p1(Term). + +string_p1([H|T]) when integer(H), H >= $\s, H < 255 -> + string_p1(T); +string_p1([$\n|T]) -> string_p1(T); +string_p1([$\r|T]) -> string_p1(T); +string_p1([$\t|T]) -> string_p1(T); +string_p1([$\v|T]) -> string_p1(T); +string_p1([$\b|T]) -> string_p1(T); +string_p1([$\f|T]) -> string_p1(T); +string_p1([$\e|T]) -> string_p1(T); +string_p1([H|T]) when list(H) -> + case string_p1(H) of + true -> string_p1(T); + _ -> false + end; +string_p1([]) -> true; +string_p1(_) -> false. + +write_time(Time) -> write_time(Time, "ERROR REPORT"). + +write_time({{Y,Mo,D},{H,Mi,S}}, Type) -> + io_lib:format("~n=~s==== ~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w ===~n", + [Type, Y, Mo, D, H, Mi, S]). + |