Skip to content

Commit 9403a8f

Browse files
committed
refactor: Extract OTLP sender infrastructure to communication/otlp-exporter
Move the OTLP sender/request-body/payload plumbing out of dd-trace-core into a standalone communication/otlp-exporter module so the profiler can reuse it for profile export. Add OtlpCanonicalResourceAttributes as the single source of shared OTLP resource attributes. Pure code movement; no behavior change. Also registers the module in the muzzle filter and the agent shadow jar, and claims ownership in CODEOWNERS.
1 parent 4adb96e commit 9403a8f

51 files changed

Lines changed: 318 additions & 116 deletions

File tree

Some content is hidden

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

‎.github/CODEOWNERS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
# Shared communication
2020
/communication/*.* @DataDog/apm-java
21+
/communication/otlp-exporter/ @DataDog/apm-sdk-capabilities-java
2122
/communication/src/*/*/datadog/communication/*.* @DataDog/apm-java
2223
/communication/src/*/*/datadog/communication/ddagent/ @DataDog/apm-java
2324
/communication/src/*/*/datadog/communication/http/ @DataDog/apm-java
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
plugins {
2+
`java-library`
3+
id("dd-trace-java.module.internal-library")
4+
}
5+
6+
description = "otlp-exporter"
7+
8+
// Network/IO classes are hard to unit-test without a real OTLP endpoint; they are exercised
9+
// via integration tests and the profiling-otel smoke tests instead.
10+
extra["excludedClassesCoverage"] = listOf(
11+
"datadog.communication.otlp.OtlpGrpcSender",
12+
"datadog.communication.otlp.OtlpHttpSender",
13+
"datadog.communication.otlp.OtlpResponse",
14+
"datadog.communication.otlp.OtlpSenderSupport"
15+
)
16+
17+
dependencies {
18+
api(project(":dd-trace-api"))
19+
api(project(":communication"))
20+
api(project(":internal-api"))
21+
implementation(project(":utils:logging-utils"))
22+
implementation(libs.slf4j)
23+
24+
testImplementation(libs.bundles.junit5)
25+
testImplementation(libs.bundles.mockito)
26+
testImplementation(libs.okhttp3.mockwebserver)
27+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package datadog.communication.otlp;
2+
3+
import static datadog.communication.ddagent.TracerVersion.TRACER_VERSION;
4+
5+
import datadog.trace.api.Config;
6+
import java.util.function.BiConsumer;
7+
8+
/** Canonical OTLP resource attributes shared by the trace and profile exports. */
9+
public final class OtlpCanonicalResourceAttributes {
10+
private OtlpCanonicalResourceAttributes() {}
11+
12+
/**
13+
* Visits {@code service.name}, {@code deployment.environment.name} and {@code service.version}
14+
* (when not empty), {@code host.name} (when reported and not empty) and the {@code
15+
* telemetry.sdk.*} attributes, in that order.
16+
*/
17+
public static void visit(Config config, BiConsumer<String, String> visitor) {
18+
visitor.accept("service.name", config.getServiceName());
19+
String env = config.getEnv();
20+
if (!env.isEmpty()) {
21+
visitor.accept("deployment.environment.name", env);
22+
}
23+
String version = config.getVersion();
24+
if (!version.isEmpty()) {
25+
visitor.accept("service.version", version);
26+
}
27+
if (config.isReportHostName()) {
28+
String hostName = config.getHostName();
29+
if (hostName != null && !hostName.isEmpty()) {
30+
visitor.accept("host.name", hostName);
31+
}
32+
}
33+
visitor.accept("telemetry.sdk.name", "datadog");
34+
visitor.accept("telemetry.sdk.version", TRACER_VERSION);
35+
visitor.accept("telemetry.sdk.language", "java");
36+
}
37+
}

dd-trace-core/src/main/java/datadog/trace/core/otlp/common/OtlpGrpcRequestBody.java renamed to communication/otlp-exporter/src/main/java/datadog/communication/otlp/OtlpGrpcRequestBody.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package datadog.trace.core.otlp.common;
1+
package datadog.communication.otlp;
22

33
import java.io.IOException;
44
import javax.annotation.Nonnull;

dd-trace-core/src/main/java/datadog/trace/core/otlp/common/OtlpGrpcSender.java renamed to communication/otlp-exporter/src/main/java/datadog/communication/otlp/OtlpGrpcSender.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
package datadog.trace.core.otlp.common;
1+
package datadog.communication.otlp;
22

33
import static datadog.communication.http.OkHttpUtils.buildHttp2Client;
44
import static datadog.communication.http.OkHttpUtils.isPlainHttp;
55

66
import datadog.communication.http.HttpRetryPolicy;
77
import datadog.logging.RatelimitedLogger;
88
import datadog.trace.api.config.OtlpConfig.Compression;
9-
import datadog.trace.common.writer.RemoteApi;
109
import java.util.Map;
1110
import java.util.concurrent.TimeUnit;
1211
import okhttp3.HttpUrl;
@@ -53,7 +52,7 @@ public OtlpGrpcSender(
5352
}
5453

5554
@Override
56-
public RemoteApi.Response send(OtlpPayload payload) {
55+
public OtlpResponse send(OtlpPayload payload) {
5756
return OtlpSenderSupport.send(client, retryPolicy, makeRequest(payload), RATELIMITED_LOGGER);
5857
}
5958

dd-trace-core/src/main/java/datadog/trace/core/otlp/common/OtlpHttpRequestBody.java renamed to communication/otlp-exporter/src/main/java/datadog/communication/otlp/OtlpHttpRequestBody.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package datadog.trace.core.otlp.common;
1+
package datadog.communication.otlp;
22

33
import java.io.IOException;
44
import javax.annotation.Nonnull;

dd-trace-core/src/main/java/datadog/trace/core/otlp/common/OtlpHttpSender.java renamed to communication/otlp-exporter/src/main/java/datadog/communication/otlp/OtlpHttpSender.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
package datadog.trace.core.otlp.common;
1+
package datadog.communication.otlp;
22

33
import static datadog.communication.http.OkHttpUtils.buildHttpClient;
44
import static datadog.communication.http.OkHttpUtils.isPlainHttp;
55

66
import datadog.communication.http.HttpRetryPolicy;
77
import datadog.logging.RatelimitedLogger;
88
import datadog.trace.api.config.OtlpConfig.Compression;
9-
import datadog.trace.common.writer.RemoteApi;
109
import java.util.Map;
1110
import java.util.concurrent.TimeUnit;
1211
import okhttp3.HttpUrl;
@@ -57,7 +56,7 @@ public HttpUrl url() {
5756
}
5857

5958
@Override
60-
public RemoteApi.Response send(OtlpPayload payload) {
59+
public OtlpResponse send(OtlpPayload payload) {
6160
return OtlpSenderSupport.send(client, retryPolicy, makeRequest(payload), RATELIMITED_LOGGER);
6261
}
6362

dd-trace-core/src/main/java/datadog/trace/core/otlp/common/OtlpPayload.java renamed to communication/otlp-exporter/src/main/java/datadog/communication/otlp/OtlpPayload.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package datadog.trace.core.otlp.common;
1+
package datadog.communication.otlp;
22

33
import java.nio.ByteBuffer;
44

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package datadog.communication.otlp;
2+
3+
import java.util.Optional;
4+
import java.util.OptionalInt;
5+
6+
/**
7+
* Encapsulates the result of an OTLP export attempt.
8+
*
9+
* <p>If communication fails or times out, the response will NOT be successful and will lack a
10+
* status code, but will have an exception.
11+
*
12+
* <p>If communication succeeds, the response will have a status code and will be marked as success
13+
* or failure in accordance with the code.
14+
*
15+
* <p>NOTE: A successful communication may still contain an exception if there was a problem parsing
16+
* the response.
17+
*/
18+
public final class OtlpResponse {
19+
/** Factory method for a successful request with a trivial response body */
20+
public static OtlpResponse success(final int status) {
21+
return new OtlpResponse(true, status, null, null);
22+
}
23+
24+
/** Factory method for a successful request with a response body */
25+
public static OtlpResponse success(final int status, String response) {
26+
return new OtlpResponse(true, status, null, response);
27+
}
28+
29+
/** Factory method for a successful request with a malformed response body */
30+
public static OtlpResponse successWithParseError(final int status, final Throwable exception) {
31+
return new OtlpResponse(true, status, exception, null);
32+
}
33+
34+
/** Factory method for a request that received an error status in response */
35+
public static OtlpResponse failed(final int status) {
36+
return new OtlpResponse(false, status, null, null);
37+
}
38+
39+
/** Factory method for a request that received an error status and a response body */
40+
public static OtlpResponse failed(final int status, String response) {
41+
return new OtlpResponse(false, status, null, response);
42+
}
43+
44+
/** Factory method for a failed communication attempt */
45+
public static OtlpResponse failed(final Throwable exception) {
46+
return new OtlpResponse(false, null, exception, null);
47+
}
48+
49+
private final boolean success;
50+
private final Integer status;
51+
private final Throwable exception;
52+
private final String response;
53+
54+
private OtlpResponse(
55+
final boolean success, final Integer status, final Throwable exception, String response) {
56+
this.success = success;
57+
this.status = status;
58+
this.exception = exception;
59+
this.response = response;
60+
}
61+
62+
public boolean success() {
63+
return success;
64+
}
65+
66+
public OptionalInt status() {
67+
return status == null ? OptionalInt.empty() : OptionalInt.of(status);
68+
}
69+
70+
public Optional<Throwable> exception() {
71+
return Optional.ofNullable(exception);
72+
}
73+
74+
/** The raw response body, or empty for failed communication attempts (no body received) */
75+
public Optional<String> response() {
76+
return Optional.ofNullable(response);
77+
}
78+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package datadog.communication.otlp;
2+
3+
/** Sends chunks of OTLP data. */
4+
public interface OtlpSender {
5+
OtlpResponse send(OtlpPayload payload);
6+
7+
void shutdown();
8+
}

0 commit comments

Comments
 (0)