查看源码 ttb (观察器 v2.17)
用于构建分布式系统跟踪工具的基础。
跟踪工具构建器 ttb
是构建分布式系统跟踪工具的基础。
当使用 ttb
时,请勿并行使用应用程序 Runtime_Tools 中的模块 dbg
。
概要
函数
等同于 tpl/4
。
读取指定的二进制跟踪日志。只要未指定选项 disable_sort
,日志将按照其时间戳顺序进行处理。
列出指定配置文件中的所有条目。
对 ttb
的所有调用都存储在历史记录中。此函数返回历史记录的当前内容。可以使用 run_history/1
重新执行任何条目,或使用 write_config/2,3
存储在配置文件中。
在指定的进程或端口上设置指定的跟踪标志。标志 timestamp
始终处于开启状态。
执行指定配置文件中的所有条目。请注意,上次跟踪的历史记录始终在文件 ttb_last_config
中可用。
执行指定配置文件中的选定条目。NumList
是一个整数列表,指出要执行的条目。
执行历史记录列表中的指定条目或多个条目。要列出历史记录,请使用 list_history/0
。
匹配规范可以打开或关闭顺序跟踪。此函数返回一个匹配规范,该规范使用指定的 Flags
打开顺序跟踪。
此函数是一个快捷方式,允许使用一个命令启动跟踪。Patterns
中的每个元组都转换为一个列表,该列表又传递给 ttb:tpl/2,3,4
。
停止所有节点上的跟踪。日志和跟踪信息文件将发送到跟踪控制节点,并存储在名为 ttb_upload_FileName-Timestamp
的目录中,其中 Filename
是在跟踪设置期间使用 {file, File}
提供的文件名,Timestamp
的格式为 yyyymmdd-hhmmss
。即使来自与跟踪控制节点在同一台机器上的节点的日志也会移动到此目录。历史记录列表将保存到名为 ttb_last_config
的文件中,以供进一步参考(因为它不再可以通过历史记录和配置管理函数访问,如 ttb:list_history/0
)。
等同于 tpl/4
。
等同于 tpl/4
。
等同于 tpl/4
。
这些函数与跟踪标志 call
、send
和 'receive'
一起使用,用于设置和清除跟踪模式。
等同于 tracer(node())
。
用于常见跟踪设置的便捷快捷方式。
在所有指定节点上启动文件跟踪端口,并将顺序跟踪的系统跟踪器指向同一端口。
创建或扩展配置文件,该配置文件可用于稍后恢复特定配置。
文件 .ti
包含 {Key,ValueList}
元组。此函数将 Data
添加到与 Key
关联的 ValueList
。使用此函数写入的所有信息都包含在对格式处理程序的调用中。
类型
-type format_handler() :: {format_fun(), InitialState :: term()}.
-type format_opt() :: {out, standard_io | file:filename()} | {handler, format_handler()} | disable_sort.
-type format_opts() :: format_opt() | [format_opt()].
-type match_spec() :: pos_integer() | x | c | cx | [] | dbg:match_spec().
-type stop_opt() :: nofetch | {fetch_dir, file:filename()} | format | {format, format_opts()} | return_fetch_dir.
-type tp_arity() :: arity() | '_'.
-type tp_function() :: atom() | '_'.
-type tp_module() :: module() | '_'.
-type trace_flag() :: s | r | m | c | p | sos | sol | sofs | all | clear | send | 'receive' | procs | ports | call | arity | return_to | silent | running | exiting | running_procs | running_ports | garbage_collection | timestamp | cpu_timestamp | monotonic_timestamp | strict_monotonic_timestamp | set_on_spawn | set_on_first_spawn | set_on_link | set_on_first_link | {tracer, pid() | port()} | {tracer, module(), term()}.
函数
-spec ctp() -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctp(Module | {Module, Function, Arity}) -> {ok, MatchDesc :: match_desc()} | {error, term()} when Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity().
等同于 tpl/4
。
-spec ctp(Module :: tp_module(), Function :: tp_function()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctp(Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctpe(Event) -> {ok, MatchDesc} | {error, term()} when Event :: send | 'receive', MatchDesc :: [MatchNum], MatchNum :: {matched, node(), 1} | {matched, node(), 0, RPCError :: term()}.
等同于 tpl/4
。
-spec ctpg() -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctpg(Module | {Module, Function :: tp_function(), Arity :: tp_arity()}) -> {ok, MatchDesc :: term()} | {error, term()} when Module :: tp_module().
等同于 tpl/4
。
-spec ctpg(Module :: tp_module(), Function :: tp_function()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctpg(Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctpl() -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctpl(Module | {Module, Function :: tp_function(), Arity :: tp_arity()}) -> {ok, MatchDesc :: term()} | {error, term()} when Module :: tp_module().
等同于 tpl/4
。
-spec ctpl(Module :: tp_module(), Function :: tp_function()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec ctpl(Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec format(Files) -> ok | {error, term()} when Files :: [file:filename()] | file:filename().
等同于 format(Files, [])
。
-spec format(Files, Options) -> ok | {error, term()} when Files :: [file:filename()] | file:filename(), Options :: format_opts().
读取指定的二进制跟踪日志。只要未指定选项 disable_sort
,日志将按照其时间戳顺序进行处理。
如果 FormatHandler = {Function,InitialState}
,则会为每条跟踪消息调用 Function
。
如果 FormatHandler = get_et_handler()
,则应用程序 ET 中的 et_viewer
用于以图形方式显示跟踪日志。ttb
提供了一些不同的过滤器,可以从 et_viewer
中的“过滤器和缩放”菜单中选择。
如果未指定 FormatHandler
,则会使用默认处理程序,将每条跟踪消息显示为文本行。
从每次调用 Function
返回的状态将传递给下一次调用,即使下一次调用是格式化来自另一个日志文件的消息也是如此。
如果指定了 Out
,则 FormatHandler
将获取指向 Out
的文件描述符作为第一个参数。
如果使用 et
格式处理程序,则 Out
将被忽略。
可以逐个或一次性格式化包装日志。要格式化一组包装日志中的一个,请指定确切的文件名。要格式化整组包装日志,请指定名称时使用 *
代替包装计数。有关示例,请参阅 用户指南
。
-spec get_et_handler() -> {Fun, InitState} when Fun :: fun(), InitState :: term().
返回 et
处理程序,该处理程序可以与 format/2
或 tracer/2
一起使用。
示例:ttb:format(Dir, [{handler, ttb:get_et_handler()}])
。
-spec list_config(ConfigFile) -> Result when ConfigFile :: file:filename(), Result :: Config | {error, term()}, Config :: [{integer(), mfas()}].
列出指定配置文件中的所有条目。
-spec list_history() -> History | {error, term()} when History :: [{N :: integer(), Func :: function(), Args :: integer()}].
对 ttb
的所有调用都存储在历史记录中。此函数返回历史记录的当前内容。可以使用 run_history/1
重新执行任何条目,或使用 write_config/2,3
存储在配置文件中。
-spec p(Item, Flags) -> Result when Item :: item(), Flags :: trace_flag() | [trace_flag()], Result :: {ok, [{item(), match_desc()}]}.
在指定的进程或端口上设置指定的跟踪标志。标志 timestamp
始终处于开启状态。
有关可能的跟踪标志,请参阅模块 dbg
的参考手册。参数 MatchDesc
与从 dbg:p/2
返回的参数相同。
进程可以指定为注册名称、全局注册名称或进程标识符。端口可以指定为注册名称或端口标识符。如果指定了注册名称,则会在所有活动节点上设置具有此名称的进程/端口上的标志。
如果使用 tracer/2
指定了选项 timer
,则发出此命令将为此跟踪启动计时器。
-spec run_config(ConfigFile) -> Result when ConfigFile :: file:filename(), Result :: ok | {error, term()}.
执行指定配置文件中的所有条目。请注意,上次跟踪的历史记录始终在文件 ttb_last_config
中可用。
-spec run_config(ConfigFile, NumList) -> Result when ConfigFile :: file:filename(), NumList :: [integer()], Result :: ok | {error, term()}.
执行指定配置文件中的选定条目。NumList
是一个整数列表,指出要执行的条目。
要列出配置文件的内容,请使用 list_config/1
。
请注意,上次跟踪的历史记录始终在文件 ttb_last_config
中可用。
-spec run_history(Entries) -> ok | {error, term()} when Entries :: [Entry] | Entry | all | all_silent, Entry :: integer().
执行历史记录列表中的指定条目或多个条目。要列出历史记录,请使用 list_history/0
。
-spec seq_trigger_ms() -> match_spec().
等同于 seq_trigger_ms(all)
。
-spec seq_trigger_ms(Flags) -> match_spec() when Flags :: all | SeqTraceFlag | [SeqTraceFlag], SeqTraceFlag :: atom().
匹配规范可以打开或关闭顺序跟踪。此函数返回一个匹配规范,该规范使用指定的 Flags
打开顺序跟踪。
此匹配规范可以指定为 tp
或 tpl
的最后一个参数。然后,激活的 Item
将成为顺序跟踪的触发器。这意味着如果在使用跟踪标志 call
集设置的进程上调用了该项,则该进程将被令牌 seq_trace
“污染”。
如果 Flags = all
,则会设置所有可能的标志。
SeqTraceFlag
的可能值在 seq_trace
中可用。
有关 match_spec()
语法描述,请参阅 ERTS 中的 Erlang 中的匹配规范
部分,其中解释了通用的匹配规范“语言”。
注意
当使用
ttb:tracer/0,1,2
启动跟踪端口时,顺序跟踪的系统跟踪器会自动由ttb
启动。
以下是如何使用函数 seq_trigger_ms/0,1
的示例
(tiger@durin)5> ttb:tracer().
{ok,[tiger@durin]}
(tiger@durin)6> ttb:p(all,call).
{ok,{[all],[call]}}
(tiger@durin)7> ttb:tp(mod,func,ttb:seq_trigger_ms()).
{ok,[{matched,1},{saved,1}]}
(tiger@durin)8>
在此之后,每当调用 mod:func(...)
时,执行进程上都会设置令牌 seq_trace
。
-spec start_trace(Nodes, Patterns, FlagSpec, TracerOpts) -> Result when Nodes :: nodes(), Patterns :: [tuple()], FlagSpec :: {item(), trace_flag() | [trace_flag()]}, TracerOpts :: term(), Result :: {ok, [{item(), match_desc()}]}.
此函数是一个快捷方式,允许使用一个命令启动跟踪。Patterns
中的每个元组都转换为一个列表,该列表又传递给 ttb:tpl/2,3,4
。
调用
> ttb:start_trace([Node, OtherNode],
[{mod, foo, []}, {mod, bar, 2}],
{all, call},
[{file, File}, {handler,{fun myhandler/4, S}}]).
等效于
> ttb:start_trace([Node, OtherNode],
[{file, File}, {handler,{fun myhandler/4, S}}]),
ttb:tpl(mod, foo, []),
ttb:tpl(mod, bar, 2, []),
ttb:p(all, call).
-spec stop() -> stopped | {stopped, Dir :: file:filename()}.
等同于 stop([])
。
-spec stop(Opts :: stop_opts()) -> stopped | {stopped, Dir :: file:filename()}.
停止所有节点上的跟踪。日志和跟踪信息文件将发送到跟踪控制节点,并存储在名为 ttb_upload_FileName-Timestamp
的目录中,其中 Filename
是在跟踪设置期间使用 {file, File}
提供的文件名,Timestamp
的格式为 yyyymmdd-hhmmss
。即使来自与跟踪控制节点在同一台机器上的节点的日志也会移动到此目录。历史记录列表将保存到名为 ttb_last_config
的文件中,以供进一步参考(因为它不再可以通过历史记录和配置管理函数访问,如 ttb:list_history/0
)。
选项
nofetch
- 表示在停止跟踪后不收集跟踪日志。{fetch, Dir}
- 允许指定要将数据提取到的目录。如果该目录已存在,则会抛出错误。format
- 表示在停止跟踪后格式化跟踪日志。提取目录中的所有日志将被合并。return_fetch_dir
- 表示返回值应为{stopped, Dir}
,而不仅仅是stopped
。这意味着fetch
。
-spec tp(tp_module(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec tp(tp_module(), tp_function(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec tp(tp_module(), tp_function(), tp_arity(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec tpe(Event, MatchSpec) -> {ok, MatchDesc :: match_desc()} | {error, term()} when Event :: send | 'receive', MatchSpec :: match_spec().
等同于 tpl/4
。
-spec tpl(tp_module(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec tpl(tp_module(), tp_function(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同于 tpl/4
。
-spec tpl(tp_module(), tp_function(), tp_arity(), match_spec()) -> {ok, match_desc()} | {error, term()}.
这些函数与跟踪标志 call
、send
和 'receive'
一起使用,用于设置和清除跟踪模式。
当在进程上设置跟踪标志 call
时,如果为被调用函数设置了跟踪模式,则会在该进程上跟踪函数调用。
send
和 'receive'
标志启用对进程/端口发送和接收的所有消息的跟踪。使用 tpe
设置的跟踪模式可以根据消息内容、发送者和/或接收者限制跟踪的消息。
跟踪模式通过使用匹配规范来指定如何跟踪函数或消息。匹配规范在 ERTS 用户指南
中描述。
这些函数等效于模块 dbg
中的相应函数,但所有调用都存储在历史记录中。历史记录缓冲区使创建配置文件变得容易;例如,可以多次设置相同的跟踪环境以比较两次测试运行。它还减少了从 Erlang shell 中使用 ttb
时的输入量。
tp
- 在全局函数调用上设置跟踪模式。tpl
- 在本地和全局函数调用上设置跟踪模式。tpe
- 在消息上设置跟踪模式。ctp
- 清除本地和全局函数调用上的跟踪模式。ctpl
- 清除本地函数调用上的跟踪模式。ctpg
- 清除全局函数调用上的跟踪模式。ctpe
- 清除消息上的跟踪模式。
使用 tp
和 tpl
,可以使用匹配规范的快捷方式之一(例如,ttb:tp(foo_module, caller)
)。
快捷方式如下
return
- 对于[{'_',[],[{return_trace}]}]
(报告被跟踪函数的返回值)caller
- 对于[{'_',[],[{message,{caller}}]}]
(报告调用函数){codestr, Str}
- 对于作为字符串传递的dbg:fun2ms/1
参数(示例:"fun(_) -> return_trace() end"
)
等同于 tracer(node())
。
用于常见跟踪设置的便捷快捷方式。
shell
等效于 tracer(node(),[{file, {local, "ttb"}}, shell])
。
dbg
等效于 tracer(node(),[{shell, only}])
。
Nodes
等效于 tracer(Nodes,[])
。
-spec tracer(Nodes, Opts) -> Result when Nodes :: nodes(), Opts :: Opt | [Opt], Opt :: {file, Client} | {handler, format_handler()} | {process_info, boolean()} | shell | {shell, ShellSpec} | {timer, TimerSpec} | {overload_check, {MSec, Module, Function}} | {flush, MSec} | resume | {resume, MSec} | {queue_size, non_neg_integer()}, TimerSpec :: MSec | {MSec, stop_opts()}, MSec :: integer(), Module :: atom(), Function :: atom(), Client :: File | {local, File}, File :: file:filename() | Wrap, Wrap :: {wrap, file:filename()} | {wrap, file:filename(), Size :: integer(), Count :: integer()}, ShellSpec :: true | false | only, Result :: {ok, [node()]} | {error, term()}.
在所有指定节点上启动文件跟踪端口,并将顺序跟踪的系统跟踪器指向同一端口。
选项
Filename
- 指定的Filename
以节点名称为前缀。默认Filename
为ttb
。File={wrap,Filename,Size,Count}
- 如果必须限制跟踪日志的大小,则可以使用此选项。默认值为Size=128*1024
和Count=8
。Client
- 在跟踪无盘节点时,必须从具有磁盘访问权限的外部“跟踪控制节点”启动ttb
,并且Client
必须为{local, File}
。然后,所有跟踪信息都将发送到跟踪控制节点,并在那里写入文件。queue_size
- 当跟踪到 shell 或{local,File}
时,内部使用 IP 跟踪驱动程序。IP 跟踪驱动程序有一个最多包含QueueSize
条消息的队列等待传递。如果驱动程序无法以生成消息的速度传递消息,则可能会超出队列大小,并且会丢弃消息。此参数是可选的,仅当跟踪处理程序收到许多{drop,N}
跟踪消息时才有用。如果未使用 shell 或{local,File}
,则它没有意义。有关 IP 跟踪驱动程序的更多信息,请参阅dbg:trace_port/2
。process_info
- 指示是否要收集进程信息。如果PI = true
(默认值),则每个进程标识符Pid
都会被替换为元组{Pid,ProcessInfo,Node}
,其中ProcessInfo
是注册的进程名称、其全局注册名称或其初始函数。要关闭此功能,请设置PI = false
。{shell, ShellSpec}
- 表示跟踪消息将在被跟踪进程接收时打印到控制台上。这意味着跟踪客户端{local, File}
。如果ShellSpec
为only
(而不是true
),则不存储跟踪日志。shell
-{shell, true}
的快捷方式。timer
- 表示在MSec
毫秒后自动停止跟踪。如果指定了StopOpts
,则将其传递给命令ttb:stop/1
(默认为[]
)。请注意,计时是近似的,因为始终存在与网络通信相关的延迟。计时器在发出ttb:p/2
后启动,因此您可以在之前设置跟踪模式。overload_check
- 允许在被跟踪的节点上启用过载检查。每MSec
毫秒执行一次Module:Function(check)
。如果检查返回true
,则在指定的节点上禁用跟踪。Module:Function
必须能够处理至少三个原子:init
、check
和stop
。init
和stop
允许您初始化和清理检查环境。当节点过载时,无法从
ttb:tp/2,3,4
系列发出ttb:p/2
或任何命令,因为它会导致不一致的跟踪状态(不同节点上的不同跟踪规范)。flush
- 定期刷新所有文件跟踪端口客户端 (请参阅dbg:flush_trace_port/1
)。启用后,缓冲区将每MSec
毫秒释放一次。此选项不允许使用{file, {local, File}}
跟踪。{resume, FetchTimeout}
- 启用自动恢复功能。启用后,如果重新启动,远程节点会尝试重新连接到控制节点。该功能要求启动 Runtime_Tools 应用程序(因此,如果跟踪的节点使用嵌入式 Erlang 运行,则必须在.boot
脚本中存在)。如果这不可能,可以通过使用rpc:call/4
远程启动Runtime_Tools
来手动执行恢复。ttb
会尝试在重新初始化跟踪之前从重新连接的节点提取所有日志。这必须在FetchTimeout
毫秒内完成,否则将中止。默认情况下,自动启动信息存储在每个节点上名为
ttb_autostart.bin
的文件中。如果不需要这样做(例如,在无盘节点上),则可以通过为应用程序 Runtime_Tools 指定环境变量ttb_autostart_module
来提供自定义模块来处理自动启动信息的存储和检索。该模块必须响应以下 APIwrite_config(Data) -> ok
- 存储提供的数据以供进一步检索。重要的是要认识到,所使用的数据存储不得受节点崩溃的影响。read_config() -> {ok, Data} | {error, Error}
- 检索使用write_config(Data)
存储的配置。delete_config() -> ok
- 删除使用write_config(Data)
存储的配置。请注意,在此调用之后,任何后续的read_config
调用都必须返回{error, Error}
。
resume
隐含默认的FetchTimeout
,即 10 秒
-spec write_config(ConfigFile, Config) -> Result when ConfigFile :: file:filename(), Config :: all | [integer()] | [mfas()], Result :: ok | {error, term()}.
-spec write_config(ConfigFile, Config, Opts) -> Result when ConfigFile :: file:filename(), Config :: all | [integer()] | [mfas()], Opts :: Opt | [Opt], Opt :: append, Result :: ok | {error, term()}.
创建或扩展配置文件,该配置文件可用于稍后恢复特定配置。
配置文件的内容可以从历史记录中提取,也可以直接指定为 {Mod,Func,Args}
的列表。
如果要将完整的历史记录存储在配置文件中,则 Config
必须为 all
。如果仅要存储历史记录中的选定数量的条目,则 Config
必须是指向要存储的条目的整数列表。
如果未指定 Opts
或如果它是 []
,则会删除 ConfigFile
并创建一个新文件。如果 Opts = [append]
,则不会删除 ConfigFile
。新信息将追加到文件的末尾。
-spec write_trace_info(Key :: term(), Info) -> ok when Info :: Data :: term() | fun(() -> Data :: term()).
文件 .ti
包含 {Key,ValueList}
元组。此函数将 Data
添加到与 Key
关联的 ValueList
。使用此函数写入的所有信息都包含在对格式处理程序的调用中。