Skip to content

Commit 9118a61

Browse files
dmehalaBridgeAR
andauthored
chore: add supported configurations (#284)
The configuration macro is changed to a registry that includes types and default values next to the configuration names. The macro must be used for any new configuration added and a CI job verifies that all entries exist and that no environment variable is accessed directly. The CI will also verify that the generated file is up to date and matches the remote registry. It would fail, if either is not the case. --------- Co-authored-by: Ruben Bridgewater <ruben.bridgewater@datadoghq.com>
1 parent 32898b5 commit 9118a61

12 files changed

Lines changed: 587 additions & 61 deletions

File tree

.github/workflows/dev.yml

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,34 @@ name: "Development"
22
on: [pull_request, workflow_dispatch, workflow_call]
33

44
jobs:
5-
format:
5+
verify:
66
runs-on: ubuntu-22.04-arm
77
container:
88
image: datadog/docker-library:dd-trace-cpp-ci-23768e9-arm64
9+
env:
10+
BUILD_DIR: .build
911
steps:
1012
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
1113
- name: Check format
1214
run: bin/check-format
1315
- name: Shellcheck
1416
run: find bin/ -executable -type f -print0 | xargs -0 shellcheck
17+
- name: Verify getenv usage
18+
run: bin/check-environment-variables
19+
- name: Configure
20+
run: bin/with-toolchain llvm cmake . -B ${BUILD_DIR} --preset ci-clang
21+
- name: Build
22+
run: cmake --build ${BUILD_DIR} -j --target config-inversion -v
23+
- name: Verify supported configurations metadata
24+
run: |
25+
tmp_dir="$(mktemp -d)"
26+
trap 'rm -rf "$tmp_dir"' EXIT
27+
./${BUILD_DIR}/tools/config-inversion/config-inversion --output-file "${tmp_dir}/ci-supported-configurations.json"
28+
if ! diff -q "$tmp_dir/ci-supported-configurations.json" "supported-configurations.json" >/dev/null 2>&1; then
29+
echo "ERROR: supported-configurations.json got out of sync with implemented configurations. Please run `./config-inversion --output-file supported-configurations.json` locally."
30+
diff -u "$tmp_dir/supported-configurations.json" supported-configurations.json || true
31+
exit 1
32+
fi
1533
1634
build-linux-cmake:
1735
strategy:
@@ -26,7 +44,7 @@ jobs:
2644
- runner: ubuntu-22.04
2745
arch: x64
2846
docker-arch: amd64
29-
needs: format
47+
needs: verify
3048
runs-on: ${{ matrix.runner }}
3149
container:
3250
image: datadog/docker-library:dd-trace-cpp-ci-23768e9-${{matrix.docker-arch}}
@@ -54,7 +72,7 @@ jobs:
5472
datadog-ci junit upload --service dd-trace-cpp --tags test.source.file:test/*.cpp .build/report.xml
5573
5674
build-linux-bazel:
57-
needs: format
75+
needs: verify
5876
strategy:
5977
fail-fast: false
6078
matrix:
@@ -77,7 +95,7 @@ jobs:
7795
run: bin/with-toolchain ${{ matrix.toolchain }} bazelisk --bazelrc=${{ matrix.bazelrc }} build dd_trace_cpp
7896

7997
build-windows-bazel:
80-
needs: format
98+
needs: verify
8199
runs-on: windows-2022
82100
defaults:
83101
run:
@@ -98,7 +116,7 @@ jobs:
98116
run: bazelisk.exe --bazelrc=${{ matrix.bazelrc }} build dd_trace_cpp
99117

100118
build-windows-cmake:
101-
needs: format
119+
needs: verify
102120
strategy:
103121
fail-fast: false
104122
matrix:

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ MODULE.bazel.lock
1111
.vscode
1212
.cache/
1313
.cursor/
14-
.DS_Store
14+
.DS_Store

.gitlab-ci.yml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
stages:
2+
- config-validation
23
- benchmarks
34
- benchmarks-report
45

5-
include: ".gitlab/benchmarks.yml"
6+
variables:
7+
SKIP_SHARED_PIPELINE: "true"
8+
9+
include:
10+
- local: ".gitlab/config-registry.yml"
11+
- local: ".gitlab/benchmarks.yml"
12+
13+
14+
# Config Registry CI Jobs
15+
validate_supported_configurations_v2_local_file:
16+
stage: config-validation
17+
image: registry.ddbuild.io/ci/libdatadog-build/packaging:82290795
18+
tags: ["runner:apm-k8s-tweaked-metal"]
19+
rules:
20+
- when: on_success
21+
extends: .validate_supported_configurations_v2_local_file
22+
variables:
23+
LOCAL_JSON_PATH: "supported-configurations.json"
24+
BACKFILLED: false
25+
26+
update_central_configurations_version_range_v2:
27+
stage: config-validation
28+
image: registry.ddbuild.io/ci/libdatadog-build/packaging:82290795
29+
tags: ["runner:apm-k8s-tweaked-metal"]
30+
extends: .update_central_configurations_version_range_v2
31+
variables:
32+
LOCAL_REPO_NAME: "dd-trace-cpp"
33+
LOCAL_JSON_PATH: "supported-configurations.json"
34+
LANGUAGE_NAME: "cpp"
35+
MULTIPLE_RELEASE_LINES: "false"

.gitlab/config-registry.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# This CI jobs are copied from libdatadog-build one-pipeline.yml gitlab template.
2+
# This URL is available in the dd-gitlab/publish-content-addresable-templates job whenever
3+
# a change is made on the one-pipeline template.
4+
variables:
5+
SCRIPTS_BASE_URL: https://gitlab-templates.ddbuild.io/libdatadog/one-pipeline/ca/f14ac28614630d12bcfe6cba4fd8d72dce142c62ff0b053ba7c323622104ebd7/scripts/config-inversion/
6+
7+
.download-scripts-from-template: &download-scripts-from-template
8+
- mkdir -p scripts
9+
- |
10+
for script_file in "config-inversion-local-validation.py" "config-inversion-update-supported-range.py"
11+
do
12+
curl --location --fail --show-error --output "scripts/${script_file}" "${SCRIPTS_BASE_URL}/${script_file}"
13+
chmod +x scripts/$script_file
14+
done
15+
16+
.validate_supported_configurations_v2_local_file:
17+
allow_failure: false
18+
rules:
19+
- when: on_success
20+
variables:
21+
LOCAL_JSON_PATH: ""
22+
BACKFILLED: ""
23+
before_script:
24+
- *download-scripts-from-template
25+
script:
26+
- scripts/config-inversion-local-validation.py
27+
28+
.update_central_configurations_version_range_v2:
29+
allow_failure: false
30+
rules:
31+
- if: '$CI_COMMIT_TAG =~ /^v?[0-9]+\.[0-9]+\.[0-9]+$/'
32+
when: always
33+
variables:
34+
LOCAL_JSON_PATH: ""
35+
LANGUAGE_NAME: ""
36+
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
37+
before_script:
38+
- *download-scripts-from-template
39+
- 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)
40+
script:
41+
- scripts/config-inversion-update-supported-range.py

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
4343
option(DD_TRACE_BUILD_EXAMPLES "Build example programs" OFF)
4444
option(DD_TRACE_BUILD_TESTING "Build the unit tests (test/)" OFF)
4545
option(DD_TRACE_BUILD_FUZZERS "Build fuzzers" OFF)
46+
option(DD_TRACE_BUILD_TOOLS "Build tools" OFF)
4647
option(DD_TRACE_BUILD_BENCHMARK "Build benchmark binaries" OFF)
4748
option(DD_TRACE_ENABLE_COVERAGE "Build code with code coverage profiling instrumentation" OFF)
4849
option(DD_TRACE_ENABLE_SANITIZE "Build with address sanitizer and undefined behavior sanitizer" OFF)
@@ -98,6 +99,11 @@ if (DD_TRACE_BUILD_BENCHMARK)
9899
add_subdirectory(benchmark)
99100
endif ()
100101

102+
if (DD_TRACE_BUILD_TOOLS)
103+
include(cmake/deps/cxxopts.cmake)
104+
add_subdirectory(tools/config-inversion)
105+
endif ()
106+
101107
add_library(dd-trace-cpp-objects OBJECT)
102108
add_library(dd-trace-cpp::obj ALIAS dd-trace-cpp-objects)
103109

CMakePresets.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"DD_TRACE_ENABLE_SANITIZE": "ON",
3131
"DD_TRACE_BUILD_TESTING": "ON",
3232
"DD_TRACE_BUILD_EXAMPLES": "ON",
33+
"DD_TRACE_BUILD_TOOLS": "ON",
3334
"DD_TRACE_BUILD_FUZZERS": "OFF"
3435
}
3536
},
@@ -39,6 +40,7 @@
3940
"cacheVariables": {
4041
"CMAKE_BUILD_TYPE": "Debug",
4142
"DD_TRACE_ENABLE_SANITIZE": "ON",
43+
"DD_TRACE_BUILD_TOOLS": "ON",
4244
"DD_TRACE_BUILD_TESTING": "ON"
4345
}
4446
}

bin/check-environment-variables

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
# TODO
3+
set -eu
4+
5+
if grep -R -n \
6+
--include='*.c' \
7+
--include='*.cc' \
8+
--include='*.cpp' \
9+
--include='*.cxx' \
10+
--include='*.h' \
11+
--include='*.hpp' \
12+
--exclude='environment.cpp' \
13+
'std::getenv' include src; then
14+
echo "Check failed: std::getenv usage detected."
15+
exit 1
16+
else
17+
echo "Check passed: no std::getenv usage found."
18+
exit 0
19+
fi

cmake/deps/cxxopts.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
include(FetchContent)
2+
3+
FetchContent_Declare(cxxopts
4+
URL https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.3.1.tar.gz
5+
URL_HASH SHA256=3bfc70542c521d4b55a46429d808178916a579b28d048bd8c727ee76c39e2072
6+
FIND_PACKAGE_ARGS NAMES cxxopts
7+
EXCLUDE_FROM_ALL
8+
SYSTEM
9+
)
10+
11+
FetchContent_MakeAvailable(cxxopts)

include/datadog/environment.h

Lines changed: 73 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,83 +6,102 @@
66
// Each `enum Variable` denotes an environment variable. The enum value names
77
// are the same as the names of the environment variables.
88
//
9-
// `variable_names` is an array of the names of the environment variables. Nginx
10-
// uses `variable_names` as an allow list of environment variables to forward to
11-
// worker processes.
12-
//
139
// `name` returns the name of a specified `Variable`.
1410
//
1511
// `lookup` retrieves the value of `Variable` in the environment.
16-
1712
#include <datadog/optional.h>
1813
#include <datadog/string_view.h>
1914

15+
#include <string>
16+
2017
namespace datadog {
2118
namespace tracing {
2219
namespace environment {
2320

24-
// To enforce correspondence between `enum Variable` and `variable_names`, the
25-
// preprocessor is used so that the DD_* symbols are listed exactly once.
26-
#define LIST_ENVIRONMENT_VARIABLES(MACRO) \
27-
MACRO(DD_AGENT_HOST) \
28-
MACRO(DD_ENV) \
29-
MACRO(DD_INSTRUMENTATION_TELEMETRY_ENABLED) \
30-
MACRO(DD_PROPAGATION_STYLE_EXTRACT) \
31-
MACRO(DD_PROPAGATION_STYLE_INJECT) \
32-
MACRO(DD_REMOTE_CONFIGURATION_ENABLED) \
33-
MACRO(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS) \
34-
MACRO(DD_SERVICE) \
35-
MACRO(DD_SPAN_SAMPLING_RULES) \
36-
MACRO(DD_SPAN_SAMPLING_RULES_FILE) \
37-
MACRO(DD_TRACE_PROPAGATION_STYLE_EXTRACT) \
38-
MACRO(DD_TRACE_PROPAGATION_STYLE_INJECT) \
39-
MACRO(DD_TRACE_PROPAGATION_STYLE) \
40-
MACRO(DD_TAGS) \
41-
MACRO(DD_TRACE_AGENT_PORT) \
42-
MACRO(DD_TRACE_AGENT_URL) \
43-
MACRO(DD_TRACE_DEBUG) \
44-
MACRO(DD_TRACE_ENABLED) \
45-
MACRO(DD_TRACE_RATE_LIMIT) \
46-
MACRO(DD_TRACE_REPORT_HOSTNAME) \
47-
MACRO(DD_TRACE_SAMPLE_RATE) \
48-
MACRO(DD_TRACE_SAMPLING_RULES) \
49-
MACRO(DD_TRACE_STARTUP_LOGS) \
50-
MACRO(DD_TRACE_TAGS_PROPAGATION_MAX_LENGTH) \
51-
MACRO(DD_VERSION) \
52-
MACRO(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED) \
53-
MACRO(DD_TELEMETRY_HEARTBEAT_INTERVAL) \
54-
MACRO(DD_TELEMETRY_METRICS_ENABLED) \
55-
MACRO(DD_TELEMETRY_METRICS_INTERVAL_SECONDS) \
56-
MACRO(DD_TELEMETRY_DEBUG) \
57-
MACRO(DD_TRACE_BAGGAGE_MAX_ITEMS) \
58-
MACRO(DD_TRACE_BAGGAGE_MAX_BYTES) \
59-
MACRO(DD_TELEMETRY_LOG_COLLECTION_ENABLED) \
60-
MACRO(DD_INSTRUMENTATION_INSTALL_ID) \
61-
MACRO(DD_INSTRUMENTATION_INSTALL_TYPE) \
62-
MACRO(DD_INSTRUMENTATION_INSTALL_TIME) \
63-
MACRO(DD_APM_TRACING_ENABLED) \
64-
MACRO(DD_TRACE_RESOURCE_RENAMING_ENABLED) \
65-
MACRO(DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT) \
66-
MACRO(DD_EXTERNAL_ENV)
21+
// Central registry for supported environment variables.
22+
// All configurations must be registered here.
23+
//
24+
// This registry is the single source of truth for:
25+
// - env variable name allowlist (`include/datadog/environment.h`)
26+
// - generated metadata (`metadata/supported-configurations.json`)
27+
//
28+
// Each entry has:
29+
// - NAME: environment variable symbol (e.g. DD_SERVICE)
30+
// - TYPE: STRING | BOOLEAN | INT | DECIMAL | ARRAY | MAP
31+
// - DEFAULT: literal default value or a marker token
32+
//
33+
// Marker tokens:
34+
// - ENV_DEFAULT_RESOLVED_IN_CODE("...description...")
35+
// The runtime default is resolved in C++ configuration finalization
36+
// logic. The description is emitted as the "default" field in
37+
// metadata/supported-configurations.json.
38+
#define DD_LIST_ENVIRONMENT_VARIABLES(MACRO) \
39+
MACRO(DD_AGENT_HOST, STRING, "localhost") \
40+
MACRO(DD_ENV, STRING, "") \
41+
MACRO(DD_INSTRUMENTATION_TELEMETRY_ENABLED, BOOLEAN, true) \
42+
MACRO(DD_PROPAGATION_STYLE_EXTRACT, ARRAY, "datadog,tracecontext,baggage") \
43+
MACRO(DD_PROPAGATION_STYLE_INJECT, ARRAY, "datadog,tracecontext,baggage") \
44+
MACRO(DD_REMOTE_CONFIGURATION_ENABLED, BOOLEAN, true) \
45+
MACRO(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS, DECIMAL, 5.0) \
46+
MACRO(DD_SERVICE, STRING, \
47+
ENV_DEFAULT_RESOLVED_IN_CODE("Defaults to process name when unset.")) \
48+
MACRO(DD_SPAN_SAMPLING_RULES, ARRAY, "[]") \
49+
MACRO(DD_SPAN_SAMPLING_RULES_FILE, STRING, "") \
50+
MACRO(DD_TRACE_PROPAGATION_STYLE_EXTRACT, ARRAY, \
51+
"datadog,tracecontext,baggage") \
52+
MACRO(DD_TRACE_PROPAGATION_STYLE_INJECT, ARRAY, \
53+
"datadog,tracecontext,baggage") \
54+
MACRO(DD_TRACE_PROPAGATION_STYLE, ARRAY, "datadog,tracecontext,baggage") \
55+
MACRO(DD_TAGS, MAP, "") \
56+
MACRO(DD_TRACE_AGENT_PORT, INT, 8126) \
57+
MACRO(DD_TRACE_AGENT_URL, STRING, \
58+
ENV_DEFAULT_RESOLVED_IN_CODE( \
59+
"If unset, built from DD_AGENT_HOST and DD_TRACE_AGENT_PORT, " \
60+
"then defaults to http://localhost:8126.")) \
61+
MACRO(DD_TRACE_DEBUG, BOOLEAN, false) \
62+
MACRO(DD_TRACE_ENABLED, BOOLEAN, true) \
63+
MACRO(DD_TRACE_RATE_LIMIT, DECIMAL, 100.0) \
64+
MACRO(DD_TRACE_REPORT_HOSTNAME, BOOLEAN, false) \
65+
MACRO(DD_TRACE_SAMPLE_RATE, DECIMAL, 1.0) \
66+
MACRO(DD_TRACE_SAMPLING_RULES, ARRAY, "[]") \
67+
MACRO(DD_TRACE_STARTUP_LOGS, BOOLEAN, true) \
68+
MACRO(DD_TRACE_TAGS_PROPAGATION_MAX_LENGTH, INT, 512) \
69+
MACRO(DD_VERSION, STRING, "") \
70+
MACRO(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED, BOOLEAN, true) \
71+
MACRO(DD_TELEMETRY_HEARTBEAT_INTERVAL, DECIMAL, 10) \
72+
MACRO(DD_TELEMETRY_METRICS_ENABLED, BOOLEAN, true) \
73+
MACRO(DD_TELEMETRY_METRICS_INTERVAL_SECONDS, DECIMAL, 60) \
74+
MACRO(DD_TELEMETRY_DEBUG, BOOLEAN, false) \
75+
MACRO(DD_TRACE_BAGGAGE_MAX_ITEMS, INT, 64) \
76+
MACRO(DD_TRACE_BAGGAGE_MAX_BYTES, INT, 8192) \
77+
MACRO(DD_TELEMETRY_LOG_COLLECTION_ENABLED, BOOLEAN, true) \
78+
MACRO(DD_INSTRUMENTATION_INSTALL_ID, STRING, "") \
79+
MACRO(DD_INSTRUMENTATION_INSTALL_TYPE, STRING, "") \
80+
MACRO(DD_INSTRUMENTATION_INSTALL_TIME, STRING, "") \
81+
MACRO(DD_APM_TRACING_ENABLED, BOOLEAN, true) \
82+
MACRO(DD_TRACE_RESOURCE_RENAMING_ENABLED, BOOLEAN, false) \
83+
MACRO(DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT, BOOLEAN, false) \
84+
MACRO(DD_EXTERNAL_ENV, STRING, "")
6785

68-
#define WITH_COMMA(ARG) ARG,
86+
#define ENV_DEFAULT_RESOLVED_IN_CODE(X) X
87+
#define WITH_COMMA(ARG, TYPE, DEFAULT_VALUE) ARG,
6988

70-
enum Variable { LIST_ENVIRONMENT_VARIABLES(WITH_COMMA) };
89+
enum Variable { DD_LIST_ENVIRONMENT_VARIABLES(WITH_COMMA) };
7190

7291
// Quoting a macro argument requires this two-step.
7392
#define QUOTED_IMPL(ARG) #ARG
7493
#define QUOTED(ARG) QUOTED_IMPL(ARG)
7594

76-
#define QUOTED_WITH_COMMA(ARG) WITH_COMMA(QUOTED(ARG))
95+
#define QUOTED_WITH_COMMA(ARG, TYPE, DEFAULT_VALUE) \
96+
WITH_COMMA(QUOTED(ARG), TYPE, DEFAULT_VALUE)
7797

7898
inline const char *const variable_names[] = {
79-
LIST_ENVIRONMENT_VARIABLES(QUOTED_WITH_COMMA)};
99+
DD_LIST_ENVIRONMENT_VARIABLES(QUOTED_WITH_COMMA)};
80100

81-
#undef QUOTED_WITH_COMMA
82101
#undef QUOTED
83102
#undef QUOTED_IMPL
84103
#undef WITH_COMMA
85-
#undef LIST_ENVIRONMENT_VARIABLES
104+
#undef ENV_DEFAULT_RESOLVED_IN_CODE
86105

87106
// Return the name of the specified environment `variable`.
88107
StringView name(Variable variable);

0 commit comments

Comments
 (0)