Skip to content

C++ Application Integration


Prerequisites

Note: If you have enabled the RUM Headless service, the prerequisites have already been automatically configured for you, and you can directly proceed with application integration.

Application Integration

The current CPP version temporarily supports Windows and Linux platforms. Log in to the Guance console, go to the Synthetic Tests page, click on the top-left corner [Create], and start creating a new application.

Installation

Source Code Address: https://github.com/GuanceCloud/datakit-cpp

Demo Address: https://github.com/GuanceCloud/datakit-cpp/ft-sdk-sample

git clone https://github.com/microsoft/vcpkg
cd vcpkg

# Download custom configuration registries file
curl -o vcpkg-configuration.json https://static.guance.com/ft-sdk-package/vcpkg_config/vcpkg-configuration.json 

bootstrap-vcpkg.bat
vcpkg install datakit-sdk-cpp:x64-windows
vcpkg integrate install
git clone https://github.com/microsoft/vcpkg

#apt install ninja-build
#apt install pkg-config

./vcpkg/bootstrap-vcpkg.sh
cd vcpkg

# Download custom configuration registries file
curl -o vcpkg-configuration.json https://static.guance.com/ft-sdk-package/vcpkg_config/vcpkg-configuration.json 

# If it's arm64, add VCPKG_FORCE_SYSTEM_BINARIES
#export VCPKG_FORCE_SYSTEM_BINARIES=1

./vcpkg install datakit-sdk-cpp:x64-linux

# In the compilation environment, reference the VCPKG_ROOT variable
export VCPKG_ROOT= [ your_vcpkg_root_dir ]

Add CMake configurations

cmake_minimum_required(VERSION 3.0)

project(ft-sdk-reference-sample VERSION 1.0.0 LANGUAGES CXX C)

add_definitions(-fPIC -g -Werror=return-type)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O1 -ftree-vectorize -ffast-math ")
set(CMAKE_CXX_STANDARD 17)

if(DEFINED ENV{VCPKG_ROOT})
if (EXISTS "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
    include ("$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
  set(VCPKG_CMAKE_SHARE "$ENV{VCPKG_ROOT}/installed/${VCPKG_TARGET_TRIPLET}/share"
      CACHE STRING "TEST")
endif ()
else ()
message(STATUS "please set the system environment variable : VCPKG_ROOT" $ENV{VCPKG_ROOT})
endif ()

# Add Guance SDK reference
find_path(FT-SDK_INCLUDE_DIR datakit-sdk-cpp/FTSDK.h)
find_library(FT-SDK_LIBRARY ft-sdk "${FT-SDK_INCLUDE_DIR}/../lib/")
include_directories(${FT-SDK_INCLUDE_DIR})

file(GLOB PROJECT_SOURCE "*.cpp")
file(GLOB PROJECT_HEADER "../include/*.h" "*.h")

add_executable (${PROJECT_NAME} ${PROJECT_SOURCE} ${PROJECT_HEADER})

# Link SDK
target_link_libraries(${PROJECT_NAME} PRIVATE ${FT-SDK_LIBRARY})

Header Reference

#include "datakit-sdk-cpp/FTSDKFactory.h"

Initialization

auto sdk = FTSDKFactory::get();
sdk->init();
Field Type Required Description
FTSDKFactory::get string No Specifies the configuration file, default is ft_sdk_config.json

Start json File Configuration

You can configure the json file through FTSDKFactory to enable SDK debugging logs.

{    
    "general_config": {
        "enable_sdk_log": true  // Enable debug log, default is off
    }
}

Global Configuration

FTSDKConfig gc;
gc.setServerUrl("http://10.0.0.1:9529")
    .setEnv(EnvType::PROD)
    .addGlobalContext("custom_key","custom_value")
    .setEnableFileDBCache(true);
sdk->install(gc)
Field Type Required Description
setServerUrl string Yes datakit access URL address, example: http://10.0.0.1:9529, default port is 9529. Note: The device installing the SDK must be able to access this address
setEnv enum No Environment configuration, default EnvType::PROD
setAppVersion enum No Windows will default retrieve, Linux systems need manual assignment
setEnableFileDBCache Bool No Whether to enable local database, default is false
addGlobalContext dictionary No Add global attributes to the SDK, refer to the rules here
setServiceName string No Affects the service field data in Logs and RUM, default for windows is df_rum_windows, for Linux is df_rum_linux

RUM Configuration

FTRUMConfig rc;
rc.setRumAppId("appid_xxxx");
sdk->initRUMWithConfig(rc);
Field Type Required Description
setRumAppId string Yes Corresponds to setting the RUM appid, enabling the RUM collection function, method to obtain appid
setSamplingRate float No Sampling rate, range [0,1], 0 means no collection, 1 means full collection, default value is 1. Scope applies to all View, Action, LongTask, Error data under the same session_id
setExtraMonitorTypeWithError ErrorMonitorType No Adds additional monitoring data to Rum crash data, ErrorMonitorType::MEMORY for memory usage, ErrorMonitorType::CPU for CPU occupancy, ErrorMonitorType::ALL for all
addGlobalContext dictionary No Adds label data, used for distinguishing user monitoring data sources. If tracking functionality is required, the parameter key should be track_id, value any numerical value. Refer to the rules here

Log Configuration

FTLogConfig lpc;
//std::vector<LogLevel> llf;
//llf.push_back(LogLevel::ERR);
//lpc.setLogLevelFilters(llf);
lpc.setEnableCustomLog(true)
    .setEnableLinkRumData(true);
Field Type Required Description
setSamplingRate float No Sampling rate, range [0,1], 0 means no collection, 1 means full collection, default value is 1.
addGlobalContext dictionary No Adds label data, refer to the rules here
setLogLevelFilters array No Set log level filters, default is not set
setEnableCustomLog bool No Whether to upload custom logs, default is false
setEnableLinkRUMData bool No Whether to link with RUM data, default is false
setLogCacheDiscardStrategy LogCacheDiscard No Default is LogCacheDiscard::DISCARD, DISCARD discards appended data, DISCARD_OLDEST discards old data

Trace Configuration

FTTraceConfig tc;
tc.setTraceType(TraceType::DDTRACE)
   .setEnableLinkRUMData(true);
Field Type Required Description
setSamplingRate float No Sampling rate, range [0,1], 0 means no collection, 1 means full collection, default value is 1.
setTraceType enum No Default is DDTrace, currently supports Zipkin , Jaeger, DDTrace, Skywalking (8.0+), TraceParent (W3C). When integrating with OpenTelemetry, choose the corresponding trace type and check supported types and agent configurations
setEnableLinkRUMData bool No Whether to link with RUM data, default is false

RUM User Data Tracking

Currently, RUM data transmission can only be achieved through manual method calls.

Action

Usage Method

/** 
 * Start action
 * 
 * @param actionName Action name
 * @param actionType Action type
 */
void startAction(std::string actionName, std::string actionType);


/**
 * End action
 * 
 */
void stopAction();

Code Example

sdk->startAction("just4test", "click");

View

Usage Method

/**
 * Start view.
 * 
 * @param viewName Current page name
 */
void startView(std::string viewName);

/**
 * End view.
 * 
 */
void stopView();

Code Example

sdk->startView("TEST_VIEW_ONE");

sdk->stopView();

Resource

Usage Method

/**
 * Start resource
 * 
 * @param resourceId Resource Id
 */
void startResource(std::string resourceId);

/**
 * End resource
 * 
 * @param resourceId Resource Id
 */
void stopResource(std::string resourceId);


/**
 * Set network transmission content
 * 
 * @param resourceId Resource Id
 * @param params Network transmission parameters
 * @param netStatusBean Network status statistics
 */
void addResource(std::string resourceId, ResourceParams params, NetStatus netStatusBean);
Method Name Meaning Required Description
NetStatus.fetchStartTime Request start time No
NetStatus.tcpTime TCP connection duration No
NetStatus.dnsTime DNS resolution time No
NetStatus.responseTime Response content transmission duration No
NetStatus.sslTime SSL connection duration No
NetStatus.firstByteTime Total time from SSL DNS resolution to receiving the first data packet No
NetStatus.ttfb Request response time, from starting the request to receiving the first response packet No
NetStatus.tcpStartTime TCP connection time No
NetStatus.tcpEndTime TCP end time No
NetStatus.dnsStartTime DNS start time No
NetStatus.dnsEndTime DNS end time No
NetStatus.responseStartTime Response start time No
NetStatus.responseEndTime Response end time No
NetStatus.sslStartTime SSL start time No
NetStatus.sslEndTime SSL end time No
ResourceParams.url URL address Yes
ResourceParams.requestHeader Request header parameters No
ResourceParams.responseHeader Response header parameters No
ResourceParams.responseConnection Response connection No
ResourceParams.responseContentType Response ContentType No
ResourceParams.responseContentEncoding Response ContentEncoding No
ResourceParams.resourceMethod Request method No GET, POST, etc.
ResourceParams.responseBody Returned body content No

Code Example

RestClient::init();
RestClient::Connection* conn = new RestClient::Connection(url);

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

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

RestClient::Connection::Info info = conn->GetInfo();

params.resourceMethod = "GET";
params.requestHeader = convert(headers);
params.responseHeader = convert(r.headers);

ResourceParams params;
params.responseBody = r.body;
params.responseConnection = "Keep-Alive";
params.responseContentEncoding = "UTF-8";
params.responseContentType = r.headers["Content-Type"];
params.url = url;
params.resourceStatus = r.code;

NetStatus status;
status.dnsTime = info.lastRequest.nameLookupTime * ns_factor;
status.tcpTime = (info.lastRequest.connectTime - info.lastRequest.nameLookupTime ) * ns_factor;
status.sslTime = (info.lastRequest.appConnectTime - info.lastRequest.connectTime) * ns_factor;
status.ttfb = (info.lastRequest.startTransferTime - info.lastRequest.preTransferTime) * ns_factor;
status.responseTime = (info.lastRequest.totalTime -info.lastRequest.startTransferTime) * ns_factor;
status.firstByteTime = info.lastRequest.startTransferTime * ns_factor;

RestClient::disable();

Error

Usage Method

/**
 * Add error information
 * 
 * @param log Log
 * @param message Message
 * @param errorType Error type
 * @param state Program running state
 */
void addError(std::string log, std::string message, RUMErrorType errorType, AppState state);

Code Example

sdk->addError("test error 1", "first error", RUMErrorType::native_crash, AppState::UNKNOWN);
sdk->addError("test error 2", "second error", RUMErrorType::network_error, AppState::UNKNOWN);

LongTask

Usage Method

/**
 * Add long-running task
 * 
 * @param log Log
 * @param duration Duration(ns)
 */
void addLongTask(std::string log, long duration);

Code Example

sdk->addLongTask("test long task", 100010);

Log Printing

Usage Method

/**
  * Upload user logs to datakit
  * @param content Log content
  * @param level Log level
  */
void addLog(std::string content, LogLevel level);

Code Example

sdk->addLog("this\\is a \"test\" log", LogLevel::info);

Tracer Network Trace

Traces are generated by creating Trace Headers, which are then added to HTTP request headers to implement tracing.

Usage Method

/**
 * Generate trace header based on configuration
 * 
 * @param url Network address
 * @return Trace data
 */
PropagationHeader generateTraceHeader(const std::string url);

Code Example

RestClient::init();
RestClient::Connection* conn = new RestClient::Connection(url);

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

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

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

Binding and Unbinding User Information

Usage Method

/**
 * Bind user data
 * 
 * @param config User data
 * @return
 */
FTSDK&& bindUserData(UserData& config);

/**
 * Unbind user data
 *
 */
void unbindUserData();

Code Example

// Bind user data
UserData uc;
uc.init("username", "1001", "someone@email.com");
uc.addCustomizeItem("ft_key", "ft_value");
sdk->bindUserData(uc);

// Unbind user data
sdk->unbindUserData();

Closing the SDK

/**
 * Close the SDK and execute related resource cleanup operations 
 */
sdk->deinit();

Common Issues

Adding Local Variables to Avoid Field Conflicts

To avoid conflicts between custom fields and SDK data, it is recommended to prefix tag names with the project abbreviation, such as df_tag_name. You can check the source code for the key values used in the project. When global variables in the SDK conflict with RUM or Logs, RUM and Logs will override the global variables in the SDK.

Feedback

Is this page helpful? ×