Instrument your C++ application for Splunk Observability Cloud

Use the OpenTelemetry Collector to send traces from your C++ applications to Splunk Observability Cloud.

You can use the OpenTelemetry Collector to send traces from C++ applications to Splunk APM. Follow these steps to instrument your C++ application:

  1. Build the OpenTelemetry C++ libraries

  2. Add the required dependencies

  3. Initialize the OpenTelemetry tracer

  4. Generate spans for your application

Prerequisites

Before you start, install the following components:

  • C++ compiler supporting C++ versions 14 and higher

  • CMake version 3.20 or higher

Additionally, install the Splunk Distribution of OpenTelemetry Collector. The following distributions are available:

After installing the Collector, have an instance of the Collector running in your environment.

Build the OpenTelemetry C++ libraries

To instrument your C++ code, install and build the OpenTelemetry C++ libraries. Follow these steps:

  1. In your project directory, create a directory called opentelemetry-cpp.

  2. In the opentelemetry-cpp directory, clone the OpenTelemetry C++ repository:

    git clone https://github.com/open-telemetry/opentelemetry-cpp.git
  3. Run the following commands to build the OpenTelemetry C++ libraries:

    cd opentelemetry-cpp
    mkdir build
    cd build
    cmake ..
    cmake --build .

Add the required dependencies

Before you get started with instrumentation, the OpenTelemetry instrumentation for C++ requires several dependencies.

In your CMakeLists.txt file, add the following code to include these dependencies:

find_package(opentelemetry-cpp CONFIG REQUIRED)

target_include_directories(foo PRIVATE ${OPENTELEMETRY_CPP_INCLUDE_DIRS})
target_link_libraries(foo PRIVATE ${OPENTELEMETRY_CPP_LIBRARIES})

Initialize the OpenTelemetry tracer

The OpenTelemetry tracer runs alongside your C++ application, generating telemetry data when the application receives calls.

To start the tracer, add the following code to your main.cpp file. This code adds functions that you can call in your application to initialize and clean up the OpenTelemetry tracer.

#include "opentelemetry/exporters/ostream/span_exporter_factory.h"
#include "opentelemetry/sdk/trace/exporter.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"

using namespace std;
namespace trace_api = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace trace_exporter = opentelemetry::exporter::trace;
namespace otlp = opentelemetry::exporter::otlp;

namespace {
    void InitTracer() {
        trace_sdk::BatchSpanProcessorOptions bspOpts{};
        // creates a new options object and sets the OTLP endpoint URL
        otlp::OtlpHttpExporterOptions opts;
        opts.url = "http://localhost:4318/v1/traces";

        // pass the options object as an argument for the exporter creator
        auto exporter = otlp::OtlpHttpExporterFactory::Create(opts);
        auto processor = trace_sdk::BatchSpanProcessorFactory::Create(std::move(exporter), bspOpts);
        std::shared_ptr<trace_api::TracerProvider> provider = trace_sdk::TracerProviderFactory::Create(std::move(processor));
        trace_api::Provider::SetTracerProvider(provider);
    }

    void CleanupTracer() {
        std::shared_ptr<opentelemetry::trace::TracerProvider> none;
        trace_api::Provider::SetTracerProvider(none);
    }
}

int main() {
    InitTracer();

    // Other application code

    CleanupTracer();
    return 0;
}

Generate spans for your application

The OpenTelemetry Collector gathers spans that your application generates. To start this process, create spans for the operations you want to track by editing your application code.

Follow these steps to create spans:

  1. Create a tracer object. You need a tracer to create and start spans.

    auto provider = opentelemetry::trace::Provider::GetTracerProvider();
    auto tracer = provider->GetTracer("foo_library", "1.0.0");
  2. Start a span. Your application emits the span whenever the associated operation is called.

    auto span = tracer->StartSpan("HandleRequest");

While the application is running, your local instance of the OpenTelemetry Collector listens for these spans and sends them to Splunk Observability Cloud. You can then see your data in Splunk APM.

Send data directly to Splunk Observability Cloud

By default, all data goes to the local instance of the Splunk Distribution of OpenTelemetry Collector.

If you need to send data directly to Splunk Observability Cloud, set the following environment variables:

OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_TRACES_HEADERS=x-sf-token=<access_token>
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<realm>.signalfx.com

Replace <realm> with your Splunk Observability Cloud realm and <access-token> with your Splunk Observability Cloud access token with ingest permissions.

Learn more

To learn more about realms and access tokens, see Create and manage organization access tokens using Splunk Observability Cloud.

For information about the types of spans you can create, see https://opentelemetry.io/docs/languages/cpp/instrumentation/#traces.

For a walkthrough that uses a sample C++ application, see https://opentelemetry.io/docs/languages/cpp/. This walkthrough uses the upstream OpenTelemetry Collector, not the Splunk Distribution.

OpenTelemetry C++ also has several example configurations. To view them, see https://github.com/open-telemetry/opentelemetry-cpp/tree/main/examples.