Skip to content

Commit 9a3bec1

Browse files
authored
Merge branch 'master' into nayeem-kamal/boomi-fix
2 parents 90197e6 + 562e533 commit 9a3bec1

File tree

231 files changed

+855
-522
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+855
-522
lines changed

.gitlab-ci.yml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ variables:
2828
GRADLE_VERSION: "8.14.3" # must match gradle-wrapper.properties
2929
MAVEN_REPOSITORY_PROXY: "http://artifactual.artifactual.all-clusters.local-dc.fabric.dog:8081/repository/maven-central/"
3030
GRADLE_PLUGIN_PROXY: "http://artifactual.artifactual.all-clusters.local-dc.fabric.dog:8081/repository/gradle-plugin-portal-proxy/"
31-
BUILDER_IMAGE_VERSION_PREFIX: "v25.06-" # use either an empty string (e.g. "") for latest images or a version followed by a hyphen (e.g. "v25.05-")
31+
BUILDER_IMAGE_VERSION_PREFIX: "v25.07-" # use either an empty string (e.g. "") for latest images or a version followed by a hyphen (e.g. "v25.05-")
3232
REPO_NOTIFICATION_CHANNEL: "#apm-java-escalations"
3333
DEFAULT_TEST_JVMS: /^(8|11|17|21|stable)$/
3434
PROFILE_TESTS:
@@ -137,9 +137,12 @@ default:
137137
KUBERNETES_MEMORY_REQUEST: 8Gi
138138
KUBERNETES_MEMORY_LIMIT: 8Gi
139139
CACHE_TYPE: lib #default
140+
FF_USE_FASTZIP: "true"
141+
CACHE_COMPRESSION_LEVEL: "slowest"
142+
140143
RUNTIME_AVAILABLE_PROCESSORS_OVERRIDE: 4 # Runtime.getRuntime().availableProcessors() returns incorrect or very high values in Kubernetes
141144
cache:
142-
- key: '$CI_SERVER_VERSION-$CACHE_TYPE' # Dependencies cache. Reset the cache every time gitlab is upgraded. ~Every couple months
145+
- key: dependency-$CACHE_TYPE # Dependencies cache
143146
paths:
144147
# Cached dependencies and wrappers for gradle
145148
- .gradle/wrapper
@@ -148,8 +151,8 @@ default:
148151
policy: $DEPENDENCY_CACHE_POLICY
149152
unprotect: true
150153
fallback_keys: # Use fallback keys because all cache types are not populated. See note under: populate_dep_cache
151-
- '$CI_SERVER_VERSION-base'
152-
- '$CI_SERVER_VERSION-lib'
154+
- 'dependency-base'
155+
- 'dependency-lib'
153156
- key: $CI_PIPELINE_ID-$CACHE_TYPE # Incremental build cache. Shared by all jobs in the pipeline of the same type
154157
paths:
155158
- .gradle/caches/$GRADLE_VERSION
@@ -837,7 +840,7 @@ package-oci:
837840

838841
configure_system_tests:
839842
variables:
840-
SYSTEM_TESTS_SCENARIOS_GROUPS: "simple_onboarding,simple_onboarding_profiling,docker-ssi,lib-injection"
843+
SYSTEM_TESTS_SCENARIOS_GROUPS: "simple_onboarding,simple_onboarding_profiling,simple_onboarding_appsec,docker-ssi,lib-injection"
841844

842845
create_key:
843846
stage: generate-signing-key

buildSrc/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ dependencies {
4646
implementation("org.ow2.asm", "asm", "9.8")
4747
implementation("org.ow2.asm", "asm-tree", "9.8")
4848

49-
testImplementation("org.spockframework", "spock-core", "2.3-groovy-3.0")
49+
testImplementation(libs.spock.core)
5050
testImplementation("org.codehaus.groovy", "groovy-all", "3.0.17")
5151
}
5252

buildSrc/call-site-instrumentation-plugin/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737
implementation("com.github.javaparser", "javaparser-symbol-solver-core", "3.24.4")
3838

3939
testImplementation("net.bytebuddy", "byte-buddy", "1.17.5")
40-
testImplementation("org.spockframework", "spock-core", "2.3-groovy-3.0")
40+
testImplementation(libs.spock.core)
4141
testImplementation("org.objenesis", "objenesis", "3.0.1")
4242
testImplementation("org.codehaus.groovy", "groovy-all", "3.0.17")
4343
testImplementation("javax.servlet", "javax.servlet-api", "3.0.1")

buildSrc/settings.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
include(":call-site-instrumentation-plugin")
2+
3+
dependencyResolutionManagement {
4+
versionCatalogs {
5+
create("libs") {
6+
from(files("../gradle/libs.versions.toml"))
7+
}
8+
}
9+
}

communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package datadog.communication.ddagent;
22

3+
import static datadog.communication.http.OkHttpUtils.DATADOG_CONTAINER_ID;
4+
import static datadog.communication.http.OkHttpUtils.DATADOG_CONTAINER_TAGS_HASH;
35
import static datadog.communication.serialization.msgpack.MsgPackWriter.FIXARRAY;
6+
import static java.util.Collections.emptySet;
47
import static java.util.Collections.singletonList;
8+
import static java.util.Collections.unmodifiableSet;
59

610
import com.squareup.moshi.JsonAdapter;
711
import com.squareup.moshi.Moshi;
812
import com.squareup.moshi.Types;
13+
import datadog.common.container.ContainerInfo;
914
import datadog.communication.http.OkHttpUtils;
1015
import datadog.communication.monitor.DDAgentStatsDClientManager;
1116
import datadog.communication.monitor.Monitoring;
@@ -86,6 +91,8 @@ public class DDAgentFeaturesDiscovery implements DroppingPolicy {
8691
private volatile String evpProxyEndpoint;
8792
private volatile String version;
8893
private volatile String telemetryProxyEndpoint;
94+
private volatile Set<String> peerTags = emptySet();
95+
private volatile Set<String> spanKindsToComputedStats = emptySet();
8996

9097
private long lastTimeDiscovered;
9198

@@ -119,6 +126,8 @@ private void reset() {
119126
version = null;
120127
lastTimeDiscovered = 0;
121128
telemetryProxyEndpoint = null;
129+
peerTags = emptySet();
130+
spanKindsToComputedStats = emptySet();
122131
}
123132

124133
/** Run feature discovery, unconditionally. */
@@ -151,11 +160,15 @@ private void doDiscovery() {
151160
// 3. fallback if the endpoint couldn't be found or the response couldn't be parsed
152161
try (Recording recording = discoveryTimer.start()) {
153162
boolean fallback = true;
154-
try (Response response =
155-
client
156-
.newCall(new Request.Builder().url(agentBaseUrl.resolve("info").url()).build())
157-
.execute()) {
163+
final Request.Builder requestBuilder =
164+
new Request.Builder().url(agentBaseUrl.resolve("info").url());
165+
final String containerId = ContainerInfo.get().getContainerId();
166+
if (containerId != null) {
167+
requestBuilder.header(DATADOG_CONTAINER_ID, containerId);
168+
}
169+
try (Response response = client.newCall(requestBuilder.build()).execute()) {
158170
if (response.isSuccessful()) {
171+
processInfoResponseHeaders(response);
159172
fallback = !processInfoResponse(response.body().string());
160173
}
161174
} catch (Throwable error) {
@@ -216,6 +229,10 @@ private String probeTracesEndpoint(String[] endpoints) {
216229
return V3_ENDPOINT;
217230
}
218231

232+
private void processInfoResponseHeaders(Response response) {
233+
ContainerInfo.get().setContainerTagsHash(response.header(DATADOG_CONTAINER_TAGS_HASH));
234+
}
235+
219236
@SuppressWarnings("unchecked")
220237
private boolean processInfoResponse(String response) {
221238
try {
@@ -287,6 +304,18 @@ private boolean processInfoResponse(String response) {
287304
null != canDrop
288305
&& ("true".equalsIgnoreCase(String.valueOf(canDrop))
289306
|| Boolean.TRUE.equals(canDrop));
307+
308+
Object peer_tags = map.get("peer_tags");
309+
peerTags =
310+
peer_tags instanceof List
311+
? unmodifiableSet(new HashSet<>((List<String>) peer_tags))
312+
: emptySet();
313+
314+
Object span_kinds = map.get("span_kinds_stats_computed");
315+
spanKindsToComputedStats =
316+
span_kinds instanceof List
317+
? unmodifiableSet(new HashSet<>((List<String>) span_kinds))
318+
: emptySet();
290319
}
291320
try {
292321
state = Strings.sha256(response);
@@ -344,6 +373,14 @@ public boolean supportsLongRunning() {
344373
return supportsLongRunning;
345374
}
346375

376+
public Set<String> peerTags() {
377+
return peerTags;
378+
}
379+
380+
public Set<String> spanKindsToComputedStats() {
381+
return spanKindsToComputedStats;
382+
}
383+
347384
public String getMetricsEndpoint() {
348385
return metricsEndpoint;
349386
}

communication/src/main/java/datadog/communication/http/OkHttpUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ public final class OkHttpUtils {
4343
private static final String DATADOG_META_LANG_INTERPRETER = "Datadog-Meta-Lang-Interpreter";
4444
private static final String DATADOG_META_LANG_INTERPRETER_VENDOR =
4545
"Datadog-Meta-Lang-Interpreter-Vendor";
46-
private static final String DATADOG_CONTAINER_ID = "Datadog-Container-ID";
46+
public static final String DATADOG_CONTAINER_ID = "Datadog-Container-ID";
4747
private static final String DATADOG_ENTITY_ID = "Datadog-Entity-ID";
48+
public static final String DATADOG_CONTAINER_TAGS_HASH = "Datadog-Container-Tags-Hash";
4849

4950
private static final String DD_API_KEY = "DD-API-KEY";
5051

communication/src/test/groovy/datadog/communication/ddagent/DDAgentFeaturesDiscoveryTest.groovy

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package datadog.communication.ddagent
22

3+
import datadog.common.container.ContainerInfo
34
import datadog.communication.monitor.Monitoring
45
import datadog.trace.test.util.DDSpecification
56
import datadog.trace.util.Strings
67
import okhttp3.Call
8+
import okhttp3.Headers
79
import okhttp3.HttpUrl
810
import okhttp3.MediaType
911
import okhttp3.OkHttpClient
@@ -19,6 +21,8 @@ import java.nio.file.Paths
1921
import static datadog.communication.ddagent.DDAgentFeaturesDiscovery.V01_DATASTREAMS_ENDPOINT
2022
import static datadog.communication.ddagent.DDAgentFeaturesDiscovery.V6_METRICS_ENDPOINT
2123
import static datadog.communication.ddagent.DDAgentFeaturesDiscovery.V7_CONFIG_ENDPOINT
24+
import static datadog.communication.http.OkHttpUtils.DATADOG_CONTAINER_ID
25+
import static datadog.communication.http.OkHttpUtils.DATADOG_CONTAINER_TAGS_HASH
2226

2327
class DDAgentFeaturesDiscoveryTest extends DDSpecification {
2428

@@ -30,6 +34,8 @@ class DDAgentFeaturesDiscoveryTest extends DDSpecification {
3034

3135
static final String INFO_RESPONSE = loadJsonFile("agent-info.json")
3236
static final String INFO_STATE = Strings.sha256(INFO_RESPONSE)
37+
static final String INFO_WITH_PEER_TAG_BACK_PROPAGATION_RESPONSE = loadJsonFile("agent-info-with-peer-tag-back-propagation.json")
38+
static final String INFO_WITH_PEER_TAG_BACK_PROPAGATION_STATE = Strings.sha256(INFO_WITH_PEER_TAG_BACK_PROPAGATION_RESPONSE)
3339
static final String INFO_WITH_CLIENT_DROPPING_RESPONSE = loadJsonFile("agent-info-with-client-dropping.json")
3440
static final String INFO_WITH_CLIENT_DROPPING_STATE = Strings.sha256(INFO_WITH_CLIENT_DROPPING_RESPONSE)
3541
static final String INFO_WITHOUT_METRICS_RESPONSE = loadJsonFile("agent-info-without-metrics.json")
@@ -424,13 +430,77 @@ class DDAgentFeaturesDiscoveryTest extends DDSpecification {
424430
!features.supportsContentEncodingHeadersWithEvpProxy()
425431
}
426432

427-
def infoResponse(Request request, String json) {
433+
def "test parse /info response with peer tag back propagation"() {
434+
setup:
435+
OkHttpClient client = Mock(OkHttpClient)
436+
DDAgentFeaturesDiscovery features = new DDAgentFeaturesDiscovery(client, monitoring, agentUrl, true, true)
437+
438+
when: "/info available"
439+
features.discover()
440+
441+
then:
442+
1 * client.newCall(_) >> { Request request -> infoResponse(request, INFO_RESPONSE) }
443+
444+
when: "/info available with peer tag back propagation"
445+
features.discover()
446+
447+
then:
448+
1 * client.newCall(_) >> { Request request -> infoResponse(request, INFO_WITH_PEER_TAG_BACK_PROPAGATION_RESPONSE) }
449+
features.state() == INFO_WITH_PEER_TAG_BACK_PROPAGATION_STATE
450+
features.supportsDropping()
451+
features.peerTags().containsAll(
452+
"_dd.base_service",
453+
"active_record.db.vendor",
454+
"amqp.destination",
455+
"amqp.exchange",
456+
"amqp.queue",
457+
"grpc.host",
458+
"hostname",
459+
"http.host",
460+
"http.server_name",
461+
"streamname",
462+
"tablename",
463+
"topicname"
464+
)
465+
features.spanKindsToComputedStats().containsAll(
466+
"client",
467+
"consumer",
468+
"producer",
469+
"server"
470+
)
471+
}
472+
473+
def "should send container id as header on the info request and parse the hash in the response"() {
474+
setup:
475+
OkHttpClient client = Mock(OkHttpClient)
476+
DDAgentFeaturesDiscovery features = new DDAgentFeaturesDiscovery(client, monitoring, agentUrl, true, true)
477+
def oldContainerId = ContainerInfo.get().getContainerId()
478+
def oldContainerTagsHash = ContainerInfo.get().getContainerTagsHash()
479+
ContainerInfo.get().setContainerId("test")
480+
481+
when: "/info requested"
482+
features.discover()
483+
484+
then:
485+
1 * client.newCall(_) >> { Request request ->
486+
assert request.header(DATADOG_CONTAINER_ID) == "test"
487+
infoResponse(request, INFO_RESPONSE, Headers.of(DATADOG_CONTAINER_TAGS_HASH, "test-hash"))
488+
}
489+
and:
490+
assert ContainerInfo.get().getContainerTagsHash() == "test-hash"
491+
cleanup:
492+
ContainerInfo.get().setContainerId(oldContainerId)
493+
ContainerInfo.get().setContainerTagsHash(oldContainerTagsHash)
494+
}
495+
496+
def infoResponse(Request request, String json, Headers headers = new Headers.Builder().build()) {
428497
return Mock(Call) {
429498
it.execute() >> new Response.Builder()
430499
.code(200)
431500
.request(request)
432501
.protocol(Protocol.HTTP_1_1)
433502
.message("")
503+
.headers(headers)
434504
.body(ResponseBody.create(MediaType.get("application/json"), json))
435505
.build()
436506
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"version": "7.67.0",
3+
"git_commit": "bdf863ccc9",
4+
"endpoints": [
5+
"/v0.3/traces",
6+
"/v0.3/services",
7+
"/v0.4/traces",
8+
"/v0.4/services",
9+
"/v0.5/traces",
10+
"/v0.7/traces",
11+
"/profiling/v1/input",
12+
"/telemetry/proxy/",
13+
"/v0.6/stats",
14+
"/v0.1/pipeline_stats",
15+
"/openlineage/api/v1/lineage",
16+
"/evp_proxy/v1/",
17+
"/evp_proxy/v2/",
18+
"/evp_proxy/v3/",
19+
"/evp_proxy/v4/",
20+
"/debugger/v1/input",
21+
"/debugger/v1/diagnostics",
22+
"/symdb/v1/input",
23+
"/dogstatsd/v1/proxy",
24+
"/dogstatsd/v2/proxy",
25+
"/tracer_flare/v1",
26+
"/config/set"
27+
],
28+
"client_drop_p0s": true,
29+
"span_meta_structs": true,
30+
"long_running_spans": true,
31+
"span_events": true,
32+
"config": {
33+
"default_env": "prod",
34+
"target_tps": 10,
35+
"max_eps": 200,
36+
"receiver_port": 8127,
37+
"receiver_socket": "/var/run/datadog/apm.socket",
38+
"connection_limit": 12,
39+
"receiver_timeout": 100,
40+
"max_request_bytes": 26214400,
41+
"statsd_port": 8125,
42+
"max_memory": 0,
43+
"max_cpu": 0,
44+
"analyzed_spans_by_service": {},
45+
"obfuscation": {
46+
"elastic_search": true,
47+
"mongo": true,
48+
"sql_exec_plan": true,
49+
"sql_exec_plan_normalize": true,
50+
"http": {
51+
"remove_query_string": true,
52+
"remove_path_digits": true
53+
},
54+
"remove_stack_traces": false,
55+
"redis": true,
56+
"memcached": false
57+
}
58+
},
59+
"peer_tags": [
60+
"_dd.base_service",
61+
"active_record.db.vendor",
62+
"amqp.destination",
63+
"amqp.exchange",
64+
"amqp.queue",
65+
"grpc.host",
66+
"hostname",
67+
"http.host",
68+
"http.server_name",
69+
"streamname",
70+
"tablename",
71+
"topicname"
72+
],
73+
"span_kinds_stats_computed": [
74+
"server",
75+
"consumer",
76+
"client",
77+
"producer"
78+
],
79+
"obfuscation_version": 1
80+
}

0 commit comments

Comments
 (0)