查看源代码 SASL 错误日志
注意
本节描述的 SASL 错误日志概念自 Erlang/OTP 21.0 起已弃用,当时引入了新的 日志 API。
新的默认行为是 SASL 应用程序不再影响记录哪些日志事件。Supervisor 报告和崩溃报告通过 Kernel 设置的默认 logger 处理程序记录。进度报告默认情况下不记录,但可以通过将主日志级别设置为
info
来启用,例如使用 Kernel 配置参数logger_level
。可以通过将 Kernel 配置参数
logger_sasl_compatible
设置为true
来重新启用旧的 SASL 错误日志行为。本节中描述的 多文件错误报告日志机制也保留以实现向后兼容。但是,新的日志 API 还引入了
logger_disk_log_h
,它是一个可以使用disk_log
打印到多个文件的 logger 处理程序。
SASL 报告
SASL 应用程序引入了三种类型的报告
- Supervisor 报告
- 进度报告
- 崩溃报告
当 SASL 应用程序启动时,它会添加一个 Logger 处理程序,该处理程序会根据 SASL 的配置参数中指定的方式格式化和写入这些报告。
Supervisor 报告
当受监控的子进程意外终止时,会发出 Supervisor 报告。Supervisor 报告包含以下项目
Supervisor
- 报告 Supervisor 的名称。Context
- 指示子进程从 Supervisor 的角度来看在哪个阶段终止。这可以是start_error
、child_terminated
或shutdown_error
。Reason
- 终止原因。Offender
- 子进程的启动规范。
进度报告
当 Supervisor 启动或重新启动子进程时,会发出进度报告。进度报告包含以下项目
Supervisor
- 报告 Supervisor 的名称。Started
- 成功启动的子进程的启动规范。
崩溃报告
使用函数 proc_lib:spawn
或 proc_lib:spawn_link
启动的进程会被包装在 catch
中。当这样的进程因意外原因(即除 normal
、shutdown
或 {shutdown,Term}
之外的任何原因)终止时,会发出崩溃报告。使用行为 gen_server
、gen_fsm
或 gen_statem
的进程就是这样的例子。崩溃报告包含以下项目
Crasher
- 关于崩溃进程的信息,例如初始函数调用、退出原因和消息队列。Neighbours
- 关于链接到崩溃进程且不捕获退出的进程的信息。这些进程是由于此进程崩溃而终止的邻居。收集的信息与前一项中描述的 Crasher 的信息相同。
示例
以下示例显示了进程崩溃时生成的报告。示例进程是由 test_sup
Supervisor 监控的 permanent
进程。执行除以零操作,错误首先由错误进程报告。由于该进程是使用函数 proc_lib:spawn/3
启动的,因此会生成崩溃报告。Supervisor 会生成一个 Supervisor 报告,显示崩溃的进程。当进程最终重新启动时,会生成进度报告。
=ERROR REPORT==== 27-May-1996::13:38:56 ===
<0.63.0>: Divide by zero !
=CRASH REPORT==== 27-May-1996::13:38:56 ===
crasher:
pid: <0.63.0>
registered_name: []
error_info: {badarith,{test,s,[]}}
initial_call: {test,s,[]}
ancestors: [test_sup,<0.46.0>]
messages: []
links: [<0.47.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 128
stack_size: 128
reductions: 348
neighbours:
=SUPERVISOR REPORT==== 27-May-1996::13:38:56 ===
Supervisor: {local,test_sup}
Context: child_terminated
Reason: {badarith,{test,s,[]}}
Offender: [{pid,<0.63.0>},
{name,test},
{mfa,{test,t,[]}},
{restart_type,permanent},
{shutdown,200},
{child_type,worker}]
=PROGRESS REPORT==== 27-May-1996::13:38:56 ===
Supervisor: {local,test_sup}
Started: [{pid,<0.64.0>},
{name,test},
{mfa,{test,t,[]}},
{restart_type,permanent},
{shutdown,200},
{child_type,worker}]
多文件错误报告日志
多文件错误报告日志用于存储 error_logger
收到的错误消息。错误消息存储在多个文件中,并且每个文件都小于指定的千字节数。同时存在的文件数不超过指定的数量。日志记录速度非常快,因为每个错误消息都以二进制术语形式写入。
有关更多详细信息,请参阅参考手册中的 sasl(6)
应用程序。
报告浏览器
报告浏览器用于浏览和格式化由 STDLIB 中定义的错误日志处理程序 log_mf_h
编写的错误报告。
log_mf_h
处理程序将所有报告写入报告日志目录,该目录在配置 SASL 应用程序时指定。
如果离线使用报告浏览器,可以将报告复制到启动浏览器时指定的另一个目录。如果未指定此类目录,浏览器会从 SASL error_logger_mf_dir
读取报告。
启动报告浏览器
使用函数 rb:start([Options])
启动 rb_server
,如下例所示
5> rb:start([{max, 20}]).
rb: reading report...done.
rb: reading report...done.
rb: reading report...done.
rb: reading report...done.
{ok,<0.199.0>}
在线帮助
输入命令 rb:help()
以访问报告浏览器在线帮助系统。
列出服务器中的报告
使用函数 rb:list()
列出所有已加载的报告
4> rb:list().
No Type Process Date Time
== ==== ======= ==== ====
20 progress <0.17.0> 1996-10-16 16:14:54
19 progress <0.14.0> 1996-10-16 16:14:55
18 error <0.15.0> 1996-10-16 16:15:02
17 progress <0.14.0> 1996-10-16 16:15:06
16 progress <0.38.0> 1996-10-16 16:15:12
15 progress <0.17.0> 1996-10-16 16:16:14
14 progress <0.17.0> 1996-10-16 16:16:14
13 progress <0.17.0> 1996-10-16 16:16:14
12 progress <0.14.0> 1996-10-16 16:16:14
11 error <0.17.0> 1996-10-16 16:16:21
10 error <0.17.0> 1996-10-16 16:16:21
9 crash_report release_handler 1996-10-16 16:16:21
8 supervisor_report <0.17.0> 1996-10-16 16:16:21
7 progress <0.17.0> 1996-10-16 16:16:21
6 progress <0.17.0> 1996-10-16 16:16:36
5 progress <0.17.0> 1996-10-16 16:16:36
4 progress <0.17.0> 1996-10-16 16:16:36
3 progress <0.14.0> 1996-10-16 16:16:36
2 error <0.15.0> 1996-10-16 16:17:04
1 progress <0.14.0> 1996-10-16 16:17:09
ok
显示报告
使用函数 rb:show(Number)
显示特定报告的详细信息
7> rb:show(4).
PROGRESS REPORT <0.20.0> 1996-10-16 16:16:36
===============================================================================
supervisor {local,sasl_sup}
started
[{pid,<0.24.0>},
{name,release_handler},
{mfa,{release_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
ok
8> rb:show(9).
CRASH REPORT <0.24.0> 1996-10-16 16:16:21
===============================================================================
Crashing process
pid <0.24.0>
registered_name release_handler
error_info {undef,{release_handler,mbj_func,[]}}
initial_call
{gen,init_it,
[gen_server,
<0.20.0>,
<0.20.0>,
{erlang,register},
release_handler,
release_handler,
[],
[]]}
ancestors [sasl_sup,<0.18.0>]
messages []
links [<0.23.0>,<0.20.0>]
dictionary []
trap_exit false
status running
heap_size 610
stack_size 142
reductions 54
ok
搜索报告
可以显示包含公共模式的所有报告。假设进程因尝试调用不存在的函数 release_handler:mbj_func/1
而崩溃。然后可以按如下方式显示报告
12> rb:grep("mbj_func").
Found match in report number 11
ERROR REPORT <0.24.0> 1996-10-16 16:16:21
===============================================================================
** undefined function: release_handler:mbj_func[] **
Found match in report number 10
ERROR REPORT <0.24.0> 1996-10-16 16:16:21
===============================================================================
** Generic server release_handler terminating
** Last message in was {unpack_release,hej}
** When Server state == {state,[],
"/home/dup/otp2/otp_beam_sunos5_p1g_7",
[{release,
"OTP APN 181 01",
"P1G",
undefined,
[],
permanent}],
undefined}
** Reason for termination ==
** {undef,{release_handler,mbj_func,[]}}
Found match in report number 9
CRASH REPORT <0.24.0> 1996-10-16 16:16:21
===============================================================================
Crashing process
pid <0.24.0>
registered_name release_handler
error_info {undef,{release_handler,mbj_func,[]}}
initial_call
{gen,init_it,
[gen_server,
<0.20.0>,
<0.20.0>,
{erlang,register},
release_handler,
release_handler,
[],
[]]}
ancestors [sasl_sup,<0.18.0>]
messages []
links [<0.23.0>,<0.20.0>]
dictionary []
trap_exit false
status running
heap_size 610
stack_size 142
reductions 54
Found match in report number 8
SUPERVISOR REPORT <0.20.0> 1996-10-16 16:16:21
===============================================================================
Reporting supervisor {local,sasl_sup}
Child process
errorContext child_terminated
reason {undef,{release_handler,mbj_func,[]}}
pid <0.24.0>
name release_handler
start_function {release_handler,start_link,[]}
restart_type permanent
shutdown 2000
child_type worker
ok
停止服务器
使用函数 rb:stop()
停止 rb_server
13> rb:stop().
ok