Skip to content

Commit a2ffb76

Browse files
committed
Add SymDB report for any jar scanning failures
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 f06d59c commit a2ffb76

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)