erlang⽇志功能。
⽤cowboy这个库,没有⽇志功能,所以研究了otp提供的⽇志功能。
1.启动SASL的⽅式
erl –boot start_sasl 默认配置⽂件下启动SASL, {env, [{sasl_error_logger, tty},{errlog_type, all}]},,见源码 sasl.app⽂件。
erl -boot start_sasl -fig 启动指定配置⽂件例如 fig ,fig 。。。配置⽂件默认⽬录是ebin,可⾃⼰指定⽬录。
还可以⽤ application:start(sasl). 在代码⾥启动应⽤。默认会读取代码ebin下的sasl.app,可去源码复制⼀份sasl.app然后修改 env参数。
sasl是通过application:get_env(sasl,xxx) 获得配置信息。
2、sasl配置⽂件:
{env, [{sasl_error_logger, {file,"../../logs/error_logs/THELOG"}},%将sasl信息输出到⽂件中(不记录error_l
ogger发送的信息)。另外,tty :输出sasl信息到shell中(默认配置),false:不输出sasl信息。 {errlog_type, all}, %过滤sasl_error_logger中的输出信息(error,progress)
{error_logger_mf_dir,"../../logs/error_logs"}, %循环⽇志路径(记录sasl信息以及error_logger发送的信息)。
{error_logger_mf_maxbytes,10485760}, %限定单个⽇志⼤⼩。
{error_logger_mf_maxfiles,10} %限定⽇志个数。
]}
3、error_logger:
参考
设置⽇志error_logger输出⽇志到⽂件:error_logger:logfile({open,Filename}).
注: 每次执⾏error_logger:logfile({open,Filename}).都会删掉之前Filename⽂件。
4、⾃定义⽇志功能:
由于业务需要,我想按照⽇期切分⽇志,该⽇志主要是为了记录业务操作。
思路:每次写⽇志到⽇志⽂件,先判断⽇志⽂件的最新修改⽇期是否跟当前⽇期⼀致,不⼀致就对该⽇志⽂件重命名(后缀添加⽇期),并重新创建⽇志⽂件。l:
-module(daylog_app).
-behaviour(application).
-export([init/1]).
-export([start/0,start/2,stop/1]).
-define(SERVER,?MODULE).
-define(LOGFILE,"info.log").
start() ->
application:start(daylog).
start(_StartType,_StartArgs) ->
LogFile = get_app_env(log_file,?LOGFILE),
supervisor:start_link({local,?SERVER},?MODULE,[daylog,LogFile]).
stop(_State) ->
ok.
init([Module,LogFile]) ->
Element = {Module,{Module,start_link,[LogFile]},
temporary,2000,worker,[Module]}, %%如何启动和管理⼦进程
Children = [Element] ,
RestartStrategy = {one_for_one,0,1}, %%重启策略
{ok,{RestartStrategy,Children}}. %%监督规范
%%----------------------------------------------------------------------
%% Internal functions
%%----------------------------------------------------------------------
get_app_env(Opt, Default) ->
case application:get_env(daylog, Opt) of
{ok, Val} -> Val;
_ ->
case init:get_argument(Opt) of
[[Val | _]] -> Val;
error -> Default
end
server error啥意思end.
%%%-------------------------------------------------------------------
%%% Author : kingson <kingsoncai2013@gmail>
%%% Description : Cutting logs every day.
%%%
%%% Created : 4 Mar 2015 by kingson <kingsoncai2013@gmail>
%%%-------------------------------------------------------------------
-module(daylog).
-behaviour(gen_server).
%% API
%% gen_server callbacks
-
export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([add_logfiles/1,info_log/1,info_log/2,logger/2,logger/3]).
-define(SERVER,?MODULE).
-record(state, {filename,other_files}).
add_logfiles(Files) ->
gen_server:cast(?SERVER,{add_logfile,Files}).
info_log(Msg) -> %通知类型⽇志(默认)
info_log(Msg,[]).
info_log(Format,Data) ->
gen_server:cast(?SERVER,{accept,Format,Data}).
logger(FileName,Msg) ->
logger(FileName,Msg,[]).
logger(FileName,Format,Data) ->
gen_server:cast(?SERVER,{accept,FileName,Format,Data}).
%%==================================================================== %% API
%%==================================================================== %%--------------------------------------------------------------------
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the server
%%--------------------------------------------------------------------
start_link(LogFile) when is_list(LogFile) ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [LogFile], []).
%%==================================================================== %% gen_server callbacks
%%==================================================================== %%--------------------------------------------------------------------
%% Function: init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
init([LogFile]) ->
process_flag(trap_exit, true),
{ok,F} = file:open(LogFile,[append]),
put(LogFile,F),
{ok, #state{filename=LogFile},0}.
%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling cast messages
%%--------------------------------------------------------------------
handle_cast({accept,Format,Data}, #state{filename=FileName}=State) ->
write(Format,Data,FileName),
{noreply, State};
handle_cast({accept,FileName,Format,Data},State) ->
write(Format,Data,FileName),
{noreply,State};
handle_cast({add_logfile,LogFiles},State) ->
open_files(LogFiles),
State2 = State#state{other_files=LogFiles},
{noreply,State2};
handle_cast(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info(timeout, State) ->
gen_server:cast(?SERVER,{accept,"Has started daylog application~n",[]}),
{noreply, State};
handle_info(_Info, State) ->
%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, State) ->
#state{filename=FileName,other_files=OtherFiles} = State,
close_files(OtherFiles),
F = get(FileName),
io:format("Has stoped daylog application~n"),
io:format(F,"Has stoped daylog application~n",[]),
file:close(F),
ok.
%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
write(Format,Data,Filename) ->
LocalTime = calendar:local_time(),
case filelib:last_modified(Filename) of
{Last_Modified_Date,_} ->
{Today,_} = LocalTime,
{Date_diff,_} = calendar:time_difference({Last_Modified_Date,{0,0,0}},{Today,{0,0,0}}),
if Date_diff /= 0 -> %not the same date
{Y,M,D} = Last_Modified_Date,
Newname = Filename ++ "." ++ integer_to_list(Y) ++ "-" ++ integer_to_list(M) ++ "-" ++ integer_to_list(D), file:close(get(Filename)),
file:rename(Filename,Newname),
{ok,F} = file:open(Filename,[append]),
put(Filename,F);
true -> false
end;
0 -> false % the file does not exist.
end,
FileHandle = get(Filename),
{{Year,Month,Day},{Hour,Minute,Second}} = LocalTime,
do_write(FileHandle,"[~p-~p-~p T ~p:~p:~p] ", [Year,Month,Day,Hour,Minute,Second]),
Format2 = Format ++ "~n",
do_write(FileHandle,Format2,Data).
do_write(FileHandle,Format,Data) ->
io:format(Format, Data),
io:format(FileHandle,Format,Data).
open_files([]) ->
ok;
open_files([File|Others]) ->
{ok,FileHandle} = file:open(File,[append]),
put(File,FileHandle),
open_files(Others).
close_files([]) ->
ok;
close_files([File|Others]) ->
FileHandle = get(File),
file:close(FileHandle),
close_files(Others).
daylog.app
{application,daylog, %%应⽤名
[ {description,""},
{vsn,"0.1.0"},
{modules,[]}, %%应⽤中的模块,可留空。
{registered,[]}, %%进程注册名,没进⾏实际注册操作,⽤于告知otp系统哪个进程注册了哪个名字,可留空
{applications,[kernel,stdlib]}, %%先⾏启动的所有应⽤,不能留空
{mod,{daylog_app,[]}}, %%指定应⽤启动模块,不能留空
{env,[{log_file,"../../logs/info.log"}]}
]}.
compile.sh
for f in *.erl;do erlc +debug_info -o ../ebin $f;done
<
API Reference:
Module:daylog
add_logfiles(Files):
Types:
Files : a list for filenames
info_log(Msg):
Types:
Msg: string
descript:output log to default file which is descripted in ebin/daylog.app. info_log(Format,Datas)
Types:
Format: string
Datas: list for data
logger(FileName,Msg) ->
Types:
FileName: string
Msg: String
logger(FileName,Format,Datas) ->
Types:
FileName: string
Format: string
Datas: list for data
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论