diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/DefaultExceptionDebugger.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/DefaultExceptionDebugger.java index 2d4b2dd5fe5..73250bf81e6 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/DefaultExceptionDebugger.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/DefaultExceptionDebugger.java @@ -28,7 +28,8 @@ public class DefaultExceptionDebugger implements DebuggerContext.ExceptionDebugger { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExceptionDebugger.class); public static final String DD_DEBUG_ERROR_PREFIX = "_dd.debug.error."; - public static final String DD_DEBUG_ERROR_EXCEPTION_ID = DD_DEBUG_ERROR_PREFIX + "exception_id"; + public static final String DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID = + DD_DEBUG_ERROR_PREFIX + "exception_capture_id"; public static final String DD_DEBUG_ERROR_EXCEPTION_HASH = DD_DEBUG_ERROR_PREFIX + "exception_hash"; public static final String ERROR_DEBUG_INFO_CAPTURED = "error.debug_info_captured"; @@ -129,7 +130,7 @@ private static void processSnapshotsAndSetTags( ThrowableState state, List chainedExceptions, String fingerprint) { - if (span.getTag(DD_DEBUG_ERROR_EXCEPTION_ID) != null) { + if (span.getTag(DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID) != null) { LOGGER.debug("Clear previous frame tags"); // already set for this span, clear the frame tags span.getTags() @@ -159,17 +160,21 @@ private static void processSnapshotsAndSetTags( span.setTag(tagName, snapshot.getId()); LOGGER.debug("add tag to span[{}]: {}: {}", span.getSpanId(), tagName, snapshot.getId()); if (!state.isSnapshotSent()) { + // decorate snapshot with specific exception information + snapshot.setFrameIndex(String.valueOf(frameIndex)); + snapshot.setExceptionHash(fingerprint); + snapshot.setExceptionCaptureId(state.getExceptionId()); DebuggerAgent.getSink().addSnapshot(snapshot); } snapshotAssigned = true; } if (snapshotAssigned) { state.markAsSnapshotSent(); - span.setTag(DD_DEBUG_ERROR_EXCEPTION_ID, state.getExceptionId()); + span.setTag(DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID, state.getExceptionId()); LOGGER.debug( "add tag to span[{}]: {}: {}", span.getSpanId(), - DD_DEBUG_ERROR_EXCEPTION_ID, + DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID, state.getExceptionId()); span.setTag(ERROR_DEBUG_INFO_CAPTURED, true); span.setTag(DD_DEBUG_ERROR_EXCEPTION_HASH, fingerprint); diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java index 7b68b69afce..c8ca473e56c 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/exception/ExceptionProbeManager.java @@ -160,7 +160,6 @@ public void addSnapshot(Snapshot snapshot) { ThrowableState state = snapshotsByThrowable.computeIfAbsent( throwable, key -> new ThrowableState(RandomUtils.randomUUID().toString())); - snapshot.setExceptionId(state.getExceptionId()); state.addSnapshot(snapshot); } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java index 59b8e9eb41c..04330a96afe 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java @@ -138,7 +138,7 @@ public void commit( "committing exception probe id={}, snapshot id={}, exception id={}", id, snapshot.getId(), - snapshot.getExceptionId()); + snapshot.getExceptionCaptureId()); } } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java index 1de96d27c34..32a26111f92 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/Snapshot.java @@ -32,7 +32,9 @@ public class Snapshot { private List evaluationErrors; private transient String message; private final transient int maxDepth; - private String exceptionId; + private String exceptionHash; + private String exceptionCaptureId; + private String frameIndex; private transient int chainedExceptionIdx; public Snapshot(java.lang.Thread thread, ProbeImplementation probeImplementation, int maxDepth) { @@ -88,8 +90,16 @@ public void setMessage(String message) { this.message = message; } - public void setExceptionId(String exceptionId) { - this.exceptionId = exceptionId; + public void setExceptionHash(String exceptionHash) { + this.exceptionHash = exceptionHash; + } + + public void setExceptionCaptureId(String exceptionCaptureId) { + this.exceptionCaptureId = exceptionCaptureId; + } + + public void setFrameIndex(String frameIndex) { + this.frameIndex = frameIndex; } public void setChainedExceptionIdx(int chainedExceptionIdx) { @@ -179,8 +189,8 @@ public int getMaxDepth() { return maxDepth; } - public String getExceptionId() { - return exceptionId; + public String getExceptionCaptureId() { + return exceptionCaptureId; } public int getChainedExceptionIdx() { diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java index aaabb300cc0..efcbb0ec94e 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java @@ -116,7 +116,8 @@ public void nestedException() { .getExceptionProbeManager() .getStateByThrowable(ExceptionHelper.getInnerMostThrowable(exception)); assertEquals( - state.getExceptionId(), spanTags.get(DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_ID)); + state.getExceptionId(), + spanTags.get(DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID)); Map snapshotMap = listener.snapshots.stream().collect(toMap(Snapshot::getId, Function.identity())); List lines = parseStackTrace(exception); @@ -190,7 +191,8 @@ public void doubleNestedException() { .getExceptionProbeManager() .getStateByThrowable(ExceptionHelper.getInnerMostThrowable(nestedException)); assertEquals( - state.getExceptionId(), spanTags.get(DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_ID)); + state.getExceptionId(), + spanTags.get(DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID)); Map snapshotMap = listener.snapshots.stream().collect(toMap(Snapshot::getId, Function.identity())); List lines = parseStackTrace(nestedException); @@ -255,7 +257,8 @@ public void nestedExceptionFullThirdParty() { .getExceptionProbeManager() .getStateByThrowable(ExceptionHelper.getInnerMostThrowable(exception)); assertEquals( - state.getExceptionId(), spanTags.get(DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_ID)); + state.getExceptionId(), + spanTags.get(DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID)); Map snapshotMap = listener.snapshots.stream().collect(toMap(Snapshot::getId, Function.identity())); List lines = parseStackTrace(exception); diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java index f895b503134..b857e5661b7 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java @@ -1,8 +1,8 @@ package com.datadog.debugger.exception; import static com.datadog.debugger.agent.ConfigurationAcceptor.Source.REMOTE_CONFIG; +import static com.datadog.debugger.exception.DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID; import static com.datadog.debugger.exception.DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_HASH; -import static com.datadog.debugger.exception.DefaultExceptionDebugger.DD_DEBUG_ERROR_EXCEPTION_ID; import static com.datadog.debugger.exception.DefaultExceptionDebugger.ERROR_DEBUG_INFO_CAPTURED; import static com.datadog.debugger.exception.DefaultExceptionDebugger.SNAPSHOT_ID_TAG_FMT; import static com.datadog.debugger.util.MoshiSnapshotTestHelper.getValue; @@ -145,7 +145,8 @@ public void instrumentAndCaptureSnapshots() throws Exception { assertEquals( location.getType() + "." + location.getMethod(), snapshot0.getStack().get(0).getFunction()); MutableSpan span = traceInterceptor.getFirstSpan(); - assertEquals(snapshot0.getExceptionId(), span.getTags().get(DD_DEBUG_ERROR_EXCEPTION_ID)); + assertEquals( + snapshot0.getExceptionCaptureId(), span.getTags().get(DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID)); assertEquals(fingerprint, span.getTags().get(DD_DEBUG_ERROR_EXCEPTION_HASH)); assertEquals(Boolean.TRUE, span.getTags().get(ERROR_DEBUG_INFO_CAPTURED)); assertEquals(snapshot0.getId(), span.getTags().get(String.format(SNAPSHOT_ID_TAG_FMT, 0))); @@ -187,11 +188,15 @@ public void differentExceptionsSameStack() throws Exception { assertProbeId(probeIdsByMethodName, "processWithException", snapshot1.getProbe().getId()); assertExceptionMsg("illegal argument", snapshot1); MutableSpan span0 = traceInterceptor.getAllTraces().get(0).get(0); - assertEquals(snapshot0.getExceptionId(), span0.getTags().get(DD_DEBUG_ERROR_EXCEPTION_ID)); + assertEquals( + snapshot0.getExceptionCaptureId(), + span0.getTags().get(DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID)); assertEquals(Boolean.TRUE, span0.getTags().get(ERROR_DEBUG_INFO_CAPTURED)); assertEquals(snapshot0.getId(), span0.getTags().get(String.format(SNAPSHOT_ID_TAG_FMT, 0))); MutableSpan span1 = traceInterceptor.getAllTraces().get(1).get(0); - assertEquals(snapshot1.getExceptionId(), span1.getTags().get(DD_DEBUG_ERROR_EXCEPTION_ID)); + assertEquals( + snapshot1.getExceptionCaptureId(), + span1.getTags().get(DD_DEBUG_ERROR_EXCEPTION_CAPTURE_ID)); assertEquals(Boolean.TRUE, span1.getTags().get(ERROR_DEBUG_INFO_CAPTURED)); assertEquals(snapshot1.getId(), span1.getTags().get(String.format(SNAPSHOT_ID_TAG_FMT, 0))); }