diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 9c65e53f..3857068d 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -2,16 +2,34 @@ name: "Development" on: [pull_request, workflow_dispatch, workflow_call] jobs: - format: + verify: runs-on: ubuntu-22.04-arm container: image: datadog/docker-library:dd-trace-cpp-ci-23768e9-arm64 + env: + BUILD_DIR: .build steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Check format run: bin/check-format - name: Shellcheck run: find bin/ -executable -type f -print0 | xargs -0 shellcheck + - name: Verify getenv usage + run: bin/check-environment-variables + - name: Configure + run: bin/with-toolchain llvm cmake . -B ${BUILD_DIR} --preset ci-clang + - name: Build + run: cmake --build ${BUILD_DIR} -j --target config-inversion -v + - name: Verify supported configurations metadata + run: | + tmp_dir="$(mktemp -d)" + trap 'rm -rf "$tmp_dir"' EXIT + ./${BUILD_DIR}/tools/config-inversion/config-inversion --output-file "${tmp_dir}/ci-supported-configurations.json" + if ! diff -q "$tmp_dir/ci-supported-configurations.json" "supported-configurations.json" >/dev/null 2>&1; then + echo "ERROR: supported-configurations.json got out of sync with implemented configurations. Please run `./config-inversion --output-file supported-configurations.json` locally." + diff -u "$tmp_dir/supported-configurations.json" supported-configurations.json || true + exit 1 + fi build-linux-cmake: strategy: @@ -26,7 +44,7 @@ jobs: - runner: ubuntu-22.04 arch: x64 docker-arch: amd64 - needs: format + needs: verify runs-on: ${{ matrix.runner }} container: image: datadog/docker-library:dd-trace-cpp-ci-23768e9-${{matrix.docker-arch}} @@ -54,7 +72,7 @@ jobs: datadog-ci junit upload --service dd-trace-cpp --tags test.source.file:test/*.cpp .build/report.xml build-linux-bazel: - needs: format + needs: verify strategy: fail-fast: false matrix: @@ -77,7 +95,7 @@ jobs: run: bin/with-toolchain ${{ matrix.toolchain }} bazelisk --bazelrc=${{ matrix.bazelrc }} build dd_trace_cpp build-windows-bazel: - needs: format + needs: verify runs-on: windows-2022 defaults: run: @@ -98,7 +116,7 @@ jobs: run: bazelisk.exe --bazelrc=${{ matrix.bazelrc }} build dd_trace_cpp build-windows-cmake: - needs: format + needs: verify strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index 60c94744..a36fe8c6 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ MODULE.bazel.lock .vscode .cache/ .cursor/ -.DS_Store \ No newline at end of file +.DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7f9babbc..a77a96af 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,35 @@ stages: + - config-validation - benchmarks - benchmarks-report -include: ".gitlab/benchmarks.yml" +variables: + SKIP_SHARED_PIPELINE: "true" + +include: + - local: ".gitlab/config-registry.yml" + - local: ".gitlab/benchmarks.yml" + + +# Config Registry CI Jobs +validate_supported_configurations_v2_local_file: + stage: config-validation + image: registry.ddbuild.io/ci/libdatadog-build/packaging:82290795 + tags: ["runner:apm-k8s-tweaked-metal"] + rules: + - when: on_success + extends: .validate_supported_configurations_v2_local_file + variables: + LOCAL_JSON_PATH: "supported-configurations.json" + BACKFILLED: false + +update_central_configurations_version_range_v2: + stage: config-validation + image: registry.ddbuild.io/ci/libdatadog-build/packaging:82290795 + tags: ["runner:apm-k8s-tweaked-metal"] + extends: .update_central_configurations_version_range_v2 + variables: + LOCAL_REPO_NAME: "dd-trace-cpp" + LOCAL_JSON_PATH: "supported-configurations.json" + LANGUAGE_NAME: "cpp" + MULTIPLE_RELEASE_LINES: "false" diff --git a/.gitlab/config-registry.yml b/.gitlab/config-registry.yml new file mode 100644 index 00000000..1d3bf2f3 --- /dev/null +++ b/.gitlab/config-registry.yml @@ -0,0 +1,41 @@ +# This CI jobs are copied from libdatadog-build one-pipeline.yml gitlab template. +# This URL is available in the dd-gitlab/publish-content-addresable-templates job whenever +# a change is made on the one-pipeline template. +variables: + SCRIPTS_BASE_URL: https://gitlab-templates.ddbuild.io/libdatadog/one-pipeline/ca/f14ac28614630d12bcfe6cba4fd8d72dce142c62ff0b053ba7c323622104ebd7/scripts/config-inversion/ + +.download-scripts-from-template: &download-scripts-from-template + - mkdir -p scripts + - | + for script_file in "config-inversion-local-validation.py" "config-inversion-update-supported-range.py" + do + curl --location --fail --show-error --output "scripts/${script_file}" "${SCRIPTS_BASE_URL}/${script_file}" + chmod +x scripts/$script_file + done + +.validate_supported_configurations_v2_local_file: + allow_failure: false + rules: + - when: on_success + variables: + LOCAL_JSON_PATH: "" + BACKFILLED: "" + before_script: + - *download-scripts-from-template + script: + - scripts/config-inversion-local-validation.py + +.update_central_configurations_version_range_v2: + allow_failure: false + rules: + - if: '$CI_COMMIT_TAG =~ /^v?[0-9]+\.[0-9]+\.[0-9]+$/' + when: always + variables: + LOCAL_JSON_PATH: "" + LANGUAGE_NAME: "" + MULTIPLE_RELEASE_LINES: "false" # expect "true" or "false" as a value to determine if a new "branch" identifier is needed to differentiate between multiple release lines + before_script: + - *download-scripts-from-template + - export FP_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.$CI_PROJECT_NAME.FP_API_KEY --with-decryption --query "Parameter.Value" --out text) + script: + - scripts/config-inversion-update-supported-range.py \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c432a352..c8f49148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) option(DD_TRACE_BUILD_EXAMPLES "Build example programs" OFF) option(DD_TRACE_BUILD_TESTING "Build the unit tests (test/)" OFF) option(DD_TRACE_BUILD_FUZZERS "Build fuzzers" OFF) + option(DD_TRACE_BUILD_TOOLS "Build tools" OFF) option(DD_TRACE_BUILD_BENCHMARK "Build benchmark binaries" OFF) option(DD_TRACE_ENABLE_COVERAGE "Build code with code coverage profiling instrumentation" OFF) option(DD_TRACE_ENABLE_SANITIZE "Build with address sanitizer and undefined behavior sanitizer" OFF) @@ -98,6 +99,11 @@ if (DD_TRACE_BUILD_BENCHMARK) add_subdirectory(benchmark) endif () +if (DD_TRACE_BUILD_TOOLS) + include(cmake/deps/cxxopts.cmake) + add_subdirectory(tools/config-inversion) +endif () + add_library(dd-trace-cpp-objects OBJECT) add_library(dd-trace-cpp::obj ALIAS dd-trace-cpp-objects) diff --git a/CMakePresets.json b/CMakePresets.json index 57abbeed..abf0d98a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -30,6 +30,7 @@ "DD_TRACE_ENABLE_SANITIZE": "ON", "DD_TRACE_BUILD_TESTING": "ON", "DD_TRACE_BUILD_EXAMPLES": "ON", + "DD_TRACE_BUILD_TOOLS": "ON", "DD_TRACE_BUILD_FUZZERS": "OFF" } }, @@ -39,6 +40,7 @@ "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "DD_TRACE_ENABLE_SANITIZE": "ON", + "DD_TRACE_BUILD_TOOLS": "ON", "DD_TRACE_BUILD_TESTING": "ON" } } diff --git a/bin/check-environment-variables b/bin/check-environment-variables new file mode 100755 index 00000000..07a7f27c --- /dev/null +++ b/bin/check-environment-variables @@ -0,0 +1,19 @@ +#!/bin/sh +# TODO +set -eu + +if grep -R -n \ + --include='*.c' \ + --include='*.cc' \ + --include='*.cpp' \ + --include='*.cxx' \ + --include='*.h' \ + --include='*.hpp' \ + --exclude='environment.cpp' \ + 'std::getenv' include src; then + echo "Check failed: std::getenv usage detected." + exit 1 +else + echo "Check passed: no std::getenv usage found." + exit 0 +fi diff --git a/cmake/deps/cxxopts.cmake b/cmake/deps/cxxopts.cmake new file mode 100644 index 00000000..7ac78121 --- /dev/null +++ b/cmake/deps/cxxopts.cmake @@ -0,0 +1,11 @@ +include(FetchContent) + +FetchContent_Declare(cxxopts + URL https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.3.1.tar.gz + URL_HASH SHA256=3bfc70542c521d4b55a46429d808178916a579b28d048bd8c727ee76c39e2072 + FIND_PACKAGE_ARGS NAMES cxxopts + EXCLUDE_FROM_ALL + SYSTEM +) + +FetchContent_MakeAvailable(cxxopts) diff --git a/include/datadog/environment.h b/include/datadog/environment.h index 358d0bcb..f2846b37 100644 --- a/include/datadog/environment.h +++ b/include/datadog/environment.h @@ -6,83 +6,102 @@ // Each `enum Variable` denotes an environment variable. The enum value names // are the same as the names of the environment variables. // -// `variable_names` is an array of the names of the environment variables. Nginx -// uses `variable_names` as an allow list of environment variables to forward to -// worker processes. -// // `name` returns the name of a specified `Variable`. // // `lookup` retrieves the value of `Variable` in the environment. - #include #include +#include + namespace datadog { namespace tracing { namespace environment { -// To enforce correspondence between `enum Variable` and `variable_names`, the -// preprocessor is used so that the DD_* symbols are listed exactly once. -#define LIST_ENVIRONMENT_VARIABLES(MACRO) \ - MACRO(DD_AGENT_HOST) \ - MACRO(DD_ENV) \ - MACRO(DD_INSTRUMENTATION_TELEMETRY_ENABLED) \ - MACRO(DD_PROPAGATION_STYLE_EXTRACT) \ - MACRO(DD_PROPAGATION_STYLE_INJECT) \ - MACRO(DD_REMOTE_CONFIGURATION_ENABLED) \ - MACRO(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS) \ - MACRO(DD_SERVICE) \ - MACRO(DD_SPAN_SAMPLING_RULES) \ - MACRO(DD_SPAN_SAMPLING_RULES_FILE) \ - MACRO(DD_TRACE_PROPAGATION_STYLE_EXTRACT) \ - MACRO(DD_TRACE_PROPAGATION_STYLE_INJECT) \ - MACRO(DD_TRACE_PROPAGATION_STYLE) \ - MACRO(DD_TAGS) \ - MACRO(DD_TRACE_AGENT_PORT) \ - MACRO(DD_TRACE_AGENT_URL) \ - MACRO(DD_TRACE_DEBUG) \ - MACRO(DD_TRACE_ENABLED) \ - MACRO(DD_TRACE_RATE_LIMIT) \ - MACRO(DD_TRACE_REPORT_HOSTNAME) \ - MACRO(DD_TRACE_SAMPLE_RATE) \ - MACRO(DD_TRACE_SAMPLING_RULES) \ - MACRO(DD_TRACE_STARTUP_LOGS) \ - MACRO(DD_TRACE_TAGS_PROPAGATION_MAX_LENGTH) \ - MACRO(DD_VERSION) \ - MACRO(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED) \ - MACRO(DD_TELEMETRY_HEARTBEAT_INTERVAL) \ - MACRO(DD_TELEMETRY_METRICS_ENABLED) \ - MACRO(DD_TELEMETRY_METRICS_INTERVAL_SECONDS) \ - MACRO(DD_TELEMETRY_DEBUG) \ - MACRO(DD_TRACE_BAGGAGE_MAX_ITEMS) \ - MACRO(DD_TRACE_BAGGAGE_MAX_BYTES) \ - MACRO(DD_TELEMETRY_LOG_COLLECTION_ENABLED) \ - MACRO(DD_INSTRUMENTATION_INSTALL_ID) \ - MACRO(DD_INSTRUMENTATION_INSTALL_TYPE) \ - MACRO(DD_INSTRUMENTATION_INSTALL_TIME) \ - MACRO(DD_APM_TRACING_ENABLED) \ - MACRO(DD_TRACE_RESOURCE_RENAMING_ENABLED) \ - MACRO(DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT) \ - MACRO(DD_EXTERNAL_ENV) +// Central registry for supported environment variables. +// All configurations must be registered here. +// +// This registry is the single source of truth for: +// - env variable name allowlist (`include/datadog/environment.h`) +// - generated metadata (`metadata/supported-configurations.json`) +// +// Each entry has: +// - NAME: environment variable symbol (e.g. DD_SERVICE) +// - TYPE: STRING | BOOLEAN | INT | DECIMAL | ARRAY | MAP +// - DEFAULT: literal default value or a marker token +// +// Marker tokens: +// - ENV_DEFAULT_RESOLVED_IN_CODE("...description...") +// The runtime default is resolved in C++ configuration finalization +// logic. The description is emitted as the "default" field in +// metadata/supported-configurations.json. +#define DD_LIST_ENVIRONMENT_VARIABLES(MACRO) \ + MACRO(DD_AGENT_HOST, STRING, "localhost") \ + MACRO(DD_ENV, STRING, "") \ + MACRO(DD_INSTRUMENTATION_TELEMETRY_ENABLED, BOOLEAN, true) \ + MACRO(DD_PROPAGATION_STYLE_EXTRACT, ARRAY, "datadog,tracecontext,baggage") \ + MACRO(DD_PROPAGATION_STYLE_INJECT, ARRAY, "datadog,tracecontext,baggage") \ + MACRO(DD_REMOTE_CONFIGURATION_ENABLED, BOOLEAN, true) \ + MACRO(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS, DECIMAL, 5.0) \ + MACRO(DD_SERVICE, STRING, \ + ENV_DEFAULT_RESOLVED_IN_CODE("Defaults to process name when unset.")) \ + MACRO(DD_SPAN_SAMPLING_RULES, ARRAY, "[]") \ + MACRO(DD_SPAN_SAMPLING_RULES_FILE, STRING, "") \ + MACRO(DD_TRACE_PROPAGATION_STYLE_EXTRACT, ARRAY, \ + "datadog,tracecontext,baggage") \ + MACRO(DD_TRACE_PROPAGATION_STYLE_INJECT, ARRAY, \ + "datadog,tracecontext,baggage") \ + MACRO(DD_TRACE_PROPAGATION_STYLE, ARRAY, "datadog,tracecontext,baggage") \ + MACRO(DD_TAGS, MAP, "") \ + MACRO(DD_TRACE_AGENT_PORT, INT, 8126) \ + MACRO(DD_TRACE_AGENT_URL, STRING, \ + ENV_DEFAULT_RESOLVED_IN_CODE( \ + "If unset, built from DD_AGENT_HOST and DD_TRACE_AGENT_PORT, " \ + "then defaults to http://localhost:8126.")) \ + MACRO(DD_TRACE_DEBUG, BOOLEAN, false) \ + MACRO(DD_TRACE_ENABLED, BOOLEAN, true) \ + MACRO(DD_TRACE_RATE_LIMIT, DECIMAL, 100.0) \ + MACRO(DD_TRACE_REPORT_HOSTNAME, BOOLEAN, false) \ + MACRO(DD_TRACE_SAMPLE_RATE, DECIMAL, 1.0) \ + MACRO(DD_TRACE_SAMPLING_RULES, ARRAY, "[]") \ + MACRO(DD_TRACE_STARTUP_LOGS, BOOLEAN, true) \ + MACRO(DD_TRACE_TAGS_PROPAGATION_MAX_LENGTH, INT, 512) \ + MACRO(DD_VERSION, STRING, "") \ + MACRO(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED, BOOLEAN, true) \ + MACRO(DD_TELEMETRY_HEARTBEAT_INTERVAL, DECIMAL, 10) \ + MACRO(DD_TELEMETRY_METRICS_ENABLED, BOOLEAN, true) \ + MACRO(DD_TELEMETRY_METRICS_INTERVAL_SECONDS, DECIMAL, 60) \ + MACRO(DD_TELEMETRY_DEBUG, BOOLEAN, false) \ + MACRO(DD_TRACE_BAGGAGE_MAX_ITEMS, INT, 64) \ + MACRO(DD_TRACE_BAGGAGE_MAX_BYTES, INT, 8192) \ + MACRO(DD_TELEMETRY_LOG_COLLECTION_ENABLED, BOOLEAN, true) \ + MACRO(DD_INSTRUMENTATION_INSTALL_ID, STRING, "") \ + MACRO(DD_INSTRUMENTATION_INSTALL_TYPE, STRING, "") \ + MACRO(DD_INSTRUMENTATION_INSTALL_TIME, STRING, "") \ + MACRO(DD_APM_TRACING_ENABLED, BOOLEAN, true) \ + MACRO(DD_TRACE_RESOURCE_RENAMING_ENABLED, BOOLEAN, false) \ + MACRO(DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT, BOOLEAN, false) \ + MACRO(DD_EXTERNAL_ENV, STRING, "") -#define WITH_COMMA(ARG) ARG, +#define ENV_DEFAULT_RESOLVED_IN_CODE(X) X +#define WITH_COMMA(ARG, TYPE, DEFAULT_VALUE) ARG, -enum Variable { LIST_ENVIRONMENT_VARIABLES(WITH_COMMA) }; +enum Variable { DD_LIST_ENVIRONMENT_VARIABLES(WITH_COMMA) }; // Quoting a macro argument requires this two-step. #define QUOTED_IMPL(ARG) #ARG #define QUOTED(ARG) QUOTED_IMPL(ARG) -#define QUOTED_WITH_COMMA(ARG) WITH_COMMA(QUOTED(ARG)) +#define QUOTED_WITH_COMMA(ARG, TYPE, DEFAULT_VALUE) \ + WITH_COMMA(QUOTED(ARG), TYPE, DEFAULT_VALUE) inline const char *const variable_names[] = { - LIST_ENVIRONMENT_VARIABLES(QUOTED_WITH_COMMA)}; + DD_LIST_ENVIRONMENT_VARIABLES(QUOTED_WITH_COMMA)}; -#undef QUOTED_WITH_COMMA #undef QUOTED #undef QUOTED_IMPL #undef WITH_COMMA -#undef LIST_ENVIRONMENT_VARIABLES +#undef ENV_DEFAULT_RESOLVED_IN_CODE // Return the name of the specified environment `variable`. StringView name(Variable variable); diff --git a/supported-configurations.json b/supported-configurations.json new file mode 100644 index 00000000..4ee3558a --- /dev/null +++ b/supported-configurations.json @@ -0,0 +1,285 @@ +{ + "supportedConfigurations": { + "DD_AGENT_HOST": [ + { + "default": "localhost", + "implementation": "A", + "type": "STRING" + } + ], + "DD_APM_TRACING_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_ENV": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_EXTERNAL_ENV": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_INSTRUMENTATION_INSTALL_ID": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_INSTRUMENTATION_INSTALL_TIME": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_INSTRUMENTATION_INSTALL_TYPE": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_INSTRUMENTATION_TELEMETRY_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_PROPAGATION_STYLE_EXTRACT": [ + { + "default": "datadog,tracecontext,baggage", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_PROPAGATION_STYLE_INJECT": [ + { + "default": "datadog,tracecontext,baggage", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_REMOTE_CONFIGURATION_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS": [ + { + "default": "5", + "implementation": "A", + "type": "DECIMAL" + } + ], + "DD_SERVICE": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_SPAN_SAMPLING_RULES": [ + { + "default": "[]", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_SPAN_SAMPLING_RULES_FILE": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_TAGS": [ + { + "default": "", + "implementation": "A", + "type": "MAP" + } + ], + "DD_TELEMETRY_DEBUG": [ + { + "default": "0", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TELEMETRY_HEARTBEAT_INTERVAL": [ + { + "default": "10", + "implementation": "A", + "type": "DECIMAL" + } + ], + "DD_TELEMETRY_LOG_COLLECTION_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TELEMETRY_METRICS_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TELEMETRY_METRICS_INTERVAL_SECONDS": [ + { + "default": "60", + "implementation": "A", + "type": "DECIMAL" + } + ], + "DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_AGENT_PORT": [ + { + "default": "8126", + "implementation": "A", + "type": "INT" + } + ], + "DD_TRACE_AGENT_URL": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ], + "DD_TRACE_BAGGAGE_MAX_BYTES": [ + { + "default": "8192", + "implementation": "A", + "type": "INT" + } + ], + "DD_TRACE_BAGGAGE_MAX_ITEMS": [ + { + "default": "64", + "implementation": "A", + "type": "INT" + } + ], + "DD_TRACE_DEBUG": [ + { + "default": "0", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_ENABLED": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_PROPAGATION_STYLE": [ + { + "default": "datadog,tracecontext,baggage", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_TRACE_PROPAGATION_STYLE_EXTRACT": [ + { + "default": "datadog,tracecontext,baggage", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_TRACE_PROPAGATION_STYLE_INJECT": [ + { + "default": "datadog,tracecontext,baggage", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_TRACE_RATE_LIMIT": [ + { + "default": "100", + "implementation": "A", + "type": "DECIMAL" + } + ], + "DD_TRACE_REPORT_HOSTNAME": [ + { + "default": "0", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT": [ + { + "default": "0", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_RESOURCE_RENAMING_ENABLED": [ + { + "default": "0", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_SAMPLE_RATE": [ + { + "default": "1", + "implementation": "A", + "type": "DECIMAL" + } + ], + "DD_TRACE_SAMPLING_RULES": [ + { + "default": "[]", + "implementation": "A", + "type": "ARRAY" + } + ], + "DD_TRACE_STARTUP_LOGS": [ + { + "default": "1", + "implementation": "A", + "type": "BOOLEAN" + } + ], + "DD_TRACE_TAGS_PROPAGATION_MAX_LENGTH": [ + { + "default": "512", + "implementation": "A", + "type": "INT" + } + ], + "DD_VERSION": [ + { + "default": "", + "implementation": "A", + "type": "STRING" + } + ] + }, + "version": "2" +} \ No newline at end of file diff --git a/tools/config-inversion/CMakeLists.txt b/tools/config-inversion/CMakeLists.txt new file mode 100644 index 00000000..394df7af --- /dev/null +++ b/tools/config-inversion/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(config-inversion main.cpp) + +target_compile_features(config-inversion + PUBLIC + cxx_std_17 +) + +target_include_directories(config-inversion + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/include +) + +target_link_libraries(config-inversion + PRIVATE + nlohmann_json::nlohmann_json + cxxopts::cxxopts + dd-trace-cpp::specs +) diff --git a/tools/config-inversion/main.cpp b/tools/config-inversion/main.cpp new file mode 100644 index 00000000..1bef85dd --- /dev/null +++ b/tools/config-inversion/main.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include + +#include "datadog/environment.h" + +namespace fs = std::filesystem; +namespace env = datadog::tracing::environment; + +template +std::string to_string_any(const T& value) { + std::ostringstream oss; + oss << value; + return oss.str(); +} + +nlohmann::json build_configuration() { + nlohmann::json j; + j["version"] = "2"; + + auto supported_configurations = nlohmann::json::object(); + +#define QUOTED_IMPL(ARG) #ARG +#define QUOTED(ARG) QUOTED_IMPL(ARG) + +#define ENV_DEFAULT_RESOLVED_IN_CODE(X) "" + +#define X(NAME, TYPE, DEFAULT_VALUE) \ + do { \ + auto obj = nlohmann::json::object(); \ + obj["default"] = to_string_any(DEFAULT_VALUE); \ + obj["implementation"] = "A"; \ + obj["type"] = QUOTED(TYPE); \ + supported_configurations[QUOTED(NAME)] = nlohmann::json::array({obj}); \ + } while (0); + + DD_LIST_ENVIRONMENT_VARIABLES(X) +#undef X +#undef ENV_DEFAULT_RESOLVED_IN_CODE + + j["supportedConfigurations"] = supported_configurations; + + return j; +} + +int main(int argc, char** argv) { + cxxopts::Options options("generate-configuration", + "A tool to generate a JSON file with Datadog " + "configuration supported by the C++ tracer."); + + options.add_options()("o,output-file", + "Location where the JSON file will be written", + cxxopts::value())("h,help", "Print usage"); + + auto result = options.parse(argc, argv); + + if (result.count("output-file") == 0 || result.count("help")) { + std::cout << options.help() << std::endl; + return 0; + } + + const fs::path output_file = result["output-file"].as(); + + const auto j = build_configuration(); + std::ofstream file(output_file, std::ios::binary); + if (!file) { + std::cerr << "Unable to write configuration file"; + return 1; + } + + file << j.dump(2); + return 0; +}