运行时跟踪¶
Crystal 运行时有一个用于低级功能的跟踪功能。它会打印关于运行时内部的诊断信息。
程序必须使用标记 -Dtracing
构建以支持跟踪。在运行时,可以通过环境变量 CRYSTAL_TRACE
启用各个跟踪组件。它接收一个逗号分隔的要启用的部分列表。
CRYSTAL_TRACE=none
禁用跟踪(默认值)CRYSTAL_TRACE=gc
: 启用垃圾回收器的跟踪CRYSTAL_TRACE=sched
: 启用调度程序的跟踪CRYSTAL_TRACE=gc,sched
: 启用垃圾回收器和调度程序的跟踪CRYSTAL_TRACE=all
启用所有跟踪(等同于gc,sched
)
示例
$ crystal build -Dtracing hello-world.cr
$ CRYSTAL_TRACE=sched ./hello-world
sched.spawn 70569399740240 thread=0x7f48d7dc9740:? fiber=0x7f48d7cd0f00:main fiber=0x7f48d7cd0dc0:Signal Loop
sched.enqueue 70569399831716 thread=0x7f48d7dc9740:? fiber=0x7f48d7cd0f00:main fiber=0x7f48d7cd0dc0:Signal Loop duration=163
Hello World
默认情况下,跟踪信息将打印到标准错误输出。这可以在运行时使用环境变量 CRYSTAL_TRACE_FILE
更改。
例如,CRYSTAL_TRACE_FILE=trace.log
会将所有跟踪输出打印到文件 trace.log
中。
跟踪格式¶
每个跟踪条目都位于单行上,以换行符结尾,长度不超过 512 字节。
每个条目都以一个标识符开头,该标识符由部分和操作名称组成,并用点号分隔(例如 gc.malloc
)。然后是一个时间戳,表示为纳秒的整数。最后是一个以 key=value
格式表示的元数据属性列表,属性之间用单个空格分隔。
前两个属性始终是源自的 thread
和 fiber
。两者都用 id 和名称标识,用冒号分隔(例如 0x7f48d7cd0f00:main
)。
- 线程 id 是操作系统句柄,因此我们可以将线程与调试器会话匹配,例如。
- fiber id 是 Crystal 运行时中的一个内部地址。名称是可选的,并且不一定是唯一的。
运行时启动初期来自的跟踪项可能缺少 fiber 元数据和线程名称。
根据特定跟踪条目,可能还有更多元数据属性。
例如,gc.malloc
指示正在分配多少内存。
报告的值通常表示为整数,具有以下语义
- 时间和持续时间以纳秒表示,符合操作系统的单调时钟(例如,
123
是123ns
,5000000000
是5s
)。 - 内存大小以字节表示(例如,
1024
是1KB
)。