Skip to content

Trace Configuration

This document describes the Trace initialization configuration and distributed tracing instructions for the C++ SDK.

Initialize Tracing

FTTraceConfig tc;
tc.setTraceType(TraceType::DDTRACE)
  .setEnableLinkRUMData(true);
sdk->initTraceWithConfig(tc);
Field Type Required Description
setSamplingRate float No Sampling rate range [0,1], 0 means no collection, 1 means full collection, default value 1
setTraceType enum No Default is DDTrace, supports Zipkin, Jaeger, DDTrace, Skywalking (8.0+), TraceParent (W3C). If you are using OpenTelemetry, please check the supported trace types and agent-related configurations when selecting the corresponding trace type.
setEnableLinkRUMData bool No Whether to associate with RUM data, default is false

Generate Trace Headers

Distributed tracing is implemented by generating trace headers and injecting them into HTTP request headers.

/**
 * Generates trace headers based on configuration.
 *
 * @param resourceId Resource ID
 * @param url Network address
 * @return trace data
 */
PropagationHeader generateTraceHeader(const std::string resourceId, const std::string url);

Example:

RestClient::init();
RestClient::Connection* conn = new RestClient::Connection(url);
std::string resId = "resource-id";

RestClient::HeaderFields headers;
headers["Accept"] = "application/json";

auto headerWithRes = sdk->generateTraceHeader(resId, url);
for (auto& hd : headerWithRes) {
    headers[hd.first] = hd.second;
}
conn->SetHeaders(headers);

RestClient::Response r = conn->get("/get");
RestClient::disable();

Windows Native SDK Auto Trace

Windows C/C++ applications that link the guance_rum_native.dll can automatically generate and inject trace headers for WinHTTP requests, and simultaneously collect the corresponding RUM Resource. When RUM linking is enabled, the same trace_id and span_id are written into the Resource data, enabling correlated navigation between RUM and APM.

!!! note

The SDK injects the request headers corresponding to the selected trace protocol. It does not add HTTP headers named `trace_id` or `span_id`. The `trace_id` and `span_id` are only written into the RUM Resource fields when `enable_link_rum_data = 1`.

Configuration

Configure tracing after guance_rum_init succeeds. The configuration structure must be initialized by calling guance_rum_trace_config_init first:

#include "guance_rum_winhttp.hpp"

#include <string>

static int should_trace(const char* url, const char*, void*) {
    const std::string value = url == nullptr ? "" : url;
    return value == "https://api.example.com" ||
        value.rfind("https://api.example.com/", 0) == 0;
}

guance_rum_trace_config trace{};
guance_rum_trace_config_init(&trace);
trace.enable_auto_trace = 1;
trace.enable_link_rum_data = 1;
trace.sample_rate = 1.0;
trace.trace_type = GUANCE_RUM_TRACE_TRACEPARENT;
trace.should_trace = should_trace;

if (!guance_rum_configure_trace(rum, &trace)) {
    // Configuration is invalid; automatic trace propagation is not enabled.
}
Field Type Default Description
enable_auto_trace int 0 Whether to automatically generate a trace context for eligible HTTP requests
enable_link_rum_data int 0 Whether to write the generated trace_id and span_id into the corresponding RUM Resource
sample_rate double 1.0 Sampling decision ratio for traces, range [0,1]; this value controls the sampling flag in the propagation protocol and does not replace the RUM session sampling configuration
trace_type guance_rum_trace_type GUANCE_RUM_TRACE_DDTRACE Trace header propagation format
service_name string RUM service_name Service name used by SkyWalking sw8; ignored by other built-in propagation formats
should_trace callback nullptr Request target filtering callback; trace context is generated only if the return value is non-0
context_provider callback nullptr Custom trace context provider; when set, replaces the SDK's built-in logic for generating headers, trace ID, and span ID
user_data void* nullptr User context passed to both callbacks

!!! warning

If `should_trace` is not set, any non-empty URL passed to the auto-trace API may receive trace headers. It is recommended to construct a clear server-side whitelist based on protocol, hostname, and port to avoid sending trace information to third-party addresses.

guance_rum_configure_trace copies string configurations but retains the callbacks and user_data. They must remain valid until reconfiguration or guance_rum_shutdown. Callbacks are synchronous and may be called concurrently by multiple request threads.

Supported Propagation Formats

guance_rum_trace_type Protocol Injected Headers
GUANCE_RUM_TRACE_DDTRACE Datadog x-datadog-origin, x-datadog-sampling-priority, x-datadog-parent-id, x-datadog-trace-id
GUANCE_RUM_TRACE_ZIPKIN_MULTI_HEADER Zipkin B3 Multi X-B3-TraceId, X-B3-SpanId, X-B3-Sampled
GUANCE_RUM_TRACE_ZIPKIN_SINGLE_HEADER Zipkin B3 Single b3
GUANCE_RUM_TRACE_TRACEPARENT W3C Trace Context traceparent
GUANCE_RUM_TRACE_SKYWALKING Apache SkyWalking sw8
GUANCE_RUM_TRACE_JAEGER Jaeger uber-trace-id

The server or agent must support the selected propagation format. The default format is GUANCE_RUM_TRACE_DDTRACE.

Auto-Instrumentation for Synchronous WinHTTP Requests

First create a WinHTTP request handle, then construct a guance::rum::WinHttpResource. The constructor immediately generates a trace context and writes the headers into the request:

// request is an HINTERNET already created via WinHttpOpenRequest; target is the full URL.
guance::rum::WinHttpResource resource(
    rum,
    request,
    target.c_str(),
    "GET");

if (!resource.send()) {
    // Request was not sent.
}
if (!resource.receive()) {
    // Response reception failed.
}

In synchronous mode, receive() reads the response status, Content-Length, and HTTP version, and finalizes the RUM Resource. WinHttpResource does not own the SDK handle or the WinHTTP request handle; both must outlive it.

For asynchronous WinHTTP requests, pass guance::rum::WinHttpRequestMode::asynchronous, keep the WinHttpResource alive until the completion callback, and call complete_from_response() after receiving WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE. Callback access to this object must be serialized by the application.

Manual Trace Context Retrieval

For non-WinHTTP network libraries, the context can be generated via the C ABI, and all headers can be written into the request:

guance_rum_trace_context context{};
guance_rum_trace_context_init(&context);

if (guance_rum_create_trace_context(
        rum,
        "https://api.example.com/v1/user",
        "GET",
        &context)) {
    for (uint32_t index = 0; index < context.header_count; ++index) {
        const char* name = context.headers[index].name;
        const char* value = context.headers[index].value;
        // Use the current network library to write name/value into the request headers.
    }
}

If you collect the RUM Resource manually, pass context.trace_id and context.span_id to guance_rum_stop_resource_ext when ending the Resource. These two fields should be associated only when context.link_rum_data != 0.

When you need to continue an existing trace or integrate with a custom protocol, you can set the context_provider. The SDK passes an already initialized guance_rum_trace_context; the callback fills the headers, trace ID, and span ID, then returns non-0. Up to GUANCE_RUM_TRACE_MAX_HEADERS headers are supported. If the provider returns 0 or provides invalid data, the SDK skips trace context generation for that request but does not interrupt the host request. Do not let C++ exceptions cross the C ABI callback boundary.

Feedback

Is this page helpful?