aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2003-10-23 19:20:56 +0000
committerAlexey Shchepin <alexey@process-one.net>2003-10-23 19:20:56 +0000
commite91a755fd9d8121be863ec43cb6ef0b8873d12ac (patch)
tree9266dfa7f0e4a56e58c7577ea3e347d131b5d54e /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.erl3
-rw-r--r--src/ejabberd_logger_h.erl180
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]).
+