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.
- Install DataKit;
- Configure RUM Collector;
- Ensure DataKit is accessible via the public network and that the IP geolocation database is installed.
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
#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¶
Initialization¶
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.
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¶
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¶
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¶
View¶
Usage Method¶
/**
* Start view.
*
* @param viewName Current page name
*/
void startView(std::string viewName);
/**
* End view.
*
*/
void stopView();
Code Example¶
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¶
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¶
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¶
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.