First of all, thanks for contributing!
This document provides some basic guidelines for contributing to this repository. To propose improvements, feel free to submit a PR or open an Issue.
Note: Datadog requires that all commits within this repository must be signed, including those within external contribution PRs. Please ensure you have followed GitHub's Signing Commits guide before proposing a contribution. PRs lacking signed commits will not be processed and may be rejected.
For any urgent matters (such as outages) or issues concerning the Datadog service or UI, contact our support team via https://docs.datadoghq.com/help/ for direct, faster assistance.
You may submit a bug report concerning the Datadog C++ SDK by opening a GitHub Issue. Use the appropriate template and provide all listed details to help us resolve the issue.
To build the Datadog C++ SDK, you'll need CMake 3.21 or newer, along with a supported C++ compiler toolchain for your operating system. We test our builds against the following compiler versions:
- On macOS: Apple Clang 15, installed with Xcode 15.3
- On Linux: Clang 15, Clang 20, GCC 11, and GCC 13, all with libstdc++
- On Windows: Microsoft Visual C++ 17.14 (vc143), installed with Visual Studio 2022
We use clang-format for automatic source code formatting, and we use clang-tidy for static analysis. These tools are not strictly required in order to build the SDK, but you should use them if you intend to submit a PR.
Regardless of the compiler toolchain used to build the SDK, all clang-format and clang-tidy checks are done using version 20.1.8 of these tools.
If you enable either tool in your CMake configuration (via DD_ENABLE_CLANG_TIDY and DD_ENABLE_CLANG_FORMAT), the required versions must be resolvable: either present in your PATH, or already installed under llvm-tools/ (e.g. from a prior auto-install). If you set -DDD_DEVELOPMENT_ALLOW_AUTO_INSTALL=ON, CMake will download them to llvm-tools/ automatically.
Alternatively, you can install the appropriate LLVM/Clang release and ensure that its bin/ directory is in your PATH.
If you want to make changes to SDK's source, you can configure your CMake build using the DD_DEVELOPMENT option:
cmake -DDD_DEVELOPMENT=ON -S . -B build
DD_DEVELOPMENT=ON is a convenience flag that enables the options you typically want while working on the SDK itself: it builds the examples, tests, and developer tools; enables asserts; and turns on clang-format, clang-tidy, coverage instrumentation, and sanitizers (ASan + UBSan by default). You can override any of these individually with the options listed below.
Other important options include:
-DCMAKE_BUILD_TYPE=Debug(orRelease, orRelWithDbgInfo)-DBUILD_SHARED_LIBS=ONwill build the SDK as a shared library; useOFFfor a static library build-DDD_HTTP_USE_SYSTEM_LIBCURL=ONwill link the SDK dynamically against the version of libcurl installed on your system; useOFFto download libcurl, build it from source, and link it into thedd-sdk-cppbinary-DDD_DEVELOPMENT_ALLOW_AUTO_INSTALL=ONwill permit the CMake configuration process to download clang-format and clang-tidy if not already present on your system-DDD_ENABLE_CLANG_FORMAT=OFFand-DDD_ENABLE_CLANG_TIDY=OFFwill omit those tools from the build-DDD_ENABLE_COVERAGE=OFFwill disablellvm-covinstrumentation in environments where it's unsupported or undesirable-DDD_ENABLE_SANITIZERS=will disable sanitizers (useful for testing crash behavior etc.); default isASan,UBSan;TSanand/orMSancan also be used as alternatives
For a complete list of configuration options, see CMakeLists.txt.
To run the build once you've configured a CMake build directory, you can use CMake to start a build:
cmake --build build
Note that when using Visual Studio, the build configuration must be passed at build-time:
cmake --build build --config Debug
Unit tests are written using Catch2. If you configure with DD_DEVELOPMENT (or DD_BUILD_TESTING), the build will produce a Catch2 binary at ./build/tests/tests. You may run that binary directly, or use CTest, to invoke the test suite:
ctest --test-dir build
Before opening a PR, format and lint your changes. CI runs the equivalent of these commands and will fail on any diff.
First-time setup — configures the build and, if clang-format / clang-tidy 20.1.8 are not already installed, downloads them into llvm-tools/. DD_DEVELOPMENT=ON already implies DD_ENABLE_CLANG_FORMAT=ON and DD_ENABLE_CLANG_TIDY=ON; they are passed explicitly below so this command also fixes an existing build/ that was previously configured with them disabled:
cmake -DDD_DEVELOPMENT=ON \
-DDD_ENABLE_CLANG_FORMAT=ON \
-DDD_ENABLE_CLANG_TIDY=ON \
-DDD_DEVELOPMENT_ALLOW_AUTO_INSTALL=ON \
-S . -B build
Note: the auto-install downloads the full LLVM release tarball (~1 GB on Linux, ~1.4 GB on macOS), so the first configure can take several minutes.
Format all SDK sources in-place:
cmake --build build --target format
Verify formatting without modifying files (what CI runs):
cmake --build build --target check-format
Verify formatting, build the tests (which runs clang-tidy at compile time via CXX_CLANG_TIDY), and run CTest — a single command that mirrors CI:
cmake --build build --target check-all
On Windows, the formatting targets do not require a --config flag (they are configuration-agnostic custom targets).
No rule to make target 'format'— you are on an older checkout or the build was configured withDD_ENABLE_CLANG_FORMAT=OFF. Reconfigure using the command above.The 'format' target is not available in this build— clang-format support is disabled or could not be resolved. Follow the hint in the error message, or reconfigure as above.- Hash mismatch during LLVM download — delete
llvm-tools/and reconfigure; the auto-installer retries once automatically but will give up after a second failure. - Want to skip these tools entirely? — configure with
-DDD_ENABLE_CLANG_FORMAT=OFF -DDD_ENABLE_CLANG_TIDY=OFF. Your PR will then need to pass these checks in CI; if you are an external contributor, it is safer to run them locally first.
include-c/contains public headers for the C API.include-cpp/contains public headers for the C++ API.src/datadog/c/implements the C API.src/datadog/cpp/implements the C++ API.src/datadog/impl/implements the core business logic of the library, split into:core/implements the primary business logic of the SDK, including:util/: Internal utility code for commonly-used functionality like asserts, diagnostic logging, etc.attribute/: Copy-on-Write implementation and other utilities used in conjunction with API-layerdatadog::Attributetypejson/: Minimal JSON serialization routines for encoding event data and attribute valuesevents/: Utilities used to build JSON-serializable struct types for event payloadsfeature_types/: Feature-specific data types used across module boundaries, including event payload types and shared context typesstorage/: Code used to access the filesystem, prepare the SDK's.datadog/storage directory, and write and migrate event dataplatform/: Implementations of platform-specific functionality like system info, HTTP client, and access to the system clockcore.hpp: Internal core of the SDK, which handles initialization, feature registration, and which runs the storage and upload threads.context.hpp: Common types likeCoreContext, which provides all features with a snapshot of the SDK's essential state.feature.hpp: Interfaces used to implement specific features, allowing a feature implementation to register itself with the core, define how it generates events for storage and processes them for upload, and implement its user-facing API.feature_scope.hpp: Definition ofFeatureScope, the interface that gives each feature to access to Core functionality required to access and update context, generate events, etc.context_thread.hpp: The context thread, where work initiated by API calls is enqueued to be processed in the background (so as not to block the calling thread), ultimately modifyingCoreContextand/or sending events to the storage thread.storage_thread.hpp: The storage thread, which asynchronously writes event payloads to disk, batched into TLV-formatted binary files, as those events are generated by feature implementations.upload_thread.hpp: The upload thread, which periodically reads batches of events from storage, passes them to the appropriate feature implementation for processing, then sends them to intake over HTTP.messaging_thread.hpp: The messaging thread, where messages are routed and handled, allowing features to respond to state changes that have occurred in the Core or in other features.
logging/allows an application to create loggers which will send messages to Datadog.rum/allows an application to keep track of application state and user interactions via Views, Actions, Resources, etc., sending RUM events to Datadog.crash_reporting/automatically detects application crashes and sends crash reports to Datadog as RUM Errors.- Multiple crash-handling mechanisms are planned; currently only
DD_CRASH_MODE=inprocessis supported.
- Multiple crash-handling mechanisms are planned; currently only
tests/: Unit tests for code insrc/, along with test-only support code.examples/demonstrates usage of both C and C++ APIs.
Our CI pipeline runs on GitLab, and jobs are not publicly visible.
If you have Docker installed, you can use docker-ci.sh to run containers that replicate the Linux build environment used in our CI pipeline.
For example, to run a development build with Clang 20 and then run the test suite:
./docker-ci.sh run unit-test --exit
Or to produce precompiled binaries using GCC 11:
./docker-ci.sh --toolchain gcc11 run package --clean --exit
Run the script with no arguments for usage information.