diff --git a/dd-java-agent/instrumentation/datadog/dynamic-instrumentation/span-origin/src/main/java/datadog/trace/instrumentation/codeorigin/CodeOriginInstrumentation.java b/dd-java-agent/instrumentation/datadog/dynamic-instrumentation/span-origin/src/main/java/datadog/trace/instrumentation/codeorigin/CodeOriginInstrumentation.java index bad0bc6ebd9..239c1f0e962 100644 --- a/dd-java-agent/instrumentation/datadog/dynamic-instrumentation/span-origin/src/main/java/datadog/trace/instrumentation/codeorigin/CodeOriginInstrumentation.java +++ b/dd-java-agent/instrumentation/datadog/dynamic-instrumentation/span-origin/src/main/java/datadog/trace/instrumentation/codeorigin/CodeOriginInstrumentation.java @@ -1,5 +1,10 @@ package datadog.trace.instrumentation.codeorigin; +import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; +import static net.bytebuddy.matcher.ElementMatchers.hasSuperType; +import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.isInterface; + import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule.Tracing; import datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers; @@ -11,6 +16,7 @@ import net.bytebuddy.description.NamedElement; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; public abstract class CodeOriginInstrumentation extends Tracing implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { @@ -37,7 +43,16 @@ public String hierarchyMarkerType() { @Override public ElementMatcher hierarchyMatcher() { - return HierarchyMatchers.declaresMethod(HierarchyMatchers.isAnnotatedWith(matcher)); + ElementMatcher.Junction matcher = + HierarchyMatchers.declaresMethod(HierarchyMatchers.isAnnotatedWith(this.matcher)); + if (InstrumenterConfig.get().isCodeOriginInterfaceSupport()) { + matcher = + matcher.or( + HierarchyMatchers.implementsInterface( + HierarchyMatchers.declaresMethod( + HierarchyMatchers.isAnnotatedWith(this.matcher)))); + } + return matcher; } @Override @@ -45,5 +60,11 @@ public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( HierarchyMatchers.isAnnotatedWith(matcher), "datadog.trace.instrumentation.codeorigin.EntrySpanOriginAdvice"); + if (InstrumenterConfig.get().isCodeOriginInterfaceSupport()) { + transformer.applyAdvice( + ElementMatchers.isDeclaredBy( + hasSuperType(isInterface().and(declaresMethod(isAnnotatedWith(matcher))))), + "datadog.trace.instrumentation.codeorigin.EntrySpanOriginAdvice"); + } } } diff --git a/dd-smoke-tests/debugger-integration-tests/src/main/java/datadog/smoketest/debugger/controller/InterfacedController.java b/dd-smoke-tests/debugger-integration-tests/src/main/java/datadog/smoketest/debugger/controller/InterfacedController.java new file mode 100644 index 00000000000..08cca6b9238 --- /dev/null +++ b/dd-smoke-tests/debugger-integration-tests/src/main/java/datadog/smoketest/debugger/controller/InterfacedController.java @@ -0,0 +1,18 @@ +package datadog.smoketest.debugger.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class InterfacedController implements InterfaceApi { + + @Override + public String process() { + return "OK"; + } +} + +interface InterfaceApi { + @RequestMapping("/process") + String process(); +} diff --git a/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/SpringBasedIntegrationTest.java b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/SpringBasedIntegrationTest.java new file mode 100644 index 00000000000..9f05e22735b --- /dev/null +++ b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/SpringBasedIntegrationTest.java @@ -0,0 +1,79 @@ +package datadog.smoketest; + +import com.datadog.debugger.probe.LogProbe; +import datadog.trace.agent.test.utils.PortUtils; +import datadog.trace.util.TagsHelper; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.locks.LockSupport; +import okhttp3.OkHttpClient; +import okhttp3.Request; + +public class SpringBasedIntegrationTest extends BaseIntegrationTest { + protected static final String DEBUGGER_TEST_APP_CLASS = + "datadog.smoketest.debugger.SpringBootTestApplication"; + + @Override + protected String getAppClass() { + return DEBUGGER_TEST_APP_CLASS; + } + + @Override + protected String getAppId() { + return TagsHelper.sanitize("SpringBootTestApplication"); + } + + protected String startSpringApp(List logProbes) throws Exception { + return startSpringApp(logProbes, false); + } + + protected String startSpringApp(List logProbes, boolean enableProcessTags) + throws Exception { + setCurrentConfiguration(createConfig(logProbes)); + String httpPort = String.valueOf(PortUtils.randomOpenPort()); + ProcessBuilder processBuilder = createProcessBuilder(logFilePath, "--server.port=" + httpPort); + if (!enableProcessTags) { + processBuilder.environment().put("DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED", "false"); + } + targetProcess = processBuilder.start(); + // assert in logs app started + waitForSpecificLogLine( + logFilePath, + "datadog.smoketest.debugger.SpringBootTestApplication - Started SpringBootTestApplication", + Duration.ofMillis(100), + Duration.ofSeconds(30)); + return httpPort; + } + + protected void sendRequest(String httpPort, String urlPath) { + OkHttpClient client = new OkHttpClient.Builder().build(); + Request request = + new Request.Builder().url("http://localhost:" + httpPort + urlPath).get().build(); + try { + client.newCall(request).execute(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + protected static void waitForSpecificLogLine( + Path logFilePath, String line, Duration sleep, Duration timeout) throws IOException { + boolean[] result = new boolean[] {false}; + long total = sleep.toNanos() == 0 ? 0 : timeout.toNanos() / sleep.toNanos(); + int i = 0; + while (i < total && !result[0]) { + Files.lines(logFilePath) + .forEach( + it -> { + if (it.contains(line)) { + result[0] = true; + } + }); + LockSupport.parkNanos(sleep.toNanos()); + i++; + } + } +} diff --git a/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/SpringCodeOriginIntegrationTest.java b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/SpringCodeOriginIntegrationTest.java new file mode 100644 index 00000000000..22cafa655fc --- /dev/null +++ b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/SpringCodeOriginIntegrationTest.java @@ -0,0 +1,109 @@ +package datadog.smoketest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import datadog.trace.api.DDTags; +import datadog.trace.test.agent.decoder.DecodedSpan; +import datadog.trace.test.agent.decoder.DecodedTrace; +import datadog.trace.test.util.NonRetryable; +import java.nio.file.Path; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledIf; + +@NonRetryable +public class SpringCodeOriginIntegrationTest extends SpringBasedIntegrationTest { + + private boolean traceReceived; + + @Override + protected ProcessBuilder createProcessBuilder(Path logFilePath, String... params) { + List commandParams = getDebuggerCommandParams(); + commandParams.add("-Ddd.trace.enabled=true"); // explicitly enable tracer + commandParams.add("-Ddd.code.origin.for.spans.enabled=true"); + commandParams.add("-Ddd.code.origin.for.spans.interface.support=true"); + return ProcessBuilderHelper.createProcessBuilder( + commandParams, logFilePath, getAppClass(), params); + } + + @Test + @DisplayName("testRegularController") + @DisabledIf( + value = "datadog.environment.JavaVirtualMachine#isJ9", + disabledReason = "Flaky on J9 JVMs") + void testRegularController() throws Exception { + registerTraceListener(this::receiveGreetingTrace); + String httpPort = startSpringApp(Collections.emptyList()); + sendRequest(httpPort, "/greeting"); // trigger CodeOriginProbe instrumentation + waitForSpecificLogLine( + logFilePath, + "DEBUG com.datadog.debugger.agent.ConfigurationUpdater - Re-transformation done", + Duration.ofMillis(100), + Duration.ofSeconds(30)); // wait for instrumentation to be done + sendRequest(httpPort, "/greeting"); // generate first span with tags + processRequests( + () -> traceReceived, () -> String.format("Timeout! traceReceived=%s", traceReceived)); + } + + @Test + @DisplayName("testInterfacedController") + @DisabledIf( + value = "datadog.environment.JavaVirtualMachine#isJ9", + disabledReason = "Flaky on J9 JVMs") + void testInterfacedController() throws Exception { + registerTraceListener(this::receiveProcessTrace); + String httpPort = startSpringApp(Collections.emptyList()); + sendRequest(httpPort, "/process"); // trigger CodeOriginProbe instrumentation + waitForSpecificLogLine( + logFilePath, + "DEBUG com.datadog.debugger.agent.ConfigurationUpdater - Re-transformation done", + Duration.ofMillis(100), + Duration.ofSeconds(30)); // wait for instrumentation to be done + sendRequest(httpPort, "/process"); // generate first span with tags + processRequests( + () -> traceReceived, () -> String.format("Timeout! traceReceived=%s", traceReceived)); + } + + private void receiveGreetingTrace(DecodedTrace decodedTrace) { + for (DecodedSpan span : decodedTrace.getSpans()) { + if (span.getName().equals("spring.handler") + && span.getResource().equals("WebController.greeting") + && span.getMeta().containsKey(DDTags.DD_CODE_ORIGIN_FRAME_TYPE)) { + assertEquals("entry", span.getMeta().get(DDTags.DD_CODE_ORIGIN_TYPE)); + assertEquals( + "datadog.smoketest.debugger.controller.WebController", + span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_TYPE)); + assertEquals("WebController.java", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_FILE)); + assertEquals("10", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_LINE)); + assertEquals("greeting", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_METHOD)); + assertEquals("()", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_SIGNATURE)); + assertFalse(traceReceived); + traceReceived = true; + } + } + } + + private void receiveProcessTrace(DecodedTrace decodedTrace) { + for (DecodedSpan span : decodedTrace.getSpans()) { + if (span.getName().equals("spring.handler") + && span.getResource().equals("InterfacedController.process") + && span.getMeta().containsKey(DDTags.DD_CODE_ORIGIN_FRAME_TYPE)) { + assertEquals("entry", span.getMeta().get(DDTags.DD_CODE_ORIGIN_TYPE)); + assertEquals( + "datadog.smoketest.debugger.controller.InterfacedController", + span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_TYPE)); + assertEquals( + "InterfacedController.java", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_FILE)); + assertEquals("11", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_LINE)); + assertEquals("process", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_METHOD)); + assertEquals("()", span.getMeta().get(DDTags.DD_CODE_ORIGIN_FRAME_SIGNATURE)); + assertFalse(traceReceived); + traceReceived = true; + } + } + } +} diff --git a/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java index 4b2f76ca94b..9990c04a8c5 100644 --- a/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java +++ b/dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/TracerDebuggerIntegrationTest.java @@ -1,6 +1,7 @@ package datadog.smoketest; import static com.datadog.debugger.util.LogProbeTestHelper.parseTemplate; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -9,22 +10,15 @@ import com.datadog.debugger.probe.LogProbe; import com.datadog.debugger.sink.Snapshot; -import datadog.trace.agent.test.utils.PortUtils; import datadog.trace.bootstrap.debugger.MethodLocation; import datadog.trace.bootstrap.debugger.ProbeId; import datadog.trace.test.util.Flaky; import datadog.trace.test.util.NonRetryable; import datadog.trace.util.TagsHelper; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.time.Duration; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.LockSupport; import java.util.regex.Pattern; -import okhttp3.OkHttpClient; -import okhttp3.Request; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIf; @@ -33,22 +27,10 @@ @Flaky @NonRetryable -public class TracerDebuggerIntegrationTest extends BaseIntegrationTest { +public class TracerDebuggerIntegrationTest extends SpringBasedIntegrationTest { - private static final String DEBUGGER_TEST_APP_CLASS = - "datadog.smoketest.debugger.SpringBootTestApplication"; private static final ProbeId PROBE_ID = new ProbeId("123356536", 1); - @Override - protected String getAppClass() { - return DEBUGGER_TEST_APP_CLASS; - } - - @Override - protected String getAppId() { - return TagsHelper.sanitize("SpringBootTestApplication"); - } - @ParameterizedTest(name = "Process tags enabled ''{0}''") @ValueSource(booleans = {true, false}) @DisplayName("testTracer") @@ -86,7 +68,8 @@ void testTracer(boolean processTagsEnabled) throws Exception { } requestReceived.set(true); }); - doTestTracer(logProbe, processTagsEnabled); + String httpPort = startSpringApp(singletonList(logProbe), processTagsEnabled); + sendRequest(httpPort, "/greeting"); processRequests( requestReceived::get, () -> String.format("timeout requestReceived=%s", requestReceived.get())); @@ -120,7 +103,8 @@ void testTracerDynamicLog() throws Exception { logFilePath, it -> it.contains("TypePool$Resolution$NoSuchTypeException"))); requestReceived.set(true); }); - doTestTracer(logProbe); + String httpPort = startSpringApp(singletonList(logProbe)); + sendRequest(httpPort, "/greeting"); processRequests( requestReceived::get, () -> String.format("timeout requestReceived=%s", requestReceived.get())); @@ -151,7 +135,8 @@ void testTracerSameMethod() throws Exception { assertTrue(Pattern.matches("\\d+", intakeRequest.getSpanId())); requestReceived.set(true); }); - doTestTracer(logProbe); + String httpPort = startSpringApp(singletonList(logProbe)); + sendRequest(httpPort, "/greeting"); processRequests( requestReceived::get, () -> String.format("timeout requestReceived=%s", requestReceived.get())); @@ -182,7 +167,8 @@ void testTracerLineSnapshotProbe() throws Exception { assertTrue(Pattern.matches("\\d+", intakeRequest.getSpanId())); requestReceived.set(true); }); - doTestTracer(logProbe); + String httpPort = startSpringApp(singletonList(logProbe)); + sendRequest(httpPort, "/greeting"); processRequests( requestReceived::get, () -> String.format("timeout requestReceived=%s", requestReceived.get())); @@ -213,56 +199,13 @@ void testTracerLineDynamicLogProbe() throws Exception { assertTrue(Pattern.matches("\\d+", intakeRequest.getSpanId())); requestReceived.set(true); }); - doTestTracer(logProbe); + String httpPort = startSpringApp(singletonList(logProbe)); + sendRequest(httpPort, "/greeting"); processRequests( requestReceived::get, () -> String.format("timeout requestReceived=%s", requestReceived.get())); } - private void doTestTracer(LogProbe logProbe) throws Exception { - doTestTracer(logProbe, false); - } - - private void doTestTracer(LogProbe logProbe, boolean enableProcessTags) throws Exception { - setCurrentConfiguration(createConfig(logProbe)); - String httpPort = String.valueOf(PortUtils.randomOpenPort()); - ProcessBuilder processBuilder = createProcessBuilder(logFilePath, "--server.port=" + httpPort); - if (!enableProcessTags) { - processBuilder.environment().put("DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED", "false"); - } - targetProcess = processBuilder.start(); - // assert in logs app started - waitForSpecificLogLine( - logFilePath, - "datadog.smoketest.debugger.SpringBootTestApplication - Started SpringBootTestApplication", - Duration.ofMillis(100), - Duration.ofSeconds(30)); - sendRequest("http://localhost:" + httpPort + "/greeting"); - /* - RecordedRequest snapshotRequest = retrieveSnapshotRequest(); - if (snapshotRequest == null) { - System.out.println("retry instrumentation because probable race with Tracer..."); - // may encounter a race with Tracer, try again to re-instrument by removing config and - // re-installing instrumentation - synchronized (configLock) { - setCurrentConfiguration(null); - configLock.wait(10_000); - if (!isConfigProvided()) { - System.out.println("Empty config was not provided!"); - } - } - setCurrentConfiguration(createConfig(logProbe)); - snapshotRequest = retrieveSnapshotRequest(); - } - assertNotNull(snapshotRequest); - - String bodyStr = snapshotRequest.getBody().readUtf8(); - JsonAdapter> adapter = createAdapterForSnapshot(); - System.out.println(bodyStr); - return adapter.fromJson(bodyStr).get(0); - */ - } - @Override protected ProcessBuilder createProcessBuilder(Path logFilePath, String... params) { List commandParams = getDebuggerCommandParams(); @@ -271,32 +214,4 @@ protected ProcessBuilder createProcessBuilder(Path logFilePath, String... params return ProcessBuilderHelper.createProcessBuilder( commandParams, logFilePath, getAppClass(), params); } - - private void sendRequest(String url) { - OkHttpClient client = new OkHttpClient.Builder().build(); - Request request = new Request.Builder().url(url).get().build(); - try { - client.newCall(request).execute(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - private static void waitForSpecificLogLine( - Path logFilePath, String line, Duration sleep, Duration timeout) throws IOException { - boolean[] result = new boolean[] {false}; - long total = sleep.toNanos() == 0 ? 0 : timeout.toNanos() / sleep.toNanos(); - int i = 0; - while (i < total && !result[0]) { - Files.lines(logFilePath) - .forEach( - it -> { - if (it.contains(line)) { - result[0] = true; - } - }); - LockSupport.parkNanos(sleep.toNanos()); - i++; - } - } } diff --git a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java index 465812e7f7b..6f355eaf879 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java @@ -50,9 +50,8 @@ public final class ConfigDefaults { static final boolean DEFAULT_WRITER_BAGGAGE_INJECT = true; static final String DEFAULT_SITE = "datadoghq.com"; - static final boolean DEFAULT_CODE_ORIGIN_FOR_SPANS_ENABLED = false; + static final boolean DEFAULT_CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT = false; static final int DEFAULT_CODE_ORIGIN_MAX_USER_FRAMES = 8; - static final boolean DEFAULT_TRACE_SPAN_ORIGIN_ENRICHED = false; static final boolean DEFAULT_TRACE_ENABLED = true; public static final boolean DEFAULT_TRACE_OTEL_ENABLED = false; static final boolean DEFAULT_INTEGRATIONS_ENABLED = true; diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java index cf4fbb1d78f..8bd99d24e45 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java @@ -10,6 +10,8 @@ */ public final class TraceInstrumentationConfig { public static final String CODE_ORIGIN_FOR_SPANS_ENABLED = "code.origin.for.spans.enabled"; + public static final String CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT = + "code.origin.for.spans.interface.support"; public static final String CODE_ORIGIN_MAX_USER_FRAMES = "code.origin.max.user.frames"; public static final String TRACE_ENABLED = "trace.enabled"; public static final String INTEGRATIONS_ENABLED = "integrations.enabled"; diff --git a/internal-api/src/main/java/datadog/trace/api/InstrumenterConfig.java b/internal-api/src/main/java/datadog/trace/api/InstrumenterConfig.java index 00dd43f7197..952b891149b 100644 --- a/internal-api/src/main/java/datadog/trace/api/InstrumenterConfig.java +++ b/internal-api/src/main/java/datadog/trace/api/InstrumenterConfig.java @@ -5,6 +5,7 @@ import static datadog.trace.api.ConfigDefaults.DEFAULT_APPSEC_RASP_ENABLED; import static datadog.trace.api.ConfigDefaults.DEFAULT_APP_LOGS_COLLECTION_ENABLED; import static datadog.trace.api.ConfigDefaults.DEFAULT_CIVISIBILITY_ENABLED; +import static datadog.trace.api.ConfigDefaults.DEFAULT_CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT; import static datadog.trace.api.ConfigDefaults.DEFAULT_DATA_JOBS_ENABLED; import static datadog.trace.api.ConfigDefaults.DEFAULT_IAST_ENABLED; import static datadog.trace.api.ConfigDefaults.DEFAULT_INTEGRATIONS_ENABLED; @@ -50,6 +51,7 @@ import static datadog.trace.api.config.TraceInstrumentationConfig.AKKA_FORK_JOIN_TASK_NAME; import static datadog.trace.api.config.TraceInstrumentationConfig.AXIS_TRANSPORT_CLASS_NAME; import static datadog.trace.api.config.TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_ENABLED; +import static datadog.trace.api.config.TraceInstrumentationConfig.CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT; import static datadog.trace.api.config.TraceInstrumentationConfig.EXPERIMENTAL_DEFER_INTEGRATIONS_UNTIL; import static datadog.trace.api.config.TraceInstrumentationConfig.HTTP_URL_CONNECTION_CLASS_NAME; import static datadog.trace.api.config.TraceInstrumentationConfig.INSTRUMENTATION_CONFIG_ID; @@ -139,6 +141,7 @@ public class InstrumenterConfig { private final boolean integrationsEnabled; private final boolean codeOriginEnabled; + private final boolean codeOriginInterfaceSupport; private final boolean traceEnabled; private final boolean traceOtelEnabled; private final boolean metricsOtelEnabled; @@ -241,6 +244,10 @@ private InstrumenterConfig() { codeOriginEnabled = configProvider.getBoolean( CODE_ORIGIN_FOR_SPANS_ENABLED, getDefaultCodeOriginForSpanEnabled()); + codeOriginInterfaceSupport = + configProvider.getBoolean( + CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT, + DEFAULT_CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT); traceEnabled = configProvider.getBoolean(TRACE_ENABLED, DEFAULT_TRACE_ENABLED); traceOtelEnabled = configProvider.getBoolean(TRACE_OTEL_ENABLED, DEFAULT_TRACE_OTEL_ENABLED); metricsOtelEnabled = @@ -373,6 +380,10 @@ public boolean isCodeOriginEnabled() { return codeOriginEnabled; } + public boolean isCodeOriginInterfaceSupport() { + return codeOriginInterfaceSupport; + } + public boolean isTriageEnabled() { return triageEnabled; } diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index 6b00677813f..68ac9893314 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -905,6 +905,14 @@ "aliases": [] } ], + "DD_CODE_ORIGIN_FOR_SPANS_INTERFACE_SUPPORT": [ + { + "version": "A", + "type": "boolean", + "default": "true", + "aliases": [] + } + ], "DD_CODE_ORIGIN_MAX_USER_FRAMES": [ { "version": "A",