From 59e3ccde4dbf158976358c1cb06083a6b82e5ade Mon Sep 17 00:00:00 2001 From: Tobias Stadler Date: Thu, 4 Nov 2021 11:19:12 +0100 Subject: [PATCH 1/3] Add the (current) transaction name to the error object --- .../elastic/apm/agent/impl/ElasticApmTracer.java | 3 +++ .../apm/agent/impl/error/ErrorCapture.java | 15 +++++++++++++++ .../report/serialize/DslJsonSerializer.java | 3 +++ .../apm/agent/impl/ElasticApmTracerTest.java | 16 ++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java index 17c9f65a35..00df192ae1 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java @@ -329,6 +329,9 @@ private ErrorCapture captureException(long epochMicros, @Nullable Throwable e, @ error.setException(e); Transaction currentTransaction = currentTransaction(); if (currentTransaction != null) { + if (currentTransaction.getNameForSerialization().length() > 0) { + error.setTransactionName(currentTransaction.getNameAsString()); + } error.setTransactionType(currentTransaction.getType()); error.setTransactionSampled(currentTransaction.isSampled()); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java index 50e0544346..50cba3d838 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java @@ -238,6 +238,11 @@ public static class TransactionInfo implements Recyclable { * A hint for UI to be able to show whether a recorded trace for the corresponding transaction is expected */ private boolean isSampled; + /** + * The related TransactionInfo name + */ + @Nullable + private String name; /** * The related TransactionInfo type */ @@ -247,6 +252,7 @@ public static class TransactionInfo implements Recyclable { @Override public void resetState() { isSampled = false; + name = null; type = null; } @@ -254,6 +260,11 @@ public boolean isSampled() { return isSampled; } + @Nullable + public String getName() { + return name; + } + @Nullable public String getType() { return type; @@ -268,6 +279,10 @@ public void setTransactionSampled(boolean transactionSampled) { transactionInfo.isSampled = transactionSampled; } + public void setTransactionName(@Nullable String name) { + transactionInfo.name = name; + } + public void setTransactionType(@Nullable String type) { transactionInfo.type = type; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java index 44c88e7585..29b6c2e52b 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java @@ -338,6 +338,9 @@ private void serializeError(ErrorCapture errorCapture) { private void serializeErrorTransactionInfo(ErrorCapture.TransactionInfo errorTransactionInfo) { writeFieldName("transaction"); jw.writeByte(JsonWriter.OBJECT_START); + if (errorTransactionInfo.getName() != null) { + writeField("name", errorTransactionInfo.getName()); + } if (errorTransactionInfo.getType() != null) { writeField("type", errorTransactionInfo.getType()); } diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java index 5c896046e3..6f70349cd1 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java @@ -267,6 +267,9 @@ private ErrorCapture validateError(ErrorCapture error, AbstractSpan span, boo .describedAs("error trace context [%s] should be a child of span trace context [%s]", error.getTraceContext(), span.getTraceContext()) .isTrue(); assertThat(error.getTransactionInfo().isSampled()).isEqualTo(sampled); + if (!transaction.getNameAsString().isEmpty()) { + assertThat(error.getTransactionInfo().getName()).isEqualTo(transaction.getNameAsString()); + } assertThat(error.getTransactionInfo().getType()).isEqualTo(transaction.getType()); return error; } @@ -484,4 +487,17 @@ void testCaptureExceptionAndGetErrorId() { assertThat(error.getTraceContext().getId().toString()).isEqualTo(errorId); } + @Test + void testCaptureExceptionWithTransactionName() { + Transaction transaction = startTestRootTransaction().withName("My Transaction"); + try (Scope scope = transaction.activateInScope()) { + transaction.captureException(new Exception("test")); + transaction.end(); + } + + assertThat(reporter.getErrors()).hasSize(1); + ErrorCapture error = reporter.getFirstError(); + assertThat(error.getTransactionInfo().getName()).isEqualTo("My Transaction"); + } + } From e5396277dc0f579806df055cd6fe3e4380ec95e6 Mon Sep 17 00:00:00 2001 From: Tobias Stadler Date: Thu, 4 Nov 2021 11:23:04 +0100 Subject: [PATCH 2/3] Added #2235 to the changelog --- CHANGELOG.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index a361ea1efb..1d4ad79d66 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -43,6 +43,7 @@ by the agent may be different. This was done in order to improve the integration * Added support to capture `context.message.routing-key` in rabbitmq, spring amqp instrumentations - {pull}1767[#1767] * Breakdown metrics are now tracked per service (when using APM Server 8.0) - {pull}2208[#2208] * Add support for Spring AMQP batch API - {pull}1716[#1716] +* Add the (current) transaction name to the error (when using APM Server 8.0) - {pull}2235[#2235] [float] ===== Performance improvements From 71f242abfa61567f081c69107d2c2d0a748bed5b Mon Sep 17 00:00:00 2001 From: Tobias Stadler Date: Thu, 4 Nov 2021 14:48:39 +0100 Subject: [PATCH 3/3] Use StringBuilder as suggested by @felixbarny --- .../co/elastic/apm/agent/impl/ElasticApmTracer.java | 2 +- .../elastic/apm/agent/impl/error/ErrorCapture.java | 13 ++++++------- .../apm/agent/impl/ElasticApmTracerTest.java | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java index 00df192ae1..f9a5d59bda 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java @@ -330,7 +330,7 @@ private ErrorCapture captureException(long epochMicros, @Nullable Throwable e, @ Transaction currentTransaction = currentTransaction(); if (currentTransaction != null) { if (currentTransaction.getNameForSerialization().length() > 0) { - error.setTransactionName(currentTransaction.getNameAsString()); + error.setTransactionName(currentTransaction.getNameForSerialization()); } error.setTransactionType(currentTransaction.getType()); error.setTransactionSampled(currentTransaction.isSampled()); diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java index 50cba3d838..cf5d017224 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java @@ -241,8 +241,7 @@ public static class TransactionInfo implements Recyclable { /** * The related TransactionInfo name */ - @Nullable - private String name; + private StringBuilder name = new StringBuilder(); /** * The related TransactionInfo type */ @@ -252,7 +251,7 @@ public static class TransactionInfo implements Recyclable { @Override public void resetState() { isSampled = false; - name = null; + name.setLength(0); type = null; } @@ -260,8 +259,7 @@ public boolean isSampled() { return isSampled; } - @Nullable - public String getName() { + public StringBuilder getName() { return name; } @@ -279,8 +277,9 @@ public void setTransactionSampled(boolean transactionSampled) { transactionInfo.isSampled = transactionSampled; } - public void setTransactionName(@Nullable String name) { - transactionInfo.name = name; + public void setTransactionName(@Nullable StringBuilder name) { + transactionInfo.name.setLength(0); + transactionInfo.name.append(name); } public void setTransactionType(@Nullable String type) { diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java index 6f70349cd1..78e98b084d 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java @@ -497,7 +497,7 @@ void testCaptureExceptionWithTransactionName() { assertThat(reporter.getErrors()).hasSize(1); ErrorCapture error = reporter.getFirstError(); - assertThat(error.getTransactionInfo().getName()).isEqualTo("My Transaction"); + assertThat(error.getTransactionInfo().getName().toString()).isEqualTo("My Transaction"); } }