Skip to content

Commit a795550

Browse files
authored
Emit recording setting events for SSI details (#7507)
1 parent ec821c1 commit a795550

File tree

7 files changed

+209
-10
lines changed

7 files changed

+209
-10
lines changed

dd-java-agent/agent-profiling/profiling-controller-ddprof/src/main/java/com/datadog/profiling/controller/ddprof/DatadogProfilerSettings.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@ public void publish() {
3535
if (serviceInjection != null) {
3636
datadogProfiler.recordSetting(SERVICE_INJECTION, serviceInjection);
3737
}
38+
datadogProfiler.recordSetting(
39+
PROFILER_ACTIVATION, profilerActivationSetting.enablement.getAlias());
40+
datadogProfiler.recordSetting(
41+
SSI_MECHANISM, profilerActivationSetting.ssiMechanism.name().toLowerCase());
3842
}
3943
}

dd-java-agent/agent-profiling/profiling-controller-openjdk/src/main/java/com/datadog/profiling/controller/openjdk/JfrProfilerSettings.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ public void publish() {
6868
if (serviceInjection != null) {
6969
new ProfilerSettingEvent(SERVICE_INJECTION, serviceInjection).commit();
7070
}
71+
new ProfilerSettingEvent(PROFILER_ACTIVATION, profilerActivationSetting.enablement.getAlias())
72+
.commit();
73+
new ProfilerSettingEvent(
74+
SSI_MECHANISM, profilerActivationSetting.ssiMechanism.name().toLowerCase())
75+
.commit();
7176
}
7277
}
7378
}

dd-java-agent/agent-profiling/profiling-controller/src/main/java/com/datadog/profiling/controller/ProfilerSettingsSupport.java

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import datadog.trace.api.Config;
44
import datadog.trace.api.Platform;
55
import datadog.trace.api.config.ProfilingConfig;
6+
import datadog.trace.api.profiling.ProfilingEnablement;
67
import datadog.trace.bootstrap.config.provider.ConfigProvider;
78
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
89
import datadog.trace.context.TraceScope;
@@ -13,10 +14,49 @@
1314
import java.nio.file.Files;
1415
import java.nio.file.Path;
1516
import java.nio.file.Paths;
17+
import java.util.Objects;
1618
import java.util.concurrent.TimeUnit;
1719

1820
/** Capture the profiler config first and allow emitting the setting events per each recording. */
1921
public abstract class ProfilerSettingsSupport {
22+
protected static final class ProfilerActivationSetting {
23+
public enum Ssi {
24+
INJECTED_AGENT,
25+
NONE
26+
}
27+
28+
public final ProfilingEnablement enablement;
29+
public final Ssi ssiMechanism;
30+
31+
public ProfilerActivationSetting(ProfilingEnablement enablement, Ssi ssiMechanism) {
32+
this.enablement = enablement;
33+
this.ssiMechanism = ssiMechanism;
34+
}
35+
36+
@Override
37+
public boolean equals(Object o) {
38+
if (this == o) return true;
39+
if (o == null || getClass() != o.getClass()) return false;
40+
ProfilerActivationSetting that = (ProfilerActivationSetting) o;
41+
return enablement == that.enablement && ssiMechanism == that.ssiMechanism;
42+
}
43+
44+
@Override
45+
public int hashCode() {
46+
return Objects.hash(enablement, ssiMechanism);
47+
}
48+
49+
@Override
50+
public String toString() {
51+
return "ProfilerActivationSetting{"
52+
+ "enablement="
53+
+ enablement
54+
+ ", ssiMechanism="
55+
+ ssiMechanism
56+
+ '}';
57+
}
58+
}
59+
2060
protected static final String JFR_IMPLEMENTATION_KEY = "JFR Implementation";
2161
protected static final String UPLOAD_PERIOD_KEY = "Upload Period";
2262
protected static final String UPLOAD_TIMEOUT_KEY = "Upload Timeout";
@@ -31,11 +71,14 @@ public abstract class ProfilerSettingsSupport {
3171
protected static final String NATIVE_STACKS_KEY = "Native Stacks";
3272
protected static final String STACK_DEPTH_KEY = "Stack Depth";
3373
protected static final String SELINUX_STATUS_KEY = "SELinux Status";
34-
protected static final String SERVICE_INSTRUMENTATION_TYPE = "Service Instrumentation Type";
35-
protected static final String SERVICE_INJECTION = "Service Injection";
3674

3775
protected static final String DDPROF_UNAVAILABLE_REASON_KEY = "DDProf Unavailable Reason";
3876

77+
protected static final String SERVICE_INSTRUMENTATION_TYPE = "Service Instrumentation Type";
78+
protected static final String SERVICE_INJECTION = "Service Injection";
79+
protected static final String PROFILER_ACTIVATION = "Profiler Activation";
80+
protected static final String SSI_MECHANISM = "SSI Mechanism";
81+
3982
protected final int uploadPeriod;
4083
protected final int uploadTimeout;
4184
protected final String uploadCompression;
@@ -57,6 +100,8 @@ public abstract class ProfilerSettingsSupport {
57100

58101
protected final String ddprofUnavailableReason;
59102

103+
protected final ProfilerActivationSetting profilerActivationSetting;
104+
60105
protected final int stackDepth;
61106
protected final boolean hasJfrStackDepthApplied;
62107

@@ -127,12 +172,24 @@ protected ProfilerSettingsSupport(
127172
this.ddprofUnavailableReason = ddprofUnavailableReason;
128173
this.hasJfrStackDepthApplied = hasJfrStackDepthApplied;
129174

130-
serviceInjection =
131-
configProvider.getString(
132-
"injection.enabled"); // usually set via DD_INJECTION_ENABLED env var
175+
serviceInjection = getServiceInjection(configProvider);
133176
serviceInstrumentationType =
134177
// usually set via DD_INSTRUMENTATION_INSTALL_TYPE env var
135178
configProvider.getString("instrumentation.install.type");
179+
this.profilerActivationSetting = getProfilerActivation(configProvider);
180+
}
181+
182+
private static String getServiceInjection(ConfigProvider configProvider) {
183+
// usually set via DD_INJECTION_ENABLED env var
184+
return configProvider.getString("injection.enabled");
185+
}
186+
187+
static ProfilerActivationSetting getProfilerActivation(ConfigProvider configProvider) {
188+
return new ProfilerActivationSetting(
189+
ProfilingEnablement.from(configProvider),
190+
getServiceInjection(configProvider) != null
191+
? ProfilerActivationSetting.Ssi.INJECTED_AGENT
192+
: ProfilerActivationSetting.Ssi.NONE);
136193
}
137194

138195
private String getSELinuxStatus() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.datadog.profiling.controller;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import com.datadog.profiling.controller.ProfilerSettingsSupport.ProfilerActivationSetting;
6+
import com.datadog.profiling.controller.ProfilerSettingsSupport.ProfilerActivationSetting.Ssi;
7+
import datadog.trace.api.config.ProfilingConfig;
8+
import datadog.trace.api.profiling.ProfilingEnablement;
9+
import datadog.trace.bootstrap.config.provider.ConfigProvider;
10+
import java.util.Properties;
11+
import java.util.stream.Stream;
12+
import org.junit.jupiter.params.ParameterizedTest;
13+
import org.junit.jupiter.params.provider.Arguments;
14+
import org.junit.jupiter.params.provider.MethodSource;
15+
16+
public class ProfilerSettingsSupportTest {
17+
@ParameterizedTest
18+
@MethodSource("activationSettings")
19+
void testActivation(
20+
String enabledSetting, String injectSetting, ProfilerActivationSetting expected) {
21+
Properties props = new Properties();
22+
if (enabledSetting != null) {
23+
props.put(ProfilingConfig.PROFILING_ENABLED, enabledSetting);
24+
}
25+
if (injectSetting != null) {
26+
props.put("injection.enabled", injectSetting);
27+
}
28+
ConfigProvider configProvider = ConfigProvider.withPropertiesOverride(props);
29+
30+
ProfilerActivationSetting setting =
31+
ProfilerSettingsSupport.getProfilerActivation(configProvider);
32+
assertEquals(expected, setting);
33+
}
34+
35+
private static Stream<Arguments> activationSettings() {
36+
return Stream.of(
37+
Arguments.of(
38+
"true", null, new ProfilerActivationSetting(ProfilingEnablement.ENABLED, Ssi.NONE)),
39+
Arguments.of(
40+
"true",
41+
"tracer",
42+
new ProfilerActivationSetting(ProfilingEnablement.ENABLED, Ssi.INJECTED_AGENT)),
43+
Arguments.of(
44+
"auto", null, new ProfilerActivationSetting(ProfilingEnablement.AUTO, Ssi.NONE)),
45+
Arguments.of(
46+
"auto",
47+
"tracer",
48+
new ProfilerActivationSetting(ProfilingEnablement.AUTO, Ssi.INJECTED_AGENT)),
49+
Arguments.of(
50+
null,
51+
"profiler,tracer",
52+
new ProfilerActivationSetting(ProfilingEnablement.INJECTED, Ssi.INJECTED_AGENT)),
53+
Arguments.of(
54+
"true",
55+
"profiler,tracer",
56+
new ProfilerActivationSetting(ProfilingEnablement.ENABLED, Ssi.INJECTED_AGENT)),
57+
Arguments.of(
58+
"auto",
59+
"profiler,tracer",
60+
new ProfilerActivationSetting(ProfilingEnablement.AUTO, Ssi.INJECTED_AGENT)));
61+
}
62+
}

internal-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,8 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
15751575
configProvider.getInteger(PROFILING_START_DELAY, PROFILING_START_DELAY_DEFAULT);
15761576
boolean profilingStartForceFirstValue =
15771577
configProvider.getBoolean(PROFILING_START_FORCE_FIRST, PROFILING_START_FORCE_FIRST_DEFAULT);
1578-
if (profilingEnabled == ProfilingEnablement.AUTO) {
1578+
if (profilingEnabled == ProfilingEnablement.AUTO
1579+
|| profilingEnabled == ProfilingEnablement.INJECTED) {
15791580
if (profilingStartDelayValue != PROFILING_START_DELAY_DEFAULT) {
15801581
log.info(
15811582
"Profiling start delay is set to {}s, but profiling enablement is set to auto. Using the default delay of {}s.",

internal-api/src/main/java/datadog/trace/api/profiling/ProfilingEnablement.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,52 @@
11
package datadog.trace.api.profiling;
22

3+
import datadog.trace.api.config.ProfilingConfig;
4+
import datadog.trace.bootstrap.config.provider.ConfigProvider;
35
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
57

68
public enum ProfilingEnablement {
7-
ENABLED(true),
9+
ENABLED(true, "manual"),
810
DISABLED(false),
9-
AUTO(true);
11+
AUTO(true),
12+
INJECTED(true);
1013

1114
private static final Logger logger = LoggerFactory.getLogger(Profiling.class);
1215

1316
private final boolean active;
17+
private final String alias;
1418

1519
ProfilingEnablement(boolean active) {
1620
this.active = active;
21+
this.alias = this.name().toLowerCase();
22+
}
23+
24+
ProfilingEnablement(boolean active, String alias) {
25+
this.active = active;
26+
this.alias = alias;
1727
}
1828

1929
public boolean isActive() {
2030
return active;
2131
}
2232

33+
public String getAlias() {
34+
return alias;
35+
}
36+
37+
public static ProfilingEnablement from(ConfigProvider config) {
38+
ProfilingEnablement ret = ProfilingEnablement.DISABLED;
39+
String value = config.getString(ProfilingConfig.PROFILING_ENABLED);
40+
if (value != null) {
41+
ret = of(value);
42+
}
43+
if (ret == DISABLED) {
44+
String ssi = config.getString("injection.enabled");
45+
ret = ssi != null && ssi.contains("profiler") ? INJECTED : DISABLED;
46+
}
47+
return ret;
48+
}
49+
2350
public static ProfilingEnablement of(String value) {
2451
if (value == null) {
2552
return DISABLED;

internal-api/src/test/java/datadog/trace/api/profiling/ProfilingEnablementTest.java

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

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

5+
import datadog.trace.api.config.ProfilingConfig;
6+
import datadog.trace.bootstrap.config.provider.ConfigProvider;
7+
import java.util.Properties;
58
import java.util.stream.Stream;
69
import org.junit.jupiter.params.ParameterizedTest;
710
import org.junit.jupiter.params.provider.Arguments;
@@ -11,8 +14,23 @@ class ProfilingEnablementTest {
1114

1215
@ParameterizedTest
1316
@MethodSource("provideValues")
14-
void of(String value, ProfilingEnablement expected) {
15-
assertEquals(expected, ProfilingEnablement.of(value));
17+
void of(String enabledValue, ProfilingEnablement expected) {
18+
ProfilingEnablement.validate(enabledValue); // make jacoco happy
19+
assertEquals(expected, ProfilingEnablement.of(enabledValue));
20+
}
21+
22+
@ParameterizedTest
23+
@MethodSource("provideValues1")
24+
void from(String enabledValue, String ssi, ProfilingEnablement expected) {
25+
Properties props = new Properties();
26+
if (enabledValue != null) {
27+
props.setProperty(ProfilingConfig.PROFILING_ENABLED, enabledValue);
28+
}
29+
if (ssi != null) {
30+
props.setProperty("injection.enabled", ssi);
31+
}
32+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
33+
assertEquals(expected, ProfilingEnablement.from(config));
1634
}
1735

1836
private static Stream<Arguments> provideValues() {
@@ -31,4 +49,29 @@ private static Stream<Arguments> provideValues() {
3149
Arguments.of("anything", ProfilingEnablement.DISABLED),
3250
Arguments.of(null, ProfilingEnablement.DISABLED));
3351
}
52+
53+
private static Stream<Arguments> provideValues1() {
54+
return Stream.of(
55+
Arguments.of("true", null, ProfilingEnablement.ENABLED),
56+
Arguments.of("true", "tracer", ProfilingEnablement.ENABLED),
57+
Arguments.of("true", "tracer,profiler", ProfilingEnablement.ENABLED),
58+
Arguments.of("1", null, ProfilingEnablement.ENABLED),
59+
Arguments.of("1", "tracer", ProfilingEnablement.ENABLED),
60+
Arguments.of("1", "tracer,profiler", ProfilingEnablement.ENABLED),
61+
Arguments.of("auto", null, ProfilingEnablement.AUTO),
62+
Arguments.of("auto", "tracer", ProfilingEnablement.AUTO),
63+
Arguments.of("auto", "tracer,profiler", ProfilingEnablement.AUTO),
64+
Arguments.of("false", null, ProfilingEnablement.DISABLED),
65+
Arguments.of("false", "tracer", ProfilingEnablement.DISABLED),
66+
Arguments.of("false", "tracer,profiler", ProfilingEnablement.INJECTED),
67+
Arguments.of("0", null, ProfilingEnablement.DISABLED),
68+
Arguments.of("0", "tracer", ProfilingEnablement.DISABLED),
69+
Arguments.of("0", "tracer,profiler", ProfilingEnablement.INJECTED),
70+
Arguments.of("anything", null, ProfilingEnablement.DISABLED),
71+
Arguments.of("anything", "tracer", ProfilingEnablement.DISABLED),
72+
Arguments.of("anything", "tracer,profiler", ProfilingEnablement.INJECTED),
73+
Arguments.of(null, null, ProfilingEnablement.DISABLED),
74+
Arguments.of(null, "tracer", ProfilingEnablement.DISABLED),
75+
Arguments.of(null, "tracer,profiler", ProfilingEnablement.INJECTED));
76+
}
3477
}

0 commit comments

Comments
 (0)