1 %%%-------------------------------------------------------------------
2 %%% File : etorrent_file_logger.erl
3 %%% Author : Jesper Louis Andersen <>
4 %%% Description : Log to a file. Loosely based on log_mf_h from the
5 %%% erlang distribution
7 %%% Created : 9 Jul 2008 by Jesper Louis Andersen <>
8 %%%-------------------------------------------------------------------
9 -module(etorrent_file_logger
).
13 -behaviour(gen_event
).
15 -export([init
/3, init
/2]).
17 -export([init
/1, handle_event
/2, handle_info
/2, terminate
/2]).
18 -export([handle_call
/2, code_change
/3]).
20 -record(state
, {dir
, fname
, cur_fd
, pred
}).
22 %%%-----------------------------------------------------------------
23 %%% This module implements an event handler that writes events
24 %%% to a single logfile.
25 %%%-----------------------------------------------------------------
27 %% Args: EventMgr = pid() | atom()
29 %% Filename = string()
30 %% Pred = fun(Event) -> boolean()
31 %% Purpose: An event handler. Writes binary events
32 %% to file Filename in the directory Dir.
33 %% Each event is filtered with the predicate function Pred.
34 %% Reports can be browsed with Report Browser Tool (rb).
35 %% Returns: Args = term()
36 %% The Args term should be used in a call to
37 %% gen_event:add_handler(EventMgr, log_mf_h, Args).
38 %%-----------------------------------------------------------------
39 init(Dir
, Filename
) -> init(Dir
, Filename
, fun(_
) -> true
end).
40 init(Dir
, Filename
, Pred
) -> {Dir
, Filename
, Pred
}.
42 %%-----------------------------------------------------------------
43 %% Call-back functions from gen_event
44 %%-----------------------------------------------------------------
45 init({Dir
, Filename
, Pred
}) ->
46 case catch file_open(Dir
, Filename
) of
47 {ok
, Fd
} -> {ok
, #state
{ dir
= Dir
, fname
= Filename
,
48 cur_fd
= Fd
, pred
= Pred
}};
52 handle_event(Event
, S
) ->
53 Date
= date_str(erlang:localtime()),
54 #state
{dir
= _Dir
, fname
= _Fname
, cur_fd
= _CurFd
, pred
= Pred
} = S
,
55 case catch Pred(Event
) of
57 io:format(S#state
.cur_fd
, "~s : ~p~n", [Date
, Event
]),
63 handle_info(_
, State
) ->
66 terminate(_
, State
) ->
67 case file:close(State#state
.cur_fd
) of
69 {error
, R
} -> ?
log([cant_close_file
,{reason
, R
}]), State
72 handle_call(null
, State
) ->
75 code_change(_OldVsn
, State
, _Extra
) ->
78 %%-----------------------------------------------------------------
80 %%-----------------------------------------------------------------
81 file_open(Dir
, Fname
) ->
82 {ok
, FD
} = file:open(filename:join(Dir
, Fname
), [append
]),
85 date_str({{Y
, Mo
, D
}, {H
, Mi
, S
}}) ->
86 lists:flatten(io_lib:format("~w-~2.2.0w-~2.2.0w ~2.2.0w:"