Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,16 @@ jobs:
run: scoop install main/cmake@4.0.1 main/ninja
- name: Build
run: |
& 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\Tools\\Launch-VsDevShell.ps1' -arch ${{ matrix.arch }}
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$vs = & $vswhere -latest -products * -property installationPath
& (Join-Path $vs 'Common7\Tools\Launch-VsDevShell.ps1') -arch ${{ matrix.arch }}
cmake --preset=ci-msvc -B build -DCMAKE_BUILD_TYPE=Debug .
cmake --build build -j $env:MAKE_JOB_COUNT -v
- name: Test
run: |
& 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\Tools\\Launch-VsDevShell.ps1' -arch ${{ matrix.arch }}
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$vs = & $vswhere -latest -products * -property installationPath
& (Join-Path $vs 'Common7\Tools\Launch-VsDevShell.ps1') -arch ${{ matrix.arch }}
.\build\test\tests.exe -r junit -o report.xml
- name: Get Datadog credentials
if: ${{ !cancelled() && github.event_name != 'pull_request' }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ build/
dist/
MODULE.bazel.lock
out/
rust/**/target/
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
[submodule "benchmark/tinycc"]
path = benchmark/tinycc
url = https://github.com/TinyCC/tinycc.git
[submodule "vendor/libdatadog"]
path = vendor/libdatadog
url = https://github.com/datadog/libdatadog.git
branch = pawel/no-std-library-config
40 changes: 39 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,40 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")

filegroup(
name = "libdd_library_config_sources",
srcs = glob(["vendor/libdatadog/libdd-library-config/src/**/*.rs"], allow_empty = True),
visibility = ["//visibility:public"],
)

exports_files(
["vendor/libdatadog/libdd-library-config/src/lib.rs"],
visibility = ["//visibility:public"],
)

cc_library(
name = "dd_trace_cpp_stable_config",
srcs = [
"src/datadog/stable_config_ffi.h",
"src/datadog/stable_config_loader.cpp",
],
hdrs = ["include/datadog/stable_config_loader.h"],
strip_include_prefix = "include/",
visibility = ["//visibility:public"],
deps = [
":dd_trace_cpp",
"//rust/stable-config-ffi:stable_config_ffi",
],
)

cc_test(
name = "stable_config_loader_test",
srcs = ["test/bazel_stable_config_test.cpp"],
data = [
"test/fixtures/stable_config/fleet.yaml",
"test/fixtures/stable_config/local.yaml",
],
deps = [":dd_trace_cpp_stable_config"],
)

cc_library(
name = "dd_trace_cpp",
Expand Down Expand Up @@ -67,6 +103,7 @@ cc_library(
"src/datadog/span_sampler.cpp",
"src/datadog/span_sampler.h",
"src/datadog/span_sampler_config.cpp",
"src/datadog/stable_config.cpp",
"src/datadog/string_util.cpp",
"src/datadog/string_util.h",
"src/datadog/tag_propagation.cpp",
Expand Down Expand Up @@ -145,6 +182,7 @@ cc_library(
"include/datadog/span_defaults.h",
"include/datadog/span_matcher.h",
"include/datadog/span_sampler_config.h",
"include/datadog/stable_config.h",
"include/datadog/string_view.h",
"include/datadog/telemetry/configuration.h",
"include/datadog/telemetry/metrics.h",
Expand Down
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ project(
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(BUILD_STATIC_LIBS "Build static libraries" ON)
option(DD_TRACE_BUILD_C_BINDING "Build C binding" OFF)
option(DD_TRACE_BUILD_STABLE_CONFIG "Build the libdatadog stable config loader" OFF)

if (WIN32)
option(DD_TRACE_STATIC_CRT "Build dd-trace-cpp with static CRT with MSVC" OFF)
Expand Down Expand Up @@ -166,6 +167,7 @@ target_sources(dd-trace-cpp-objects
include/datadog/span_defaults.h
include/datadog/span_matcher.h
include/datadog/span_sampler_config.h
include/datadog/stable_config.h
include/datadog/string_view.h
include/datadog/trace_id.h
include/datadog/trace_sampler_config.h
Expand Down Expand Up @@ -214,6 +216,7 @@ target_sources(dd-trace-cpp-objects
src/datadog/span_matcher.cpp
src/datadog/span_sampler_config.cpp
src/datadog/span_sampler.cpp
src/datadog/stable_config.cpp
src/datadog/string_util.cpp
src/datadog/tags.cpp
src/datadog/tag_propagation.cpp
Expand Down Expand Up @@ -367,6 +370,16 @@ if (BUILD_STATIC_LIBS)
)
endif ()

if (DD_TRACE_BUILD_STABLE_CONFIG)
include(cmake/stable_config.cmake)
if (DD_TRACE_BUILD_TESTING)
target_sources(tests PRIVATE test/test_stable_config.cpp)
target_link_libraries(tests PRIVATE dd-trace-cpp::stable-config)
target_compile_definitions(tests PRIVATE
"DD_TRACE_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"")
endif ()
endif ()

# install target
write_basic_package_version_file(
"${PROJECT_NAME}-config-version.cmake"
Expand Down
25 changes: 25 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,28 @@ bazel_dep(name = "abseil-cpp", version = "20260817.0", repo_name = "com_google_a
bazel_dep(name = "bazel_skylib", version = "1.9.2")
bazel_dep(name = "platforms", version = "1.1.0")
bazel_dep(name = "rules_cc", version = "0.2.22")
bazel_dep(name = "rules_rs", version = "0.0.112")

rust_toolchains = use_extension("@rules_rs//rs/toolchains:module_extension.bzl", "toolchains")
rust_toolchains.toolchain(
edition = "2021",
version = "1.92.0",
)
use_repo(rust_toolchains, "default_rust_toolchains")
register_toolchains("@default_rust_toolchains//...")

stable_config_crates = use_extension("@rules_rs//rs:extensions.bzl", "crate")
stable_config_crates.from_cargo(
name = "stable_config_crates",
cargo_lock = "//rust/stable-config-bazel-deps:Cargo.lock",
cargo_toml = "//rust/stable-config-bazel-deps:Cargo.toml",
platform_triples = [
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-pc-windows-msvc",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
],
)
use_repo(stable_config_crates, "stable_config_crates")
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,48 @@ Installation places a shared library and public headers into the appropriate sys
cmake --install build --prefix=.install
```

### Stable configuration

The optional stable configuration loader uses the `libdd-library-config` crate
from the pinned `vendor/libdatadog` submodule. The CMake build requires Cargo
and Rust.

```shell
git submodule update --init vendor/libdatadog
cmake -B build -DDD_TRACE_BUILD_STABLE_CONFIG=ON .
cmake --build build -j
```

With Bazel and Bzlmod, build and test the loader with:

```shell
bazel test //:stable_config_loader_test
```

Link the CMake target `dd-trace-cpp::stable-config` or the Bazel target
`//:dd_trace_cpp_stable_config`. Bazel manages Rust dependencies and the
toolchain through `rules_rs` in `MODULE.bazel`. Load configuration before
creating a tracer:

```c++
#include <datadog/stable_config_loader.h>

datadog::tracing::TracerConfig config;
auto finalized = datadog::tracing::finalize_config_with_stable_config(config, "cpp");
if (!finalized) {
// Handle finalized.error().
}
```

The loader reads the standard local and fleet YAML paths used by libdatadog.
Pass local and fleet paths as the third and fourth arguments to use other files.
Settings resolve in this order: defaults, local YAML, environment variables,
fleet YAML, and values in `TracerConfig`. The stable configuration overload
records the source and config ID in configuration telemetry. The existing
`finalize_config(config)` overload keeps its original behavior.
Call `clear_rules()` on `trace_sampler` or `span_sampler` to override stable
sampling rules with an empty list.

### Optional: Linking to the shared library

In case you decided to build the shared library:
Expand Down
7 changes: 7 additions & 0 deletions cmake/dd-trace-cpp-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ if(DD_TRACE_TRANSPORT STREQUAL "curl")
find_dependency(CURL)
endif()

if(@DD_TRACE_BUILD_STABLE_CONFIG@ AND
NOT TARGET dd-trace-cpp-stable-config-rust-lib)
add_library(dd-trace-cpp-stable-config-rust-lib STATIC IMPORTED)
set_target_properties(dd-trace-cpp-stable-config-rust-lib PROPERTIES
IMPORTED_LOCATION "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@/@DD_TRACE_RUST_FILE_NAME@")
endif()

include("${CMAKE_CURRENT_LIST_DIR}/dd-trace-cpp-targets.cmake")
63 changes: 63 additions & 0 deletions cmake/stable_config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
find_program(DD_TRACE_CARGO cargo REQUIRED)

file(GLOB_RECURSE DD_TRACE_LIBDD_LIBRARY_CONFIG_SOURCES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/vendor/libdatadog/libdd-library-config/src/*.rs")

set(DD_TRACE_RUST_TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/stable-config-rust")
set(DD_TRACE_RUST_FILE_NAME
"${CMAKE_STATIC_LIBRARY_PREFIX}dd_trace_cpp_stable_config_ffi${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(DD_TRACE_RUST_LIBRARY
"${DD_TRACE_RUST_TARGET_DIR}/release/${DD_TRACE_RUST_FILE_NAME}")

add_custom_command(
OUTPUT "${DD_TRACE_RUST_LIBRARY}"
COMMAND ${CMAKE_COMMAND} -E env
"CARGO_TARGET_DIR=${DD_TRACE_RUST_TARGET_DIR}"
${DD_TRACE_CARGO} build --release --locked
--manifest-path "${CMAKE_CURRENT_SOURCE_DIR}/rust/stable-config-ffi/Cargo.toml"
DEPENDS
rust/stable-config-ffi/Cargo.toml
rust/stable-config-ffi/Cargo.lock
rust/stable-config-ffi/src/lib.rs
vendor/libdatadog/libdd-library-config/Cargo.toml
${DD_TRACE_LIBDD_LIBRARY_CONFIG_SOURCES}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
VERBATIM
)

add_custom_target(dd-trace-cpp-stable-config-rust
DEPENDS "${DD_TRACE_RUST_LIBRARY}")
add_library(dd-trace-cpp-stable-config-rust-lib STATIC IMPORTED GLOBAL)
set_target_properties(dd-trace-cpp-stable-config-rust-lib PROPERTIES
IMPORTED_LOCATION "${DD_TRACE_RUST_LIBRARY}")
add_dependencies(dd-trace-cpp-stable-config-rust-lib
dd-trace-cpp-stable-config-rust)

add_library(dd-trace-cpp-stable-config STATIC
src/datadog/stable_config_loader.cpp)
Comment thread
pawelchcki marked this conversation as resolved.
add_library(dd-trace-cpp::stable-config ALIAS dd-trace-cpp-stable-config)
set_target_properties(dd-trace-cpp-stable-config PROPERTIES EXPORT_NAME stable-config)
set_target_properties(dd-trace-cpp-stable-config PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_compile_features(dd-trace-cpp-stable-config PUBLIC cxx_std_17)
target_include_directories(dd-trace-cpp-stable-config PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_sources(dd-trace-cpp-stable-config PUBLIC
FILE_SET public_headers TYPE HEADERS BASE_DIRS include
FILES include/datadog/stable_config_loader.h)
target_link_libraries(dd-trace-cpp-stable-config
PUBLIC dd-trace-cpp-stable-config-rust-lib)
if (BUILD_SHARED_LIBS)
target_link_libraries(dd-trace-cpp-stable-config PUBLIC dd-trace-cpp::shared)
elseif (BUILD_STATIC_LIBS)
target_link_libraries(dd-trace-cpp-stable-config PUBLIC dd-trace-cpp::static)
else ()
message(FATAL_ERROR "Stable config requires a dd-trace-cpp library")
endif ()

install(TARGETS dd-trace-cpp-stable-config
EXPORT dd-trace-cpp-targets
FILE_SET public_headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES "${DD_TRACE_RUST_LIBRARY}"
DESTINATION ${CMAKE_INSTALL_LIBDIR})
38 changes: 26 additions & 12 deletions include/datadog/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ struct ConfigMetadata {
ENVIRONMENT_VARIABLE, // Originating from environment variables
CODE, // Defined in code
REMOTE_CONFIG, // Retrieved from remote configuration
DEFAULT // Default value
DEFAULT, // Default value
LOCAL_STABLE_CONFIG,
FLEET_STABLE_CONFIG
};

// Name of the configuration parameter
Expand All @@ -56,11 +58,17 @@ struct ConfigMetadata {
Origin origin;
// Optional error associated with the configuration parameter
Optional<Error> error;
Optional<std::string> config_id;

ConfigMetadata() = default;
ConfigMetadata(ConfigName n, std::string v, Origin orig,
Optional<Error> err = nullopt)
: name(n), value(std::move(v)), origin(orig), error(std::move(err)) {}
Optional<Error> err = nullopt,
Optional<std::string> id = nullopt)
: name(n),
value(std::move(v)),
origin(orig),
error(std::move(err)),
config_id(std::move(id)) {}
};

// Returns the final configuration value using the following
Expand Down Expand Up @@ -96,7 +104,11 @@ Value resolve_and_record_config(
const Optional<Value>& from_env, const Optional<Value>& from_user,
std::unordered_map<ConfigName, std::vector<ConfigMetadata>>* metadata,
ConfigName config_name, DefaultValue fallback = nullptr,
Stringifier to_string_fn = nullptr) {
Stringifier to_string_fn = nullptr,
ConfigMetadata::Origin from_env_origin =
ConfigMetadata::Origin::ENVIRONMENT_VARIABLE,
Optional<std::string> from_env_config_id = nullopt,
bool programmatic_wins = false) {
auto stringify = [&](const Value& v) -> std::string {
if constexpr (!std::is_same_v<Stringifier, std::nullptr_t>) {
return to_string_fn(v); // use provided function
Expand All @@ -112,9 +124,11 @@ Value resolve_and_record_config(
std::vector<ConfigMetadata> metadata_entries;
Optional<Value> chosen_value;

auto add_entry = [&](ConfigMetadata::Origin origin, const Value& val) {
auto add_entry = [&](ConfigMetadata::Origin origin, const Value& val,
Optional<std::string> config_id = nullopt) {
std::string val_str = stringify(val);
metadata_entries.emplace_back(ConfigMetadata{config_name, val_str, origin});
metadata_entries.emplace_back(
ConfigMetadata{config_name, val_str, origin, nullopt, config_id});
chosen_value = val;
};

Expand All @@ -123,12 +137,12 @@ Value resolve_and_record_config(
add_entry(ConfigMetadata::Origin::DEFAULT, fallback);
}

if (from_user) {
add_entry(ConfigMetadata::Origin::CODE, *from_user);
}

if (from_env) {
add_entry(ConfigMetadata::Origin::ENVIRONMENT_VARIABLE, *from_env);
if (programmatic_wins) {
if (from_env) add_entry(from_env_origin, *from_env, from_env_config_id);
if (from_user) add_entry(ConfigMetadata::Origin::CODE, *from_user);
} else {
if (from_user) add_entry(ConfigMetadata::Origin::CODE, *from_user);
if (from_env) add_entry(from_env_origin, *from_env, from_env_config_id);
}

if (!metadata_entries.empty()) {
Expand Down
7 changes: 7 additions & 0 deletions include/datadog/datadog_agent_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace datadog::tracing {

class EventScheduler;
class Logger;
class StableConfig;

struct DatadogAgentConfig {
// The `HTTPClient` used to submit traces to the Datadog Agent. If this
Expand Down Expand Up @@ -65,6 +66,9 @@ struct DatadogAgentConfig {
class FinalizedDatadogAgentConfig {
friend Expected<FinalizedDatadogAgentConfig> finalize_config(
const DatadogAgentConfig&, const std::shared_ptr<Logger>&, const Clock&);
friend Expected<FinalizedDatadogAgentConfig> finalize_config(
const DatadogAgentConfig&, const std::shared_ptr<Logger>&, const Clock&,
const StableConfig*);

FinalizedDatadogAgentConfig() = default;

Expand Down Expand Up @@ -94,5 +98,8 @@ class FinalizedDatadogAgentConfig {
Expected<FinalizedDatadogAgentConfig> finalize_config(
const DatadogAgentConfig& config, const std::shared_ptr<Logger>& logger,
const Clock& clock);
Expected<FinalizedDatadogAgentConfig> finalize_config(
const DatadogAgentConfig& config, const std::shared_ptr<Logger>& logger,
const Clock& clock, const StableConfig* stable_config);

} // namespace datadog::tracing
Loading
Loading