The IoT C++ SDK provides APIs to instrument C++ applications running on connected devices such as industrial or home gateways, points of sale, smart TVs or car infotainment systems. This getting started will show you how to install the C++ SDK and instrument your IoT application.

Follow these steps to get your EUM App Key and instrument your IoT C/C++ apps.

If you have ANSI-C application or if your platform is not Linux x86, please contact your AppDynamics account representative.

Learn about the C/C++ SDK

You should know that the C++ SDK:

  • Operates within the application thread and doesn’t spawn any new threads.
  • Keeps all the event data in memory and doesn’t persist on disk.
  • Provides an API to register for the network interface.
  • Uses application's HTTPS stack to communicate with the EUM Server.
  • Provides an API to fetch SDK log messages. Application developers have to manage logs by writing the log messages to stderr or to a log file.
  • Uses the open-source json-c library that is statically linked.
  • Makes synchronous blocking API calls that are not thread-safe. Application developers are responsible for making thread-safe calls.

Review the Requirements

Before you begin, make sure you meet these requirements:

  • GNU C++ Compiler (g++) version 4.2 for 32/64-bit architectures
  • Any Linux distribution based on glibc >= 2.20
  • HTTPS stack for sending beacons to the EUM Cloud
  • EUM App Key

Get the IoT C++ SDK

You can get the C++ SDK by cloning or downloading the IoT C++ SDK from GitHub. Follow the instructions given in Installation to build the IoT C++ SDK.

Upgrade the IoT C++ SDK

From the root directory of your clone of the IoT C++ SDK from GitHub:

  • Update the repository: $ git pull origin master
  • Follow the instructions given in Installation to rebuild the IoT C++ SDK.

Install the C++ SDK in Your Application

The C++ SDK is packaged as a tar zip file and contains the following:

  • include - directory containing headers for the public API for use with the C++ SDK
  • lib - the directory containing the shared object files for the C++ SDK

Add the SDK Headers

Copy or move the include directory, which contains the SDK header files into your application directory, and include it in your code to access the SDK APIs. 

#include "appd_iot_interface.h"   
  ....
{
CPP

Initialize the SDK

You must initialize the C++ SDK by providing the SDK and device configuration as input parameters and then calling the function appd_iot_init_sdk as shown below. The SDK configuration takes in parameters for the app key, log level, and the EUM Collector URL. The SDK uses the EUM Collector URL to send data to the EUM Server. The device configuration contains information to identify a unique device.

See Cisco AppDynamics SaaS Domains and IP Ranges for EUM Collector URLs in each geographic region. If the EUM Collector URL is not specified, the default SaaS Collector URL is used.

#include "appd_iot_interface.h"   
  ....
{
  // Declare config variables for the SDK and device.
  appd_iot_sdk_config_t sdkcfg;
  appd_iot_device_config_t devcfg;
  appd_iot_init_to_zero(&sdkcfg, sizeof(sdkcfg));
  appd_iot_init_to_zero(&devcfg, sizeof(devcfg));
 
  // Set the initialization configurations for the SDK
  sdkcfg.appkey = "<EUM_APP_KEY>";
 
  // Set the device configurations
  devcfg.device_id = "1111";
  devcfg.device_type = "SmartCar";
  devcfg.device_name = "AudiS3";
 
  // Initialize the instrumentation
  appd_iot_init_sdk(sdkcfg, devcfg);
}
CPP

Register Network Interface

The SDK needs an HTTPS interface to send events to the EUM Server. The application developer has to provide callback functions for the SDK to execute the HTTPS request. Refer to Run the Sample Application for a sample network interface implementation using libcurl

#include "appd_iot_interface.h"   
  ....
{
  appd_iot_http_cb_t http_cb;
 
  //Callback function triggered by SDK to send http request and receive http response
  http_cb.http_req_send_cb = &your_network_interface_send_cb;
 
  //Callback function triggered by SDK to indicate completion of http response processing
  http_cb.http_resp_done_cb = &your_network_interface_resp_done_cb;


  //register http interface callbacks
  appd_iot_register_network_interface(http_cb);

  ...
}
CPP

Add and Send Events

 To understand the different types of events, you will work with the sample smart car IoT application given in the sections below.

Custom Events

Custom event to capture technical stats of a "SmartCar".

#include "appd_iot_interface.h"   
  ....
 
{
  appd_iot_custom_event_t custom_event;
  appd_iot_init_to_zero(&custom_event, sizeof(custom_event));
 
  custom_event.type = "SmartCar Stats";
  custom_event.summary = "Technical Stats of SmartCar";
  custom_event.timestamp_ms = ((int64_t)time(NULL) * 1000);
  custom_event.data = (appd_iot_data_t*)calloc(2, sizeof(appd_iot_data_t)); 
  appd_iot_data_set_integer(&custom_event.data[0], "Speed mph", 65);
  appd_iot_data_set_double(&custom_event.data[1], "Oil Temperature", 220);
 
  appd_iot_add_custom_event(custom_event);
  free(custom_event.data);
 
  ....

  appd_iot_send_all_events();
}
CPP

Network Request Events

Network Request event to capture the performance of an HTTPS call to get weather information.

#include "appd_iot_interface.h"   
  ....
 
{
  
  appd_iot_network_request_event_t network_event;
  appd_iot_init_to_zero(&network_event, sizeof(network_event));
 
  network_event.url = "https://apdy.api/weather";
  network_event.resp_code = 202;
  network_event.duration_ms = 10;
  network_event.req_content_length = 300;
  network_event.req_content_length = 100;
  network_event.timestamp_ms = ((int64_t)time(NULL) * 1000);
  network_event.data = (appd_iot_data_t*)calloc(1, sizeof(appd_iot_data_t));
  appd_iot_data_set_string(&network_event.data[0], "city", "San Francisco");
  
  appd_iot_add_network_request_event(network_event);
  free(network_event.data);
 
  ....
  appd_iot_send_all_events();
}
CPP

Error Events

The Error event below is used to capture Bluetooth errors in the SmartCar app.

#include "appd_iot_interface.h"   
  ....
{
  
  appd_iot_error_event_t error_event;
  appd_iot_init_to_zero(&error_event, sizeof(error_event));
  
  error_event.name = "Bluetooth Connection Error";
  error_event.message = "connection dropped due to bluetooth exception";
  error_event.severity = APPD_IOT_ERR_SEVERITY_CRITICAL;
  error_event.timestamp_ms = ((int64_t)time(NULL) * 1000);
  error_event.data = (appd_iot_data_t*)calloc(1, sizeof(appd_iot_data_t));
  appd_iot_data_set_integer(&error_event.data[0], "Bluetooth Error Code", 43);
  
  appd_iot_add_error_event(error_event);
  free(error_event.data);
  
  ....


  appd_iot_send_all_events();
}
CPP

Correlate Business Transactions with Network Requests (Optional)

To correlate business transactions (BTs) with network requests, you need to instrument a business application and enabled business transactions in the Controller UI. See Correlate Business Transactions for IoT Monitoring to learn more.

The steps below show you how to get the BT response headers and use them to correlate the BT with an IoT Network Request event.

  1. Set the AppDynamics HTTP headers ADRUM and ADRUM_1 as part of a network request to your business application.

    /* Initialize all the data structures for the request and response. */
    appd_iot_http_req_t http_req;
    appd_iot_http_req_t http_resp;
    
    /* Initialize the request and response. */
    appd_iot_init_to_zero(&http_req, sizeof(http_req));
    appd_iot_init_to_zero(&http_resp, sizeof(http_resp));
    
    /* Provide the URL to your instrumented business app that is enabled for business transaction correlation. */
    http_req.url = "<url-to-your-business-app-enabled-for-bt>";
    
    
    /* Add your other HTTP request parameters here:
    ...
    */ 
    /* Call the SDK method to get the headers for ADRUM and ADRUM_1. */
    const appd_iot_data_t* correlation_headers = appd_iot_get_server_correlation_headers();
    
    for (size_t i = 0; i < APPD_IOT_NUM_SERVER_CORRELATION_HEADERS; i++)
    {
      appd_iot_data_set_string(&http_req.headers[i], correlation_headers[i].key, correlation_headers[i].strval);
    }
    
    /* Make the request, and assign the response to a variable. */
    http_resp = http_curl_req_send_cb(&http_req);
    CPP
  2. The call will return response headers (i.e., ADRUM_*) that contain information for correlating the business transaction. If you were to print these BT response headers, you would see something like the following:

    ADRUM_0: clientRequestGUID:0f5c7602-9b69-4e40-85a6-e0abf288accf
    ADRUM_1: globalAccountName:eum-mobile_4debdbad-3f8e-4f6d-8faf-e5f5781ec0d7
    ADRUM_2: btId:3867
    ADRUM_3: serverSnapshotType:f
    ADRUM_4: btDuration:829
    CPP
  3. Add these BT response headers to the network event that you send to the EUM Server:

    /* Create a network event to report to the EUM Server. */
    appd_iot_network_request_event_t network_event;
    appd_iot_init_to_zero(&network_event, sizeof(appd_iot_network_request_event_t));
    
    /* Add information about the network event that you want to report. */
    network_event.url = "<url-to-your-business-app-enabled-for-bts>";
    network_event.resp_code = http_resp->resp_code;
    
    /* Assign the returned BT response headers from the call to the business app to the headers of the request. */
    network_event.resp_headers = http_resp->headers;
    
    // Add the network event to beacon to send to the EUM Server. */
    appd_iot_add_network_request_event(network_event);
    appd_iot_send_all_events();
    CPP
  4. In the Controller UI, you should be able to view the correlated business transaction in the Device Details dialog. 

Compile and Run Your App with the SDK Library File

  1. Compile your program. For example, if the driver file is main.cpp:

    $ g++ -c main.cpp -I<appd_iot_sdk_dir>/include
    BASH
  2. Create the binary with the object code of your application and linking  AppDynamics IoT C++ SDK library.

    $ g++ main.o <appd_iot_sdk_dir>/lib/libappdynamics_iot.so -o main
    BASH
    $ g++ main.o <appd_iot_sdk_dir>/lib/libappdynamics_iot.dylib -o main
    BASH

    You can combine steps 1 and 2 into one step as below:

    $ g++ main.cpp -o main -I<appd_iot_cpp_sdk_dir>/include -L<appd_iot_cpp_sdk_dir>/lib -lappdynamics_iot
    BASH
  3. Set the environment variable DYLD_LIBRARY_PATH to the PATH where the SDK library is installed. This will let dynamic linker know the directory to search for shared libraries.

    $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<appd_iot_cpp_sdk_dir>/lib
    BASH
    $ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:<appd_iot_cpp_sdk_dir>/lib
    BASH

  4. Run your program. For example: 

    $ ./main
    BASH

Verify the Instrumentation in the Controller UI

See Confirm the IoT Application Reported Data to the Controller to verify the instrumentation. 

Customize the IoT C++ Instrumentation (Optional)

 You can further customize the IoT C++ instrumentation using the IoT C++ SDK. See the latest IoT C++ SDK documentation or the previous versions listed below:

Run the Sample C++ Application

The sample C++ application sends sample data for Custom, Network Request, and Error events. The data mocks a smart car application, capturing usage information, network performance, and errors.

To run the sample app, follow the instructions given in Sample Application using IoT C++ SDK.