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.

Installation and getting started

Follow the Quickstart instructions within the Datadog app for the best experience, including:

  • Step-by-step instructions scoped to your deployment configuration (hosts, Docker, Kubernetes, or Amazon ECS).
  • Dynamically set service, env, and version tags.
  • Enable features such as ingesting 100% of traces, and Trace ID injection into logs during setup.

Configure the Datadog Agent for APM

Install and configure the Datadog Agent to receive traces from your instrumented application. By default the Datadog Agent is enabled in your datadog.yaml file under apm_config with enabled: true and listens for trace traffic at localhost:8126. For containerized environments, follow the links below to enable trace collection within the Datadog Agent.

  1. Set apm_non_local_traffic: true in the apm_config section of your main datadog.yaml configuration file.

  2. See the specific setup instructions to ensure that the Agent is configured to receive traces in a containerized environment:

Docker
Kubernetes
Amazon ECS
ECS Fargate

  1. The tracing client sends traces to localhost:8126 by default. If this is not the correct host and port for your Agent, set the DD_AGENT_HOST and DD_TRACE_AGENT_PORT environment variables.

To connect to the Agent using Unix Domain Sockets, use DD_TRACE_AGENT_URL instead. Set it to the same value as the Agent’s value for DD_APM_RECEIVER_SOCKET.

To set up Datadog APM in AWS Lambda, see the Tracing Serverless Functions documentation.

Tracing is available for other environments, including Heroku, Cloud Foundry, AWS Elastic Beanstalk, and Azure App Service.

For other environments, see the Integrations documentation for that environment and contact support if you encounter setup issues.

Instrument your application

After the Agent is installed, follow these steps to add the Datadog tracing library to your C++ applications 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.

Configuration

If needed, configure the tracing library to send application performance telemetry data as you require, including setting up Unified Service Tagging. Read Library Configuration for details.

Further Reading