Skip to content

Commit

Permalink
Add support for 'auto' value in DD_PROFILING_ENABLED (#7264)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbachorik committed Jul 2, 2024
1 parent 16dbb60 commit 2c9c668
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import datadog.trace.api.config.UsmConfig;
import datadog.trace.api.gateway.RequestContextSlot;
import datadog.trace.api.gateway.SubscriptionService;
import datadog.trace.api.profiling.ProfilingEnablement;
import datadog.trace.api.scopemanager.ScopeListener;
import datadog.trace.bootstrap.benchmark.StaticEventLogger;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
Expand Down Expand Up @@ -1124,6 +1125,11 @@ private static boolean isFeatureEnabled(AgentFeature feature) {
// true unless it's explicitly set to "false"
return !("false".equalsIgnoreCase(featureEnabled) || "0".equals(featureEnabled));
} else {
if (feature == AgentFeature.PROFILING) {
// We need this hack because profiling in SSI can receive 'auto' value in
// the enablement config
return ProfilingEnablement.of(featureEnabled).isActive();
}
// false unless it's explicitly set to "true"
return Boolean.parseBoolean(featureEnabled) || "1".equals(featureEnabled);
}
Expand Down
37 changes: 29 additions & 8 deletions internal-api/src/main/java/datadog/trace/api/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@
import datadog.trace.api.iast.IastDetectionMode;
import datadog.trace.api.iast.telemetry.Verbosity;
import datadog.trace.api.naming.SpanNaming;
import datadog.trace.api.profiling.ProfilingEnablement;
import datadog.trace.bootstrap.config.provider.CapturedEnvironmentConfigSource;
import datadog.trace.bootstrap.config.provider.ConfigProvider;
import datadog.trace.bootstrap.config.provider.SystemPropertiesConfigSource;
Expand Down Expand Up @@ -709,7 +710,7 @@ static class HostNameHolder {
private final String spanSamplingRules;
private final String spanSamplingRulesFile;

private final boolean profilingEnabled;
private final ProfilingEnablement profilingEnabled;
private final boolean profilingAgentless;
private final boolean isDatadogProfilerEnabled;
@Deprecated private final String profilingUrl;
Expand Down Expand Up @@ -1504,9 +1505,12 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins
// on whether
// the profiler was enabled at build time or not.
// Otherwise just do the standard config lookup by key.
// An extra step is needed to properly handle the 'auto' value for profiling enablement via SSI.
profilingEnabled =
configProvider.getBoolean(
ProfilingConfig.PROFILING_ENABLED, instrumenterConfig.isProfilingEnabled());
ProfilingEnablement.of(
configProvider.getString(
ProfilingConfig.PROFILING_ENABLED,
String.valueOf(instrumenterConfig.isProfilingEnabled())));
profilingAgentless =
configProvider.getBoolean(PROFILING_AGENTLESS, PROFILING_AGENTLESS_DEFAULT);
isDatadogProfilerEnabled =
Expand Down Expand Up @@ -1548,10 +1552,27 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
}

profilingTags = configProvider.getMergedMap(PROFILING_TAGS);
profilingStartDelay =
int profilingStartDelayValue =
configProvider.getInteger(PROFILING_START_DELAY, PROFILING_START_DELAY_DEFAULT);
profilingStartForceFirst =
boolean profilingStartForceFirstValue =
configProvider.getBoolean(PROFILING_START_FORCE_FIRST, PROFILING_START_FORCE_FIRST_DEFAULT);
if (profilingEnabled == ProfilingEnablement.AUTO) {
if (profilingStartDelayValue != PROFILING_START_DELAY_DEFAULT) {
log.info(
"Profiling start delay is set to {}s, but profiling enablement is set to auto. Using the default delay of {}s.",
profilingStartDelayValue,
PROFILING_START_DELAY_DEFAULT);
}
if (profilingStartForceFirstValue != PROFILING_START_FORCE_FIRST_DEFAULT) {
log.info(
"Profiling is requested to start immediately, but profiling enablement is set to auto. Profiling will be started with delay of {}s.",
PROFILING_START_DELAY_DEFAULT);
}
profilingStartDelayValue = PROFILING_START_DELAY_DEFAULT;
profilingStartForceFirstValue = PROFILING_START_FORCE_FIRST_DEFAULT;
}
profilingStartDelay = profilingStartDelayValue;
profilingStartForceFirst = profilingStartForceFirstValue;
profilingUploadPeriod =
configProvider.getInteger(PROFILING_UPLOAD_PERIOD, PROFILING_UPLOAD_PERIOD_DEFAULT);
profilingTemplateOverrideFile = configProvider.getString(PROFILING_TEMPLATE_OVERRIDE_FILE);
Expand Down Expand Up @@ -2664,14 +2685,14 @@ public String getSpanSamplingRulesFile() {

public boolean isProfilingEnabled() {
if (Platform.isNativeImage()) {
if (!instrumenterConfig.isProfilingEnabled() && profilingEnabled) {
if (!instrumenterConfig.isProfilingEnabled() && profilingEnabled.isActive()) {
log.warn(
"Profiling was not enabled during the native image build. "
+ "Please set DD_PROFILING_ENABLED=true in your native image build configuration if you want"
+ "to use profiling.");
}
}
return profilingEnabled && instrumenterConfig.isProfilingEnabled();
return profilingEnabled.isActive() && instrumenterConfig.isProfilingEnabled();
}

public boolean isProfilingTimelineEventsEnabled() {
Expand Down Expand Up @@ -2759,7 +2780,7 @@ public boolean isProfilingRecordExceptionMessage() {
}

public boolean isDatadogProfilerEnabled() {
return profilingEnabled && isDatadogProfilerEnabled;
return isProfilingEnabled() && isDatadogProfilerEnabled;
}

public static boolean isDatadogProfilerEnablementOverridden() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import static datadog.trace.util.CollectionUtils.tryMakeImmutableList;
import static datadog.trace.util.CollectionUtils.tryMakeImmutableSet;

import datadog.trace.api.profiling.ProfilingEnablement;
import datadog.trace.bootstrap.config.provider.ConfigProvider;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -103,7 +104,7 @@ public class InstrumenterConfig {
private final boolean traceEnabled;
private final boolean traceOtelEnabled;
private final boolean logs128bTraceIdEnabled;
private final boolean profilingEnabled;
private final ProfilingEnablement profilingEnabled;
private final boolean ciVisibilityEnabled;
private final ProductActivation appSecActivation;
private final ProductActivation iastActivation;
Expand Down Expand Up @@ -178,7 +179,9 @@ private InstrumenterConfig() {
logs128bTraceIdEnabled =
configProvider.getBoolean(
TRACE_128_BIT_TRACEID_LOGGING_ENABLED, DEFAULT_TRACE_128_BIT_TRACEID_LOGGING_ENABLED);
profilingEnabled = configProvider.getBoolean(PROFILING_ENABLED, PROFILING_ENABLED_DEFAULT);
profilingEnabled =
ProfilingEnablement.of(
configProvider.getString(PROFILING_ENABLED, String.valueOf(PROFILING_ENABLED_DEFAULT)));

if (!Platform.isNativeImageBuilder()) {
ciVisibilityEnabled =
Expand Down Expand Up @@ -301,7 +304,7 @@ public boolean isLogs128bTraceIdEnabled() {
}

public boolean isProfilingEnabled() {
return profilingEnabled;
return profilingEnabled.isActive();
}

public boolean isCiVisibilityEnabled() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package datadog.trace.api.profiling;

public enum ProfilingEnablement {
ENABLED(true),
DISABLED(false),
AUTO(true);

private final boolean active;

ProfilingEnablement(boolean active) {
this.active = active;
}

public boolean isActive() {
return active;
}

public static ProfilingEnablement of(String value) {
if (value == null) {
return DISABLED;
}
switch (value.toLowerCase()) {
case "true":
case "1":
return ENABLED;
case "auto":
return AUTO;
default:
return DISABLED;
}
}
}
25 changes: 25 additions & 0 deletions internal-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ import static datadog.trace.api.config.ProfilingConfig.PROFILING_PROXY_PASSWORD
import static datadog.trace.api.config.ProfilingConfig.PROFILING_PROXY_PORT
import static datadog.trace.api.config.ProfilingConfig.PROFILING_PROXY_USERNAME
import static datadog.trace.api.config.ProfilingConfig.PROFILING_START_DELAY
import static datadog.trace.api.config.ProfilingConfig.PROFILING_START_DELAY_DEFAULT
import static datadog.trace.api.config.ProfilingConfig.PROFILING_START_FORCE_FIRST
import static datadog.trace.api.config.ProfilingConfig.PROFILING_START_FORCE_FIRST_DEFAULT
import static datadog.trace.api.config.ProfilingConfig.PROFILING_TAGS
import static datadog.trace.api.config.ProfilingConfig.PROFILING_TEMPLATE_OVERRIDE_FILE
import static datadog.trace.api.config.ProfilingConfig.PROFILING_UPLOAD_COMPRESSION
Expand Down Expand Up @@ -2440,4 +2442,27 @@ class ConfigTest extends DDSpecification {
true | 11 | 11
false | 17 | 0
}

def "check profiling SSI auto-enablement"() {
when:
def prop = new Properties()
prop.setProperty(PROFILING_ENABLED, enablementMode)
prop.setProperty(PROFILING_START_DELAY, "1")
prop.setProperty(PROFILING_START_FORCE_FIRST, "true")

Config config = Config.get(prop)

then:
config.profilingEnabled == expectedEnabled
config.profilingStartDelay == expectedStartDelay
config.profilingStartForceFirst == expectedStartForceFirst

where:
// spotless:off
enablementMode | expectedEnabled | expectedStartDelay | expectedStartForceFirst
"true" | true | 1 | true
"false" | false | 1 | true
"auto" | true | PROFILING_START_DELAY_DEFAULT | PROFILING_START_FORCE_FIRST_DEFAULT
// spotless:on
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package datadog.trace.api.profiling;

import static org.junit.jupiter.api.Assertions.*;

import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class ProfilingEnablementTest {

@ParameterizedTest
@MethodSource("provideValues")
void of(String value, ProfilingEnablement expected) {
assertEquals(expected, ProfilingEnablement.of(value));
}

private static Stream<Arguments> provideValues() {
return Stream.of(
Arguments.of("true", ProfilingEnablement.ENABLED),
Arguments.of("TRUE", ProfilingEnablement.ENABLED),
Arguments.of("tRuE", ProfilingEnablement.ENABLED),
Arguments.of("1", ProfilingEnablement.ENABLED),
Arguments.of("auto", ProfilingEnablement.AUTO),
Arguments.of("AUTO", ProfilingEnablement.AUTO),
Arguments.of("aUtO", ProfilingEnablement.AUTO),
Arguments.of("false", ProfilingEnablement.DISABLED),
Arguments.of("FALSE", ProfilingEnablement.DISABLED),
Arguments.of("fAlSe", ProfilingEnablement.DISABLED),
Arguments.of("0", ProfilingEnablement.DISABLED),
Arguments.of("anything", ProfilingEnablement.DISABLED),
Arguments.of(null, ProfilingEnablement.DISABLED));
}
}

0 comments on commit 2c9c668

Please sign in to comment.