Skip to content

Commit 5f0a764

Browse files
committed
fix: Only enable client side stats if the host agent is at least 7.65.0
1 parent 912bdde commit 5f0a764

File tree

5 files changed

+127
-3
lines changed

5 files changed

+127
-3
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package datadog.communication.ddagent;
2+
3+
public class AgentVersion {
4+
5+
/**
6+
* Checks if the given version string represents a version that is at least the specified major,
7+
* minor, and patch version.
8+
*
9+
* @param version the version string to check (e.g., "7.65.0")
10+
* @param minMajor minimum major version
11+
* @param minMinor minimum minor version
12+
* @param minPatch minimum patch version
13+
* @return true if version is at least the specified minimum, false otherwise (including when
14+
* version is null or unparseable)
15+
*/
16+
public static boolean isVersionAtLeast(String version, int minMajor, int minMinor, int minPatch) {
17+
if (version == null || version.isEmpty()) {
18+
return false;
19+
}
20+
21+
try {
22+
// Parse version string in format "major.minor.patch" (e.g., "7.65.0")
23+
int majorDot = version.indexOf('.');
24+
if (majorDot == -1) {
25+
return false;
26+
}
27+
28+
int major = Integer.parseInt(version.substring(0, majorDot));
29+
30+
if (major > minMajor) {
31+
return true;
32+
} else if (major < minMajor) {
33+
return false;
34+
}
35+
36+
// major == minMajor
37+
int minorDot = version.indexOf('.', majorDot + 1);
38+
if (minorDot == -1) {
39+
return false;
40+
}
41+
42+
int minor = Integer.parseInt(version.substring(majorDot + 1, minorDot));
43+
if (minor > minMinor) {
44+
return true;
45+
} else if (minor < minMinor) {
46+
return false;
47+
}
48+
49+
// major == minMajor && minor == minMinor
50+
// Find end of patch version (may have suffix like "-rc.1")
51+
int patchEnd = minorDot + 1;
52+
while (patchEnd < version.length() && Character.isDigit(version.charAt(patchEnd))) {
53+
patchEnd++;
54+
}
55+
56+
int patch = Integer.parseInt(version.substring(minorDot + 1, patchEnd));
57+
return patch >= minPatch;
58+
} catch (NumberFormatException | IndexOutOfBoundsException e) {
59+
return false;
60+
}
61+
}
62+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ private static void discoverStatsDPort(final Map<String, Object> info) {
358358
public boolean supportsMetrics() {
359359
return metricsEnabled
360360
&& null != discoveryState.metricsEndpoint
361-
&& discoveryState.supportsDropping;
361+
&& discoveryState.supportsDropping
362+
&& AgentVersion.isVersionAtLeast(discoveryState.version, 7, 65, 0);
362363
}
363364

364365
public boolean supportsDebugger() {

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

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,67 @@ class DDAgentFeaturesDiscoveryTest extends DDSpecification {
498498
)
499499
}
500500

501+
def "test metrics disabled for agent version below 7.65"() {
502+
setup:
503+
OkHttpClient client = Mock(OkHttpClient)
504+
DDAgentFeaturesDiscovery features = new DDAgentFeaturesDiscovery(client, monitoring, agentUrl, true, true)
505+
506+
when: "agent version is below 7.65"
507+
features.discover()
508+
509+
then:
510+
1 * client.newCall(_) >> { Request request ->
511+
def response = """
512+
{
513+
"version": "${version}",
514+
"endpoints": ["/v0.5/traces", "/v0.6/stats"],
515+
"client_drop_p0s": true,
516+
"config": {}
517+
}
518+
"""
519+
infoResponse(request, response)
520+
}
521+
features.getMetricsEndpoint() == V6_METRICS_ENDPOINT
522+
features.supportsDropping() == true
523+
features.supportsMetrics() == expected
524+
525+
where:
526+
version | expected
527+
"7.64.0" | false
528+
"7.64.9" | false
529+
"7.64.9-rc.1" | false
530+
"7.65.0" | true
531+
"7.65.1" | true
532+
"7.70.0" | true
533+
"8.0.0" | true
534+
}
535+
536+
def "test metrics disabled for agent with unparseable version"() {
537+
setup:
538+
OkHttpClient client = Mock(OkHttpClient)
539+
DDAgentFeaturesDiscovery features = new DDAgentFeaturesDiscovery(client, monitoring, agentUrl, true, true)
540+
541+
when: "agent version is unparseable"
542+
features.discover()
543+
544+
then:
545+
1 * client.newCall(_) >> { Request request ->
546+
def response = """
547+
{
548+
"version": "${version}",
549+
"endpoints": ["/v0.5/traces", "/v0.6/stats"],
550+
"client_drop_p0s": true,
551+
"config": {}
552+
}
553+
"""
554+
infoResponse(request, response)
555+
}
556+
!features.supportsMetrics()
557+
558+
where:
559+
version << ["invalid", "7", "7.65", "", null]
560+
}
561+
501562
def "should send container id as header on the info request and parse the hash in the response"() {
502563
setup:
503564
OkHttpClient client = Mock(OkHttpClient)

communication/src/test/resources/agent-features/agent-info-with-client-dropping.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.99.0",
2+
"version": "7.65.0",
33
"git_commit": "fab047e10",
44
"build_date": "2020-12-04 15:57:06.74187 +0200 EET m=+0.029001792",
55
"endpoints": [

dd-trace-core/src/test/groovy/datadog/trace/common/metrics/MetricsReliabilityTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class MetricsReliabilityTest extends DDCoreSpecification {
3535
httpServer {
3636
handlers {
3737
get("/info") {
38-
final def res = '{"endpoints":[' + (state.agentMetricsAvailable ? '"/v0.6/stats", ' : '') + '"/v0.4/traces"], "client_drop_p0s" : true}'
38+
final def res = '{"version":"7.65.0","endpoints":[' + (state.agentMetricsAvailable ? '"/v0.6/stats", ' : '') + '"/v0.4/traces"], "client_drop_p0s" : true}'
3939
state.hash = Strings.sha256(res)
4040
response.send(res)
4141
state.latch.countDown()

0 commit comments

Comments
 (0)