Skip to content

Commit a41d151

Browse files
authored
Add SymDB report for any jar scanning failures (#8300)
Any bail out when resolving or scanning for jars will be reported into SymDBReport and logged as a single INFO log line at the end of SYMDB extraction process from SymDB enablement
1 parent e078e8a commit a41d151

File tree

5 files changed

+70
-11
lines changed

5 files changed

+70
-11
lines changed

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/symbol/JarScanner.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ public class JarScanner {
1919
private static final String SPRING_CLASSES_PREFIX = "BOOT-INF/classes/";
2020
private static final String SPRING_DEPS_PREFIX = "BOOT-INF/lib/";
2121

22-
public static Path extractJarPath(Class<?> clazz) throws URISyntaxException {
23-
return extractJarPath(clazz.getProtectionDomain());
22+
public static Path extractJarPath(Class<?> clazz, SymDBReport symDBReport)
23+
throws URISyntaxException {
24+
return extractJarPath(clazz.getProtectionDomain(), symDBReport);
2425
}
2526

26-
public static Path extractJarPath(ProtectionDomain protectionDomain) throws URISyntaxException {
27+
public static Path extractJarPath(ProtectionDomain protectionDomain, SymDBReport symDBReport) {
2728
if (protectionDomain == null) {
2829
return null;
2930
}
@@ -50,6 +51,9 @@ public static Path extractJarPath(ProtectionDomain protectionDomain) throws URIS
5051
} else if (locationStr.startsWith(FILE_PREFIX)) {
5152
return getPathFromPrefixedFileName(locationStr, FILE_PREFIX, locationStr.length());
5253
}
54+
if (symDBReport != null) {
55+
symDBReport.addLocationError(locationStr);
56+
}
5357
return null;
5458
}
5559

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/symbol/SymDBEnablement.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ public void startSymbolExtraction() {
119119
symbolExtractionTransformer =
120120
new SymbolExtractionTransformer(symbolAggregator, classNameFilter);
121121
instrumentation.addTransformer(symbolExtractionTransformer);
122-
extractSymbolForLoadedClasses();
122+
SymDBReport symDBReport = new SymDBReport();
123+
extractSymbolForLoadedClasses(symDBReport);
124+
symDBReport.report();
123125
lastUploadTimestamp = System.currentTimeMillis();
124126
} catch (Throwable ex) {
125127
// catch all Throwables because LinkageError is possible (duplicate class definition)
@@ -130,7 +132,7 @@ public void startSymbolExtraction() {
130132
}
131133
}
132134

133-
private void extractSymbolForLoadedClasses() {
135+
private void extractSymbolForLoadedClasses(SymDBReport symDBReport) {
134136
Class<?>[] classesToExtract;
135137
try {
136138
classesToExtract =
@@ -148,19 +150,21 @@ private void extractSymbolForLoadedClasses() {
148150
for (Class<?> clazz : classesToExtract) {
149151
Path jarPath;
150152
try {
151-
jarPath = JarScanner.extractJarPath(clazz);
153+
jarPath = JarScanner.extractJarPath(clazz, symDBReport);
152154
} catch (URISyntaxException e) {
153155
throw new RuntimeException(e);
154156
}
155157
if (jarPath == null) {
156158
continue;
157159
}
158160
if (!Files.exists(jarPath)) {
161+
symDBReport.addMissingJar(jarPath.toString());
159162
continue;
160163
}
161164
File jarPathFile = jarPath.toFile();
162165
if (jarPathFile.isDirectory()) {
163166
// we are not supporting class directories (classpath) but only jar files
167+
symDBReport.addDirectoryJar(jarPath.toString());
164168
continue;
165169
}
166170
if (alreadyScannedJars.contains(jarPath.toString())) {
@@ -178,6 +182,7 @@ private void extractSymbolForLoadedClasses() {
178182
}
179183
alreadyScannedJars.add(jarPath.toString());
180184
} catch (IOException e) {
185+
symDBReport.addIOException(jarPath.toString(), e);
181186
throw new RuntimeException(e);
182187
}
183188
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.datadog.debugger.symbol;
2+
3+
import java.io.IOException;
4+
import java.util.ArrayList;
5+
import java.util.HashMap;
6+
import java.util.HashSet;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
13+
public class SymDBReport {
14+
private static final Logger LOGGER = LoggerFactory.getLogger(SymDBReport.class);
15+
16+
private final Set<String> missingJars = new HashSet<>();
17+
private final Set<String> directoryJars = new HashSet<>();
18+
private final Map<String, String> ioExceptions = new HashMap<>();
19+
private final List<String> locationErrors = new ArrayList<>();
20+
21+
public void addMissingJar(String jarPath) {
22+
missingJars.add(jarPath);
23+
}
24+
25+
public void addDirectoryJar(String jarPath) {
26+
directoryJars.add(jarPath);
27+
}
28+
29+
public void addIOException(String jarPath, IOException e) {
30+
ioExceptions.put(jarPath, e.toString());
31+
}
32+
33+
public void addLocationError(String locationStr) {
34+
locationErrors.add(locationStr);
35+
}
36+
37+
public void report() {
38+
String content =
39+
"== SymDB Report == Location errors:"
40+
+ locationErrors
41+
+ " Missing jars: "
42+
+ missingJars
43+
+ " Directory jars: "
44+
+ directoryJars
45+
+ " IOExceptions: "
46+
+ ioExceptions;
47+
LOGGER.info(content);
48+
}
49+
}

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/symbol/SymbolAggregator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public void parseClass(
4343
String className, byte[] classfileBuffer, ProtectionDomain protectionDomain) {
4444
try {
4545
String jarName = "DEFAULT";
46-
Path jarPath = JarScanner.extractJarPath(protectionDomain);
46+
Path jarPath = JarScanner.extractJarPath(protectionDomain, null);
4747
if (jarPath != null && Files.exists(jarPath)) {
4848
LOGGER.debug("jarpath: {}", jarPath);
4949
jarName = jarPath.toString();

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/symbol/JarScannerTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ public void extractJarPathFromJar()
2222
URL jarUrl = new URL("jar:file:" + jarFileUrl.getFile() + "!/");
2323
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {jarUrl}, null);
2424
Class<?> testClass = urlClassLoader.loadClass(CLASS_NAME);
25-
assertEquals(jarFileUrl.getFile(), JarScanner.extractJarPath(testClass).toString());
25+
assertEquals(jarFileUrl.getFile(), JarScanner.extractJarPath(testClass, null).toString());
2626
assertEquals(
2727
jarFileUrl.getFile(),
28-
JarScanner.extractJarPath(testClass.getProtectionDomain()).toString());
28+
JarScanner.extractJarPath(testClass.getProtectionDomain(), null).toString());
2929
}
3030

3131
@Test
@@ -34,7 +34,7 @@ public void extractJarPathFromFile() throws ClassNotFoundException, URISyntaxExc
3434
URL jarFileUrl = getClass().getResource("/debugger-symbol.jar");
3535
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {jarFileUrl}, null);
3636
Class<?> testClass = urlClassLoader.loadClass(CLASS_NAME);
37-
assertEquals(jarFileUrl.getFile(), JarScanner.extractJarPath(testClass).toString());
37+
assertEquals(jarFileUrl.getFile(), JarScanner.extractJarPath(testClass, null).toString());
3838
}
3939

4040
@Test
@@ -45,6 +45,7 @@ public void extractJarPathFromNestedJar() throws URISyntaxException {
4545
.thenReturn("jar:nested:" + jarFileUrl.getFile() + "/!BOOT-INF/classes/!");
4646
CodeSource codeSource = new CodeSource(mockLocation, (Certificate[]) null);
4747
ProtectionDomain protectionDomain = new ProtectionDomain(codeSource, null);
48-
assertEquals(jarFileUrl.getFile(), JarScanner.extractJarPath(protectionDomain).toString());
48+
assertEquals(
49+
jarFileUrl.getFile(), JarScanner.extractJarPath(protectionDomain, null).toString());
4950
}
5051
}

0 commit comments

Comments
 (0)