|
|
@ -1,32 +1,36 @@ |
|
|
|
%% @doc Lager crash log writer. This module implements a gen_server which writes |
|
|
|
%% error_logger error messages out to a file in their original format. The |
|
|
|
%% location to which it logs is configured by the application var `crash_log'. |
|
|
|
%% Omitting this variable disables crash logging. Crash logs are printed safely |
|
|
|
%% using trunc_io via code mostly lifted from riak_err. |
|
|
|
-module(rumCrashLog). |
|
|
|
%% @doc eRum crash log writer。它将error_logger错误消息以其原始格式发送到`crash_log`指定的文件, 如果`crash_log`未设置则禁用crash logging |
|
|
|
%% Crash logs are printed safely using trunc_io via code mostly lifted from riak_err. |
|
|
|
%% |
|
|
|
%% The `crash_log_msg_size' application var is used to specify the maximum |
|
|
|
%% size of any message to be logged. `crash_log_size' is used to specify the |
|
|
|
%% maximum size of the crash log before it will be rotated (0 will disable). |
|
|
|
%% Time based rotation is configurable via `crash_log_date', the syntax is |
|
|
|
%% documented in the README. To control the number of rotated files to be |
|
|
|
%% retained, use `crash_log_count'. |
|
|
|
%% `crash_log_msg_size` 应用程序var用于指定最大值要记录的任何消息的大小。 |
|
|
|
%% `crash_log_size` 用于指定崩溃日志的最大大小,然后将其旋转(0将禁用)。 |
|
|
|
%% `crash_log_date` 基于时间的轮播可通过配置,语法为自述文件中记录了 |
|
|
|
%% `crash_log_count` 控制要旋转的文件数已保留。 |
|
|
|
|
|
|
|
-module(rumCrashLog). |
|
|
|
-behaviour(gen_srv). |
|
|
|
|
|
|
|
-include("eRum.hrl"). |
|
|
|
|
|
|
|
-behaviour(gen_server). |
|
|
|
|
|
|
|
-ifdef(TEST). |
|
|
|
-include_lib("eunit/include/eunit.hrl"). |
|
|
|
-include_lib("kernel/include/file.hrl"). |
|
|
|
-endif. |
|
|
|
|
|
|
|
%% callbacks |
|
|
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, |
|
|
|
code_change/3]). |
|
|
|
-export([ |
|
|
|
start/6 |
|
|
|
, start_link/6 |
|
|
|
|
|
|
|
]). |
|
|
|
|
|
|
|
-export([ |
|
|
|
init/1 |
|
|
|
, handleCall/3 |
|
|
|
, handleCast/2 |
|
|
|
, handleInfo/2 |
|
|
|
, terminate/2 |
|
|
|
, code_change/3 |
|
|
|
]). |
|
|
|
|
|
|
|
-export([start_link/6, start/6]). |
|
|
|
|
|
|
|
-record(state, { |
|
|
|
name :: string(), |
|
|
@ -41,53 +45,45 @@ |
|
|
|
rotator :: atom() |
|
|
|
}). |
|
|
|
|
|
|
|
%% @private |
|
|
|
start_link(Filename, MaxBytes, Size, Date, Count, Rotator) -> |
|
|
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [Filename, MaxBytes, |
|
|
|
Size, Date, Count, Rotator], []). |
|
|
|
|
|
|
|
%% @private |
|
|
|
start(Filename, MaxBytes, Size, Date, Count, Rotator) -> |
|
|
|
gen_server:start({local, ?MODULE}, ?MODULE, [Filename, MaxBytes, Size, |
|
|
|
Date, Count, Rotator], []). |
|
|
|
gen_srv:start({local, ?MODULE}, ?MODULE, {Filename, MaxBytes, Size, Date, Count, Rotator}, []). |
|
|
|
|
|
|
|
%% @private |
|
|
|
init([RelFilename, MaxBytes, Size, Date, Count, Rotator]) -> |
|
|
|
start_link(Filename, MaxBytes, Size, Date, Count, Rotator) -> |
|
|
|
gen_srv:start_link({local, ?MODULE}, ?MODULE, {Filename, MaxBytes, Size, Date, Count, Rotator}, []). |
|
|
|
|
|
|
|
init({RelFilename, MaxBytes, Size, Date, Count, Rotator}) -> |
|
|
|
Filename = rumUtil:expand_path(RelFilename), |
|
|
|
case Rotator:open_logfile(Filename, false) of |
|
|
|
{ok, {FD, Inode, Ctime, _Size}} -> |
|
|
|
schedule_rotation(Date), |
|
|
|
{ok, #state{name = Filename, fd = FD, inode = Inode, ctime = Ctime, |
|
|
|
fmtmaxbytes = MaxBytes, size = Size, count = Count, date = Date, |
|
|
|
rotator = Rotator}}; |
|
|
|
{ok, #state{name = Filename, fd = FD, inode = Inode, ctime = Ctime, fmtmaxbytes = MaxBytes, size = Size, count = Count, date = Date, rotator = Rotator}}; |
|
|
|
{error, Reason} -> |
|
|
|
?INT_LOG(error, "Failed to open crash log file ~ts with error: ~s", |
|
|
|
[Filename, file:format_error(Reason)]), |
|
|
|
{ok, #state{name = Filename, fmtmaxbytes = MaxBytes, flap = true, |
|
|
|
size = Size, count = Count, date = Date, rotator = Rotator}} |
|
|
|
{ok, #state{name = Filename, fmtmaxbytes = MaxBytes, flap = true, size = Size, count = Count, date = Date, rotator = Rotator}} |
|
|
|
end. |
|
|
|
|
|
|
|
%% @private |
|
|
|
handle_call({log, _} = Log, _From, State) -> |
|
|
|
handleCall({log, _} = Log, State, _From) -> |
|
|
|
{Reply, NewState} = do_log(Log, State), |
|
|
|
{reply, Reply, NewState}; |
|
|
|
handle_call(_Call, _From, State) -> |
|
|
|
{reply, ok, State}. |
|
|
|
handleCall(_Msg, _State, _From) -> |
|
|
|
?ERR("~p call receive unexpect msg ~p ~n ", [?MODULE, _Msg]), |
|
|
|
{reply, ok}. |
|
|
|
|
|
|
|
%% @private |
|
|
|
handle_cast({log, _} = Log, State) -> |
|
|
|
handleCast({log, _} = Log, State) -> |
|
|
|
{_, NewState} = do_log(Log, State), |
|
|
|
{noreply, NewState}; |
|
|
|
handle_cast(_Request, State) -> |
|
|
|
{noreply, State}. |
|
|
|
handleCast(_Msg, _State) -> |
|
|
|
?ERR("~p cast receive unexpect msg ~p ~n ", [?MODULE, _Msg]), |
|
|
|
kpS. |
|
|
|
|
|
|
|
%% @private |
|
|
|
handle_info(rotate, #state{name = Name, count = Count, date = Date, rotator = Rotator} = State) -> |
|
|
|
handleInfo(rotate, #state{name = Name, count = Count, date = Date, rotator = Rotator}) -> |
|
|
|
_ = Rotator:rotate_logfile(Name, Count), |
|
|
|
schedule_rotation(Date), |
|
|
|
{noreply, State}; |
|
|
|
handle_info(_Info, State) -> |
|
|
|
{noreply, State}. |
|
|
|
kpS; |
|
|
|
handleInfo(_Msg, _State) -> |
|
|
|
?ERR("~p info receive unexpect msg ~p ~n ", [?MODULE, _Msg]), |
|
|
|
kpS. |
|
|
|
|
|
|
|
%% @private |
|
|
|
terminate(_Reason, _State) -> |
|
|
|