mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-26 16:26:24 +01:00
Added accesslog parameter to record requests log in a file similar to Apache (thanks to Jerome Sautret)
SVN Revision: 2184
This commit is contained in:
parent
487b80b9b0
commit
b57248e822
@ -15,14 +15,16 @@
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([
|
||||
start/2,
|
||||
stop/1,
|
||||
process/2
|
||||
start/2,
|
||||
stop/1,
|
||||
process/2,
|
||||
ctl_process/2
|
||||
]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("ejabberd_ctl.hrl").
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% REQUEST HANDLERS
|
||||
@ -30,7 +32,7 @@
|
||||
|
||||
%%-----------------------------------------------------------------------
|
||||
%% FUNCTION
|
||||
%%
|
||||
%%
|
||||
%% process/2
|
||||
%%
|
||||
%% PURPOSE
|
||||
@ -48,8 +50,21 @@
|
||||
%%
|
||||
%%-----------------------------------------------------------------------
|
||||
|
||||
process(LocalPath, _Request) ->
|
||||
|
||||
process(LocalPath, Request) ->
|
||||
?DEBUG("Requested ~p", [LocalPath]),
|
||||
|
||||
Result = serve(LocalPath),
|
||||
case ets:lookup(mod_http_fileserver, accessfile) of
|
||||
undefined ->
|
||||
ok;
|
||||
[{accessfile, AccessFile}] ->
|
||||
{Code, _, _} = Result,
|
||||
log(AccessFile, Code, Request)
|
||||
end,
|
||||
Result.
|
||||
|
||||
serve(LocalPath) ->
|
||||
[{docroot, DocRoot}] = ets:lookup(mod_http_fileserver, docroot),
|
||||
FileName = filename:join(filename:split(DocRoot) ++ LocalPath),
|
||||
case file:read_file(FileName) of
|
||||
@ -68,11 +83,40 @@ process(LocalPath, _Request) ->
|
||||
end
|
||||
end.
|
||||
|
||||
ctl_process(_Val, ["reopen-weblog"]) ->
|
||||
mod_http_fileserver_server ! reopenlog,
|
||||
?STATUS_SUCCESS;
|
||||
ctl_process(Val, _Args) ->
|
||||
Val.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% UTILITIES
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
join([], _) ->
|
||||
"";
|
||||
join([E], _) ->
|
||||
E;
|
||||
join([H | T], Separator) ->
|
||||
lists:foldl(fun(E, Acc) -> lists:concat([Acc, Separator, E]) end, H, T).
|
||||
|
||||
log(File, Code, Request) ->
|
||||
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(),
|
||||
IP = join(tuple_to_list(Request#request.ip), "."),
|
||||
Path = join(Request#request.path, "/"),
|
||||
Query = case join(lists:map(fun(E) -> lists:concat([element(1, E), "=", element(2, E)]) end,
|
||||
Request#request.q), "&") of
|
||||
[] ->
|
||||
"";
|
||||
String ->
|
||||
[$? | String]
|
||||
end,
|
||||
% combined apache like log format :
|
||||
% 127.0.0.1 - - [28/Mar/2007:18:41:55 +0200] "GET / HTTP/1.1" 302 303 "-" "tsung"
|
||||
% XXX TODO some fields are harcoded/missing (reply size, user agent or referer for example)
|
||||
io:format(File, "~p - - [~p/~p/~p:~p:~p:~p] \"~s /~s~s\" ~p -1 \"-\" \"-\"~n",
|
||||
[IP, Day, Month, Year, Hour, Minute, Second, Request#request.method, Path, Query, Code]).
|
||||
|
||||
content_type(Filename) ->
|
||||
case httpd_util:to_lower(filename:extension(Filename)) of
|
||||
".jpg" -> "image/jpeg";
|
||||
@ -88,25 +132,78 @@ content_type(Filename) ->
|
||||
_Else -> "application/octet-stream"
|
||||
end.
|
||||
|
||||
open_file(Filename) ->
|
||||
case file:open(Filename, [append]) of
|
||||
{ok, File} ->
|
||||
ets:insert(mod_http_fileserver, {accessfile, File}),
|
||||
ok;
|
||||
{error, _Reason} ->
|
||||
{'EXIT', {unaccessible_accessfile, ?MODULE}}
|
||||
end.
|
||||
|
||||
loop(Filename) ->
|
||||
receive
|
||||
reopenlog ->
|
||||
case ets:lookup(mod_http_fileserver, accessfile) of
|
||||
undefined ->
|
||||
ok;
|
||||
[{accessfile, AccessFile}] ->
|
||||
file:close(AccessFile),
|
||||
case open_file(Filename) of
|
||||
ok ->
|
||||
ok;
|
||||
_ ->
|
||||
error
|
||||
end
|
||||
end,
|
||||
loop(Filename);
|
||||
stop ->
|
||||
ok
|
||||
end.
|
||||
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% BEHAVIOUR CALLBACKS
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
start(_Host, Opts) ->
|
||||
ejabberd_ctl:register_commands([{"reopen-weblog", "reopen http fileserver log file"}],
|
||||
?MODULE, ctl_process),
|
||||
case gen_mod:get_opt(docroot, Opts, undefined) of
|
||||
undefined ->
|
||||
{'EXIT', {missing_document_root, ?MODULE}};
|
||||
DocRoot ->
|
||||
case filelib:is_dir(DocRoot) of
|
||||
true ->
|
||||
ets:new(mod_http_fileserver, [named_table, bag]),
|
||||
% XXX WARNING, using a single ets table name will
|
||||
% not work with virtual hosts
|
||||
ets:new(mod_http_fileserver, [named_table, public]),
|
||||
ets:insert(mod_http_fileserver, [{docroot, DocRoot}]),
|
||||
ok;
|
||||
case gen_mod:get_opt(accesslog, Opts, undefined) of
|
||||
undefined ->
|
||||
ok;
|
||||
Filename ->
|
||||
% XXX same remark as above for proc name
|
||||
register(mod_http_fileserver_server, spawn(?MODULE, loop, [Filename])),
|
||||
open_file(Filename)
|
||||
end;
|
||||
_Else ->
|
||||
{'EXIT', {unaccessible_document_root, ?MODULE}}
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
case ets:info(mod_http_fileserver, name) of
|
||||
undefined ->
|
||||
ok;
|
||||
_ ->
|
||||
case ets:lookup(mod_http_fileserver, accessfile) of
|
||||
undefined ->
|
||||
ok;
|
||||
[{accessfile, AccessFile}] ->
|
||||
mod_http_fileserver_server ! stop,
|
||||
file:close(AccessFile)
|
||||
end,
|
||||
ets:delete(mod_http_fileserver)
|
||||
end,
|
||||
ok.
|
||||
|
Loading…
Reference in New Issue
Block a user