1%%%-------------------------------------------------------------------
2%%% File    : yaws_log_file_h.erl
3%%% Author  :  <klacke@hyber.org>
4%%% Description :
5%%%
6%%% Created : 11 Mar 2004 by  <klacke@hyber.org>
7%%%-------------------------------------------------------------------
8
9
10%% Just extending the error_logger_file_h abit,
11%% If they change the internals of that module, this module
12%% breaks, but then again, the otp crew doesn't ever appear to
13%% change anything that might break anything .....
14
15-module(yaws_log_file_h).
16-behaviour(gen_event).
17-include_lib("kernel/include/file.hrl").
18
19-export([init/1,
20         handle_event/2, handle_call/2, handle_info/2,
21         terminate/2, code_change/3]).
22
23
24
25%% This one is used when we are started directly.
26init(File) ->
27    process_flag(trap_exit, true),
28    {ok, [Major,Minor], _} = io_lib:fread("~d.~d", erlang:system_info(version)),
29    case file:open(File, [append]) of
30        {ok, Fd} when {Major,Minor} < {7,1} ->  %% Pre 18.1
31            {ok, {Fd, File, []}};
32        {ok, Fd} ->                             %% Post 18.1
33            {ok, {st, Fd, File, [], unlimited}};
34        Error ->
35            error_logger:error_msg(
36              "Failed to set Yaws error report handler: ~p~n", [Error]
37             ),
38            Error
39    end.
40
41%% Pre 18.1
42handle_call(reopen, {Fd, File, Prev}) ->
43    {ok, ok, {reopen(Fd,File), File, Prev}};
44handle_call(wrap, {Fd, File, Prev}) ->
45    {ok, ok, {wrap(Fd,File), File, Prev}};
46handle_call(size, {Fd, File, Prev}) ->
47    {ok, size(Fd,File), {Fd, File, Prev}};
48
49%% Post 18.1
50handle_call(reopen, {st, Fd, File, Prev, Depth}) ->
51    {ok, ok, {st, reopen(Fd,File), File, Prev, Depth}};
52handle_call(wrap, {st, Fd, File, Prev, Depth}) ->
53    {ok, ok, {st, wrap(Fd,File), File, Prev, Depth}};
54handle_call(size, {st, Fd, File, Prev, Depth}) ->
55    {ok, size(Fd,File), {st, Fd, File, Prev, Depth}};
56
57handle_call(X, S) ->
58    error_logger_file_h:handle_call(X,S).
59
60
61handle_event(X, S) ->
62    error_logger_file_h:handle_event(X, S).
63handle_info(X, S) ->
64    error_logger_file_h:handle_info(X, S).
65
66
67terminate(Reason, State) ->
68    error_logger_file_h:terminate(Reason, State).
69
70code_change(_OldVsn, State, _Extra) ->
71    {ok, State}.
72
73
74reopen(Fd, File) ->
75    file:close(Fd),
76    {ok, Fd2} = file:open(File, [write,append]),
77    Fd2.
78
79wrap(Fd, File) ->
80    Old = File ++ ".old",
81    file:delete(Old),
82    file:close(Fd),
83    file:rename(File, Old),
84    {ok, Fd2} = file:open(File, [write,append]),
85    Fd2.
86
87size(Fd, File) ->
88    file:sync(Fd),
89    case file:read_file_info(File) of
90        {ok, FI} -> {ok, FI#file_info.size};
91        Error    -> Error
92    end.
93