Tracing C++ Applications
Security Monitoring is now available Security Monitoring is now available

Tracing C++ Applications

Note: C++ does not provide integrations for OOTB instrumentation, but it’s used by Proxy tracing such as Envoy and Nginx. For compatibility requirements for the C++ Tracer, visit the Compatibility Requirements page.

Getting Started

If you already have a Datadog account you can find step-by-step instructions in our in-app guides for either host-based or container-based set ups.

Otherwise, to begin tracing applications written in any language, first install and configure the Datadog Agent.

Compile against OpenTracing-cpp.

Installation

Datadog tracing can be enabled in one of two ways:

  • Compile against dd-opentracing-cpp, where the Datadog lib is compiled in and configured in code
  • Dynamic loading, where the Datadog OpenTracing library is loaded at runtime and configured via JSON

Compile against dd-opentracing-cpp

# Gets the latest release version number from Github.
get_latest_release() {
  wget -qO- "https://api.github.com/repos/$1/releases/latest" |
    grep '"tag_name":' |
    sed -E 's/.*"([^"]+)".*/\1/';
}
DD_OPENTRACING_CPP_VERSION="$(get_latest_release DataDog/dd-opentracing-cpp)"
# Download and install dd-opentracing-cpp library.
wget https://github.com/DataDog/dd-opentracing-cpp/archive/${DD_OPENTRACING_CPP_VERSION}.tar.gz -O dd-opentracing-cpp.tar.gz
mkdir -p dd-opentracing-cpp/.build
tar zxvf dd-opentracing-cpp.tar.gz -C ./dd-opentracing-cpp/ --strip-components=1
cd dd-opentracing-cpp/.build
# Download and install the correct version of opentracing-cpp, & other deps.
../scripts/install_dependencies.sh
cmake ..
make
make install

Include <datadog/opentracing.h> and create the tracer:

// tracer_example.cpp
#include <datadog/opentracing.h>
#include <iostream>
#include <string>

int main(int argc, char* argv[]) {
  datadog::opentracing::TracerOptions tracer_options{"localhost", 8126, "compiled-in example"};
  auto tracer = datadog::opentracing::makeTracer(tracer_options);

  // Create some spans.
  {
    auto span_a = tracer->StartSpan("A");
    span_a->SetTag("tag", 123);
    auto span_b = tracer->StartSpan("B", {opentracing::ChildOf(&span_a->context())});
    span_b->SetTag("tag", "value");
  }

  tracer->Close();
  return 0;
}

Link against libdd_opentracing and libopentracing, making sure that they are both in your LD_LIBRARY_PATH:

g++ -std=c++14 -o tracer_example tracer_example.cpp -ldd_opentracing -lopentracing
./tracer_example

Dynamic Loading

get_latest_release() {
  wget -qO- "https://api.github.com/repos/$1/releases/latest" |
    grep '"tag_name":' |
    sed -E 's/.*"([^"]+)".*/\1/';
}
DD_OPENTRACING_CPP_VERSION="$(get_latest_release DataDog/dd-opentracing-cpp)"
OPENTRACING_VERSION="$(get_latest_release opentracing/opentracing-cpp)"
# Download and install OpenTracing-cpp
wget https://github.com/opentracing/opentracing-cpp/archive/${OPENTRACING_VERSION}.tar.gz -O opentracing-cpp.tar.gz
mkdir -p opentracing-cpp/.build
tar zxvf opentracing-cpp.tar.gz -C ./opentracing-cpp/ --strip-components=1
cd opentracing-cpp/.build
cmake ..
make
make install
# Install dd-opentracing-cpp shared plugin.
wget https://github.com/DataDog/dd-opentracing-cpp/releases/download/${DD_OPENTRACING_CPP_VERSION}/linux-amd64-libdd_opentracing_plugin.so.gz
gunzip linux-amd64-libdd_opentracing_plugin.so.gz -c > /usr/local/lib/libdd_opentracing_plugin.so

Include <opentracing/dynamic_load.h> and load the tracer from libdd_opentracing_plugin.so:

// tracer_example.cpp
#include <opentracing/dynamic_load.h>
#include <iostream>
#include <string>

int main(int argc, char* argv[]) {
  // Load the tracer library.
  std::string error_message;
  auto handle_maybe = opentracing::DynamicallyLoadTracingLibrary(
      "/usr/local/lib/libdd_opentracing_plugin.so", error_message);
  if (!handle_maybe) {
    std::cerr << "Failed to load tracer library " << error_message << "\n";
    return 1;
  }

  // Read in the tracer's configuration.
  std::string tracer_config = R"({
      "service": "dynamic-load example",
      "agent_host": "localhost",
      "agent_port": 8126
    })";

  // Construct a tracer.
  auto& tracer_factory = handle_maybe->tracer_factory();
  auto tracer_maybe = tracer_factory.MakeTracer(tracer_config.c_str(), error_message);
  if (!tracer_maybe) {
    std::cerr << "Failed to create tracer " << error_message << "\n";
    return 1;
  }
  auto& tracer = *tracer_maybe;

  // Create some spans.
  {
    auto span_a = tracer->StartSpan("A");
    span_a->SetTag("tag", 123);
    auto span_b = tracer->StartSpan("B", {opentracing::ChildOf(&span_a->context())});
    span_b->SetTag("tag", "value");
  }

  tracer->Close();
  return 0;
}

Just link against libopentracing, making sure that libopentracing.so is in your LD_LIBRARY_PATH:

g++ -std=c++11 -o tracer_example tracer_example.cpp -lopentracing
./tracer_example

Note: OpenTracing requires C++ 11 or higher.

Environment Variables

VariableVersionDefaultNote
DD_AGENT_HOSTv0.3.6localhostSets the host where traces are sent (the host running the Agent). Can be a hostname or an IP address. Ignored if DD_TRACE_AGENT_URL is set.
DD_TRACE_AGENT_PORTv0.3.68126Sets the port where traces are sent (the port where the Agent is listening for connections). Ignored if DD_TRACE_AGENT_URL is set.
DD_TRACE_AGENT_URLv1.1.4Sets the URL endpoint where traces are sent. Overrides DD_AGENT_HOST and DD_TRACE_AGENT_PORT if set. This URL supports http, https and unix address schemes.
DD_ENVv1.0.0If specified, adds the env tag with the specified value to all generated spans.
DD_SERVICEv1.1.4If specified, sets the default service name. Otherwise the service name must be provided via TracerOptions or JSON configuration.
DD_TRACE_ANALYTICS_ENABLEDv1.1.3falseEnable App Analytics globally for the application.
DD_TRACE_ANALYTICS_SAMPLE_RATEv1.1.3Sets the App Analytics sampling rate. Overrides DD_TRACE_ANALYTICS_ENABLED if set. A floating point number between 0.0 and 1.0.
DD_TRACE_SAMPLING_RULESv1.1.4[{"sample_rate": 1.0}]A JSON array of objects. Each object must have a “sample_rate”, and the “name” and “service” fields are optional. The “sample_rate” value must be between 0.0 and 1.0 (inclusive). Rules are applied in configured order to determine the trace’s sample rate.
DD_VERSIONv1.1.4If specified, adds the version tag with the specified value to all generated spans.
DD_TAGSv1.1.4If specified, will add tags to all generated spans. A comma-separated list of key:value pairs.
DD_PROPAGATION_STYLE_INJECTv0.4.1DatadogPropagation style(s) to use when injecting tracing headers. Datadog, B3, or Datadog B3.
DD_PROPAGATION_STYLE_EXTRACTv0.4.1DatadogPropagation style(s) to use when extracting tracing headers. Datadog, B3, or Datadog B3.

Change Agent Hostname

Configure your application level tracers to submit traces to a custom Agent hostname. The C++ Tracing Module automatically looks for and initializes with the ENV variables DD_AGENT_HOST and DD_TRACE_AGENT_PORT.

To connect to the agent using Unix Domain Sockets, DD_TRACE_AGENT_URL can be used instead. The value should match the Agent’s value for DD_APM_RECEIVER_SOCKET.

Further Reading