异步跟踪

本指南介绍了如何向代码添加异步跟踪功能。

前提条件

在开始之前,请确保您已完成以下操作:

添加异步跟踪

有一组异步跟踪函数用于 操作跨多个线程。

例如,在多线程服务器中,一个请求由一个线程处理, 然后在操作正在进行时放回队列中。 一段时间后,另一个线程收到操作 “接送”相应请求的处理过程 异步跟踪的目标是让这些不相交的 跟踪事件。

异步跟踪考虑到使用的是相同的代码路径 多个不同的处理流程 在之前的示例中,我们想了解某个特定网页 函数,或者某个时间点在某个时间点的值是什么。 对于异步跟踪,我们希望跟踪相同的数据, 逻辑处理流程,而不是基于程序位置的流程。

在队列处理示例中,接收请求的代码将标记每个 包含“Nonce”的请求— 随请求一起返回的唯一值。 此 Nonce 可通过 TRACE_NONCE() 生成,后者只会递增 全局计数器。

我们来看看具体是如何做的。 首先,声明一个存储 Nonce 的位置。 这通常在请求本身的上下文结构中:

typedef struct {
...
    // add the nonce to your context structure
    trace_async_id_t async_id;
} my_request_context_t;

当请求到达时,您提取一个 Nonce 并开始异步跟踪 流程:

// a new request; start asynchronous tracing
ctx->async_id = TRACE_NONCE();
TRACE_ASYNC_BEGIN("category", "name", ctx->async_id, "key", TA_STRING("value"));

您可以使用 TRACE_ASYNC_INSTANT() 宏定期记录跟踪事件 (类似于我们对上述 TRACE_INSTANT() 宏执行的操作):

TRACE_ASYNC_INSTANT("category", "name", ctx->async_id, "state", TA_STRING("phase2"));

然后通过 TRACE_ASYNC_END() 进行清理:

TRACE_ASYNC_END("category", "name", ctx->async_id);

请不要混淆“异步”的这种用法通过 Google Cloud 控制台中运行的异步循环 过程;它们并不相关

流跟踪

异步跟踪旨在在同一进程内进行跟踪, 可能是通过不同的线程实现的

还有一种更高级别的跟踪机制,称为“流程”也就是 旨在在进程或抽象层之间使用。

调用 TRACE_FLOW_BEGIN() 来标记“流程”的开始。 与 TRACE_ASYNC_BEGIN() 一样,您可以传入一个 Nonce 来识别此元素 特定流。流 ID 是一个无符号的 64 位整数。

然后,您可以(可选)调用 TRACE_FLOW_STEP() 来指明 跟踪该流中的操作

完成后,您可以使用 TRACE_FLOW_END() 结束流程。

例如,客户端和服务器之间可以使用数据流来跟踪 从客户端、通过服务器再到发回客户端的端到端请求。