From 51a4a9de85308e1ff3168f00b743a50cb5fa7513 Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Thu, 12 Jun 2025 10:30:22 -0400 Subject: [PATCH 1/2] chore(ssi): track the source of installation --- .../trace/bootstrap/AgentBootstrap.java | 11 +++++++ .../datadog/trace/bootstrap/SystemUtils.java | 8 +++++ .../datadog/trace/api/ConfigDefaults.java | 3 ++ .../trace/api/config/GeneralConfig.java | 4 +++ .../main/java/datadog/trace/api/Config.java | 11 +++++++ .../datadog/trace/api/ConfigTest.groovy | 32 +++++++++++++++++++ 6 files changed, 69 insertions(+) diff --git a/dd-java-agent/src/main/java/datadog/trace/bootstrap/AgentBootstrap.java b/dd-java-agent/src/main/java/datadog/trace/bootstrap/AgentBootstrap.java index 77bc9f8685e..ea784033ebb 100644 --- a/dd-java-agent/src/main/java/datadog/trace/bootstrap/AgentBootstrap.java +++ b/dd-java-agent/src/main/java/datadog/trace/bootstrap/AgentBootstrap.java @@ -46,6 +46,7 @@ public final class AgentBootstrap { static final String LIB_INJECTION_ENABLED_ENV_VAR = "DD_INJECTION_ENABLED"; static final String LIB_INJECTION_FORCE_SYS_PROP = "dd.inject.force"; + static final String LIB_INSTRUMENTATION_SOURCE_SYS_PROP = "dd.instrumentation.source"; private static final Class thisClass = AgentBootstrap.class; private static final int MAX_EXCEPTION_CHAIN_LENGTH = 99; @@ -134,6 +135,12 @@ private static void agentmainImpl( return; } + if (getConfig(LIB_INJECTION_ENABLED_ENV_VAR)) { + recordInstrumentationSource("ssi"); + } else { + recordInstrumentationSource("cmd_line"); + } + final URL agentJarURL = installAgentJar(inst); final Class agentClass; try { @@ -164,6 +171,10 @@ static boolean getConfig(String configName) { } } + private static void recordInstrumentationSource(String source) { + SystemUtils.trySetProperty(LIB_INSTRUMENTATION_SOURCE_SYS_PROP, source); + } + static boolean exceptionCauseChainContains(Throwable ex, String exClassName) { Set stack = Collections.newSetFromMap(new IdentityHashMap<>()); Throwable t = ex; diff --git a/dd-java-agent/src/main/java/datadog/trace/bootstrap/SystemUtils.java b/dd-java-agent/src/main/java/datadog/trace/bootstrap/SystemUtils.java index 1ad66462da1..21e28cf509f 100644 --- a/dd-java-agent/src/main/java/datadog/trace/bootstrap/SystemUtils.java +++ b/dd-java-agent/src/main/java/datadog/trace/bootstrap/SystemUtils.java @@ -23,6 +23,14 @@ public static String tryGetProperty(String property) { } } + public static String trySetProperty(String property, String value) { + try { + return System.setProperty(property, value); + } catch (SecurityException e) { + return null; + } + } + public static String getPropertyOrDefault(String property, String defaultValue) { try { return System.getProperty(property, defaultValue); 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 1f8d733e8ce..c389eccbd95 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 @@ -240,6 +240,9 @@ public final class ConfigDefaults { static final boolean DEFAULT_TELEMETRY_LOG_COLLECTION_ENABLED = true; static final int DEFAULT_TELEMETRY_DEPENDENCY_RESOLUTION_QUEUE_SIZE = 100000; + static final boolean DEFAULT_SSI_INJECTION_FORCE = false; + static final String DEFAULT_INSTRUMENTATION_SOURCE = "manual"; + static final Set DEFAULT_TRACE_EXPERIMENTAL_FEATURES_ENABLED = new HashSet<>( asList("DD_TAGS", "DD_LOGS_INJECTION", "DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED")); diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/GeneralConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/GeneralConfig.java index 3d26641f837..8be2c2a975f 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/GeneralConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/GeneralConfig.java @@ -103,5 +103,9 @@ public final class GeneralConfig { public static final String STACK_TRACE_LENGTH_LIMIT = "stack.trace.length.limit"; + public static final String SSI_INJECTION_ENABLED = "injection.enabled"; + public static final String SSI_INJECTION_FORCE = "inject.force"; + public static final String INSTRUMENTATION_SOURCE = "instrumentation.source"; + private GeneralConfig() {} } diff --git a/internal-api/src/main/java/datadog/trace/api/Config.java b/internal-api/src/main/java/datadog/trace/api/Config.java index 3d4dc949c9a..e77dd9dd6b8 100644 --- a/internal-api/src/main/java/datadog/trace/api/Config.java +++ b/internal-api/src/main/java/datadog/trace/api/Config.java @@ -237,6 +237,10 @@ public static String getHostName() { private final boolean traceGitMetadataEnabled; + private final boolean ssiInjectionForce; + private final String ssiInjectionEnabled; + private final String instrumentationSource; + private final Map traceSamplingServiceRules; private final Map traceSamplingOperationRules; private final String traceSamplingRules; @@ -2041,6 +2045,13 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment()) "AppSec SCA is enabled but telemetry is disabled. AppSec SCA will not work."); } + // Used to report telemetry on SSI injection + this.ssiInjectionEnabled = configProvider.getString(SSI_INJECTION_ENABLED); + this.ssiInjectionForce = + configProvider.getBoolean(SSI_INJECTION_FORCE, DEFAULT_SSI_INJECTION_FORCE); + this.instrumentationSource = + configProvider.getString(INSTRUMENTATION_SOURCE, DEFAULT_INSTRUMENTATION_SOURCE); + this.apmTracingEnabled = configProvider.getBoolean(GeneralConfig.APM_TRACING_ENABLED, true); this.jdkSocketEnabled = configProvider.getBoolean(JDK_SOCKET_ENABLED, true); diff --git a/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy index 1db85217521..75556772033 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy @@ -58,6 +58,9 @@ import static datadog.trace.api.config.GeneralConfig.SITE import static datadog.trace.api.config.GeneralConfig.TAGS import static datadog.trace.api.config.GeneralConfig.TRACER_METRICS_IGNORED_RESOURCES import static datadog.trace.api.config.GeneralConfig.VERSION +import static datadog.trace.api.config.GeneralConfig.SSI_INJECTION_ENABLED +import static datadog.trace.api.config.GeneralConfig.SSI_INJECTION_FORCE +import static datadog.trace.api.config.GeneralConfig.INSTRUMENTATION_SOURCE import static datadog.trace.api.config.JmxFetchConfig.JMX_FETCH_CHECK_PERIOD import static datadog.trace.api.config.JmxFetchConfig.JMX_FETCH_ENABLED import static datadog.trace.api.config.JmxFetchConfig.JMX_FETCH_METRICS_CONFIGS @@ -2597,6 +2600,35 @@ class ConfigTest extends DDSpecification { "450" | 450 } + def "ssi injection enabled"() { + when: + def prop = new Properties() + prop.setProperty(SSI_INJECTION_ENABLED, "tracer") + Config config = Config.get(prop) + + then: + config.ssiInjectionEnabled == "tracer" + } + + def "ssi inject force"() { + when: + def prop = new Properties() + prop.setProperty(SSI_INJECTION_FORCE, true) + Config config = Config.get(prop) + + then: + config.ssiInjectionForce == true + } + + def "instrumentation source"() { + when: + def prop = new Properties() + prop.setProperty(INSTRUMENTATION_SOURCE, "ssi") + + then: + config.instrumentationSource == "ssi" + } + def "long running trace invalid flush_interval set to default: #configuredFlushInterval"() { when: def prop = new Properties() From 1463cd91b526dc1ea483c0ff0ae8a2f78b8da3fd Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Thu, 12 Jun 2025 11:35:20 -0400 Subject: [PATCH 2/2] fix broken test --- .../src/test/groovy/datadog/trace/api/ConfigTest.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy index 75556772033..915b77c1a66 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy @@ -2613,7 +2613,7 @@ class ConfigTest extends DDSpecification { def "ssi inject force"() { when: def prop = new Properties() - prop.setProperty(SSI_INJECTION_FORCE, true) + prop.setProperty(SSI_INJECTION_FORCE, "true") Config config = Config.get(prop) then: @@ -2624,6 +2624,7 @@ class ConfigTest extends DDSpecification { when: def prop = new Properties() prop.setProperty(INSTRUMENTATION_SOURCE, "ssi") + Config config = Config.get(prop) then: config.instrumentationSource == "ssi"