erlang应用都会启动一个sasl应用,sasl的一个重要功能便是可以记录系统进程相关日志,如进程启动、结束、崩溃错误等信息。sasl的日志功能是基于erlang自带的日志模块error_logger来实现的. sasl中定义了下面3个错误处理:
sasl_report_tty_h : 将日志输出到控制台 .
sasl_report_file_h : 将日志输出到单个文件
error_logger_mf_h :循环日志文件记录
sasl日志可以通过配置文件来定制,示例
elog.config %% rotating log and minimal tty [{sasl, [ {sasl_error_logger, false}, %% define the parameters of the rotating log %% the log file directory {error_logger_mf_dir,"/home/joe/error_logs" }, %% # bytes per logfile {error_logger_mf_maxbytes,10485760}, % 10 MB %% maximum number of logfiles {error_logger_mf_maxfiles, 10} ]}]. $erl -boot start_sasl -config elog
在sasl.erl模块中注册了日志处理句柄,可以找到代码片断
...... add_sasl_error_logger(undefined, _Type) -> ok; add_sasl_error_logger(Handler, Type) -> error_logger:add_report_handler(mod(Handler), args(Handler, Type)). ...... add_error_logger_mf(undefined) -> ok; add_error_logger_mf({Dir, MaxB, MaxF}) -> error_logger:add_report_handler( log_mf_h, log_mf_h:init(Dir, MaxB, MaxF, fun pred/1)). 在模块sasl_report.erl中可以找到处理输出的代码: is_my_error_report(all, Type) -> is_my_error_report(Type); is_my_error_report(error, Type) -> is_my_error_report(Type); is_my_error_report(_, _Type) -> false. is_my_error_report(supervisor_report) -> true; is_my_error_report(crash_report) -> true; is_my_error_report(_) -> false. is_my_info_report(all, Type) -> is_my_info_report(Type); is_my_info_report(progress, Type) -> is_my_info_report(Type); is_my_info_report(_, _Type) -> false. is_my_info_report(progress) -> true; is_my_info_report(_) -> false. write_report2(IO, Fd, Head, supervisor_report, Report) -> Name = sup_get(supervisor, Report), Context = sup_get(errorContext, Report), Reason = sup_get(reason, Report), Offender = sup_get(offender, Report), FmtString = " Supervisor: ~p~n Context: ~p~n Reason: " "~80.18p~n Offender: ~80.18p~n~n", write_report_action(IO, Fd, Head ++ FmtString, [Name,Context,Reason,Offender]); write_report2(IO, Fd, Head, progress, Report) -> Format = format_key_val(Report), write_report_action(IO, Fd, Head ++ "~s", [Format]); write_report2(IO, Fd, Head, crash_report, Report) -> Format = proc_lib:format(Report), write_report_action(IO, Fd, Head ++ "~s", [Format]).
从上面的代码可以看出sasl会处理supervisor_report、crash_report类型的标准错误报告,对于指定了类型的标准错误报告,默认的错误处理句柄是不会处理的。
我们可以模拟一下进程启动的输出日志
C:\Users\Administrator>erl -boot start_sasl =PROGRESS REPORT==== 15-Aug-2013::23:17:28 === supervisor: {local,sasl_safe_sup} started: [{pid,<0.33.0>}, {name,alarm_handler}, {mfargs,{alarm_handler,start_link,[] {restart_type,permanent}, {shutdown,2000}, {child_type,worker}] ...... 1> error_logger:info_report(progress,[{application,test},{started_at, nonode@noh ost}]). =PROGRESS REPORT==== 15-Aug-2013::23:19:45 === application: test started_at: nonode@nohost ok