Skip to content

Commit 320e6cd

Browse files
authored
Merge branch 'master' into kr-igor/kafka-lag-spark-streaming
2 parents 4b6dc92 + 6025023 commit 320e6cd

File tree

86 files changed

+1861
-169
lines changed

Some content is hidden

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

86 files changed

+1861
-169
lines changed

.circleci/config.continue.yml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ instrumentation_modules: &instrumentation_modules "dd-java-agent/instrumentation
3636
debugger_modules: &debugger_modules "dd-java-agent/agent-debugger|dd-java-agent/agent-bootstrap|dd-java-agent/agent-builder|internal-api|communication|dd-trace-core"
3737
profiling_modules: &profiling_modules "dd-java-agent/agent-profiling"
3838

39-
default_system_tests_commit: &default_system_tests_commit 20b61e9be1e8c922804f8e5ddc80ba4a1f4cdd5b
39+
default_system_tests_commit: &default_system_tests_commit 1c9542783eedfed1b995d976963fbeb14ba772b9
4040

4141
parameters:
4242
nightly:

.github/CODEOWNERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ dd-java-agent/instrumentation/karate/ @DataDog/ci-app-libraries-java
2626
dd-java-agent/instrumentation/scalatest/ @DataDog/ci-app-libraries-java
2727
dd-java-agent/instrumentation/selenium/ @DataDog/ci-app-libraries-java
2828
dd-java-agent/instrumentation/testng/ @DataDog/ci-app-libraries-java
29-
dd-java-agent/instrumentation/gradle/ @DataDog/ci-app-libraries-java
29+
dd-java-agent/instrumentation/gradle-3.0/ @DataDog/ci-app-libraries-java
30+
dd-java-agent/instrumentation/gradle-8.3/ @DataDog/ci-app-libraries-java
3031
dd-java-agent/instrumentation/maven-3.2.1/ @DataDog/ci-app-libraries-java
3132
dd-smoke-tests/gradle/ @DataDog/ci-app-libraries-java
3233
dd-smoke-tests/maven/ @DataDog/ci-app-libraries-java

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/utils/ProcessHierarchyUtils.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ private static boolean isMavenParent() {
3838
}
3939

4040
private static boolean isGradleDaemon() {
41-
return ClassLoader.getSystemClassLoader().getResource("org/gradle/launcher/daemon/") != null;
41+
return ClassLoader.getSystemClassLoader()
42+
.getResource("org/gradle/launcher/daemon/bootstrap/GradleDaemon.class")
43+
!= null
44+
// double-check this is not a Gradle Worker
45+
&& System.getProperties().getProperty("org.gradle.internal.worker.tmpdir") == null;
4246
}
4347

4448
public static long getParentSessionId() {

dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/Redaction.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,15 @@ public class Redaction {
110110
private static List<String> redactedPackages;
111111

112112
static {
113+
initKeywords();
114+
}
115+
116+
static void initKeywords() {
113117
/*
114118
* based on sentry list: https://github.com/getsentry/sentry-python/blob/fefb454287b771ac31db4e30fa459d9be2f977b8/sentry_sdk/scrubber.py#L17-L58
115119
*/
116120
KEYWORDS.addAll(PREDEFINED_KEYWORDS);
121+
KEYWORDS.removeAll(Config.get().getDebuggerRedactionExcludedIdentifiers());
117122
}
118123

119124
public static void addUserDefinedKeywords(Config config) {

dd-java-agent/agent-debugger/debugger-bootstrap/src/test/java/datadog/trace/bootstrap/debugger/util/RedactionTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
import datadog.trace.api.Config;
66
import java.lang.reflect.Field;
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.HashSet;
710
import org.junit.jupiter.api.Test;
811

912
class RedactionTest {
@@ -48,6 +51,20 @@ public void userDefinedTypes() {
4851
}
4952
}
5053

54+
@Test
55+
public void exclusions() {
56+
Config config = Config.get();
57+
setFieldInConfig(
58+
config, "debuggerRedactionExcludedIdentifiers", new HashSet<>(Arrays.asList("password")));
59+
Redaction.initKeywords();
60+
try {
61+
assertFalse(Redaction.isRedactedKeyword("password"));
62+
} finally {
63+
setFieldInConfig(config, "debuggerRedactionExcludedIdentifiers", Collections.emptySet());
64+
Redaction.initKeywords();
65+
}
66+
}
67+
5168
private static void setFieldInConfig(Config config, String fieldName, Object value) {
5269
try {
5370
Field field = config.getClass().getDeclaredField(fieldName);

dd-java-agent/agent-debugger/debugger-el/src/main/java/com/datadog/debugger/el/expressions/ComparisonOperator.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,52 @@ public Boolean apply(Value<?> left, Value<?> right) {
2121
}
2222
return compare(leftNumber, rightNumber) == 0;
2323
}
24+
if (left.getValue() instanceof Enum || right.getValue() instanceof Enum) {
25+
return applyEqualityForEnum(left, right);
26+
}
2427
if (left.getValue().getClass() == right.getValue().getClass()) {
2528
return Objects.equals(left.getValue(), right.getValue());
2629
}
2730
return Boolean.FALSE;
2831
}
32+
33+
private Boolean applyEqualityForEnum(Value<?> left, Value<?> right) {
34+
if (left.getValue() instanceof Enum && right instanceof StringValue) {
35+
return doApplyEqualityForEnum(left, right);
36+
}
37+
if (left instanceof StringValue && right.getValue() instanceof Enum) {
38+
return doApplyEqualityForEnum(right, left);
39+
}
40+
throw new EvaluationException(
41+
"Equality operator is not supported for the given types: "
42+
+ left.getValue().getClass().getName()
43+
+ " and "
44+
+ right.getValue().getClass().getName(),
45+
null);
46+
}
47+
48+
private Boolean doApplyEqualityForEnum(Value<?> enumExpr, Value<?> enumValueExpr) {
49+
Enum<?> enumValue = (Enum<?>) enumExpr.getValue();
50+
String enumValueStr = (String) enumValueExpr.getValue();
51+
Class<? extends Enum> enumClass = enumValue.getClass();
52+
Enum[] enumConstants = enumClass.getEnumConstants();
53+
for (Enum<?> enumConstant : enumConstants) {
54+
// Check if string constant as value expression matches for enum constant
55+
// the endsWith allow to match either:
56+
// - the full enum constant name (com.datadog.debugger.MyEnum.ONE)
57+
// - the simple name with enum class name (MyEnum.ONE)
58+
// - the simple name (ONE)
59+
// The second check against enumValue is to ensure the instance filtered based on the
60+
// name is still correct because the name can partially match (CLOSE in OPENCLOSE)
61+
// with an enum defined like (OPEN, CLOSE, OPENCLOSE)
62+
if (enumValueStr.endsWith(enumConstant.name())) {
63+
if (enumValue.equals(enumConstant)) {
64+
return Boolean.TRUE;
65+
}
66+
}
67+
}
68+
return Boolean.FALSE;
69+
}
2970
},
3071
GE(">=") {
3172
@Override

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/expressions/ComparisonExpressionTest.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.datadog.debugger.el.values.StringValue;
1717
import datadog.trace.bootstrap.debugger.el.ValueReferenceResolver;
1818
import java.math.BigDecimal;
19+
import java.nio.file.StandardOpenOption;
1920
import java.util.ArrayList;
2021
import java.util.Random;
2122
import java.util.stream.Stream;
@@ -164,7 +165,37 @@ private static Stream<Arguments> expressions() {
164165
new StringValue("java.lang.Double"),
165166
INSTANCEOF,
166167
true,
167-
"1.0 instanceof \"java.lang.Double\""));
168+
"1.0 instanceof \"java.lang.Double\""),
169+
Arguments.of(
170+
new ObjectValue(StandardOpenOption.READ),
171+
new StringValue("READ"),
172+
EQ,
173+
true,
174+
"java.nio.file.StandardOpenOption == \"READ\""),
175+
Arguments.of(
176+
new ObjectValue(StandardOpenOption.READ),
177+
new StringValue("StandardOpenOption.READ"),
178+
EQ,
179+
true,
180+
"java.nio.file.StandardOpenOption == \"StandardOpenOption.READ\""),
181+
Arguments.of(
182+
new ObjectValue(StandardOpenOption.READ),
183+
new StringValue("java.nio.file.StandardOpenOption.READ"),
184+
EQ,
185+
true,
186+
"java.nio.file.StandardOpenOption == \"java.nio.file.StandardOpenOption.READ\""),
187+
Arguments.of(
188+
new ObjectValue(StandardOpenOption.CREATE),
189+
new StringValue("READ"),
190+
EQ,
191+
false,
192+
"java.nio.file.StandardOpenOption == \"READ\""),
193+
Arguments.of(
194+
new StringValue("READ"),
195+
new ObjectValue(StandardOpenOption.READ),
196+
EQ,
197+
true,
198+
"\"READ\" == java.nio.file.StandardOpenOption"));
168199
}
169200

170201
@ParameterizedTest

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,6 @@ public void commit(CapturedContext lineContext, int line) {
553553
if (status.shouldSend()) {
554554
snapshot.setTraceId(lineContext.getTraceId());
555555
snapshot.setSpanId(lineContext.getSpanId());
556-
if (isCaptureSnapshot()) {
557-
snapshot.addLine(lineContext, line);
558-
}
559556
snapshot.setMessage(status.getMessage());
560557
shouldCommit = true;
561558
}
@@ -564,9 +561,12 @@ public void commit(CapturedContext lineContext, int line) {
564561
shouldCommit = true;
565562
}
566563
if (shouldCommit) {
567-
// freeze context just before commit because line probes have only one context
568-
Duration timeout = Duration.of(Config.get().getDebuggerCaptureTimeout(), ChronoUnit.MILLIS);
569-
lineContext.freeze(new TimeoutChecker(timeout));
564+
if (isCaptureSnapshot()) {
565+
// freeze context just before commit because line probes have only one context
566+
Duration timeout = Duration.of(Config.get().getDebuggerCaptureTimeout(), ChronoUnit.MILLIS);
567+
lineContext.freeze(new TimeoutChecker(timeout));
568+
snapshot.addLine(lineContext, line);
569+
}
570570
commitSnapshot(snapshot, sink);
571571
return;
572572
}

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/SymbolSink.java

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
import com.datadog.debugger.symbol.Scope;
44
import com.datadog.debugger.symbol.ServiceVersion;
55
import com.datadog.debugger.uploader.BatchUploader;
6-
import com.datadog.debugger.util.ExceptionHelper;
76
import com.datadog.debugger.util.MoshiHelper;
87
import com.squareup.moshi.JsonAdapter;
98
import datadog.trace.api.Config;
109
import datadog.trace.util.TagsHelper;
1110
import java.nio.charset.StandardCharsets;
1211
import java.util.ArrayList;
13-
import java.util.Collections;
1412
import java.util.List;
1513
import java.util.concurrent.ArrayBlockingQueue;
1614
import java.util.concurrent.BlockingQueue;
@@ -21,7 +19,7 @@
2119
public class SymbolSink {
2220

2321
private static final Logger LOGGER = LoggerFactory.getLogger(SymbolSink.class);
24-
private static final int CAPACITY = 1024;
22+
static final int CAPACITY = 1024;
2523
private static final JsonAdapter<ServiceVersion> SERVICE_VERSION_ADAPTER =
2624
MoshiHelper.createMoshiSymbol().adapter(ServiceVersion.class);
2725
private static final String EVENT_FORMAT =
@@ -36,7 +34,7 @@ public class SymbolSink {
3634
private final String version;
3735
private final BatchUploader symbolUploader;
3836
private final BatchUploader.MultiPartContent event;
39-
private final BlockingQueue<ServiceVersion> scopes = new ArrayBlockingQueue<>(CAPACITY);
37+
private final BlockingQueue<Scope> scopes = new ArrayBlockingQueue<>(CAPACITY);
4038
private final Stats stats = new Stats();
4139

4240
public SymbolSink(Config config) {
@@ -59,37 +57,47 @@ public void stop() {
5957
symbolUploader.shutdown();
6058
}
6159

62-
public boolean addScope(Scope jarScope) {
63-
ServiceVersion serviceVersion =
64-
new ServiceVersion(serviceName, env, version, "JAVA", Collections.singletonList(jarScope));
65-
return scopes.offer(serviceVersion);
60+
public void addScope(Scope jarScope) {
61+
boolean added = scopes.offer(jarScope);
62+
int retries = 10;
63+
while (!added) {
64+
// Q is full, flushing synchronously
65+
flush();
66+
added = scopes.offer(jarScope);
67+
retries--;
68+
if (retries < 0) {
69+
throw new IllegalStateException("Scope cannot be enqueued after 10 retries" + jarScope);
70+
}
71+
}
6672
}
6773

6874
public void flush() {
6975
if (scopes.isEmpty()) {
7076
return;
7177
}
72-
List<ServiceVersion> scopesToSerialize = new ArrayList<>();
78+
List<Scope> scopesToSerialize = new ArrayList<>();
79+
// ArrayBlockingQueue makes drainTo atomic, so it is safe to call flush from different and
80+
// concurrent threads
7381
scopes.drainTo(scopesToSerialize);
74-
LOGGER.debug("Sending {} scopes", scopesToSerialize.size());
75-
for (ServiceVersion serviceVersion : scopesToSerialize) {
76-
try {
77-
String json = SERVICE_VERSION_ADAPTER.toJson(serviceVersion);
78-
LOGGER.debug(
79-
"Sending scope: {}, size={}",
80-
serviceVersion.getScopes().get(0).getName(),
81-
json.length());
82-
List<Scope> classScopes = serviceVersion.getScopes().get(0).getScopes();
83-
int classScopeCount = classScopes != null ? classScopes.size() : 0;
84-
stats.updateStats(classScopeCount, json.length());
85-
symbolUploader.uploadAsMultipart(
86-
"",
87-
event,
88-
new BatchUploader.MultiPartContent(
89-
json.getBytes(StandardCharsets.UTF_8), "file", "file.json"));
90-
} catch (Exception e) {
91-
ExceptionHelper.logException(LOGGER, e, "Error during scope serialization:");
92-
}
82+
// concurrent calls to flush can result in empty scope to send, we don't want to send empty
83+
if (scopesToSerialize.isEmpty()) {
84+
return;
85+
}
86+
String json =
87+
SERVICE_VERSION_ADAPTER.toJson(
88+
new ServiceVersion(serviceName, env, version, "JAVA", scopesToSerialize));
89+
LOGGER.debug("Sending {} jar scopes size={}", scopesToSerialize.size(), json.length());
90+
updateStats(scopesToSerialize, json);
91+
symbolUploader.uploadAsMultipart(
92+
"",
93+
event,
94+
new BatchUploader.MultiPartContent(
95+
json.getBytes(StandardCharsets.UTF_8), "file", "file.json"));
96+
}
97+
98+
private void updateStats(List<Scope> scopesToSerialize, String json) {
99+
for (Scope scope : scopesToSerialize) {
100+
stats.updateStats(scope.getScopes() != null ? scope.getScopes().size() : 0, json.length());
93101
}
94102
}
95103

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/uploader/BatchUploader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ private void doUpload(Runnable makeRequest) {
174174
debuggerMetrics.count("batch.uploaded", 1);
175175
} else {
176176
debuggerMetrics.count("request.queue.full", 1);
177-
log.warn("Cannot upload batch data: too many enqueued requests!");
177+
ratelimitedLogger.warn(
178+
"Cannot upload batch data to {}: too many enqueued requests!", urlBase);
178179
}
179180
} catch (Exception ex) {
180181
debuggerMetrics.count("batch.upload.error", 1);

0 commit comments

Comments
 (0)