Skip to content

Commit

Permalink
Setting transaction.sampled in errors (#405)
Browse files Browse the repository at this point in the history
  • Loading branch information
eyalkoren authored Jan 7, 2019
1 parent e2261a9 commit 03b566e
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ else if (active instanceof Span) {
error.getContext().getTags().putAll(span.getContext().getTags());
}
error.asChildOf(active);
error.setTransactionSampled(active.isSampled());
} else {
error.getTraceContext().getId().setToRandomValue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ public class ErrorCapture implements Recyclable {
* (Required)
*/
private long timestamp;
/**
* A hint for UI to be able to show whether a recorded trace for the corresponding transaction is expected
*/
private boolean isTransactionSampled;
private ElasticApmTracer tracer;
private final StringBuilder culprit = new StringBuilder();

Expand Down Expand Up @@ -97,6 +101,7 @@ public void resetState() {
exception = null;
context.resetState();
timestamp = 0;
isTransactionSampled = false;
traceContext.resetState();
culprit.setLength(0);
}
Expand Down Expand Up @@ -171,4 +176,12 @@ private void setCulprit(StackTraceElement stackTraceElement) {
}
culprit.append(')');
}

public boolean isTransactionSampled() {
return isTransactionSampled;
}

public void setTransactionSampled(boolean transactionSampled) {
isTransactionSampled = transactionSampled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ private void serializeError(ErrorCapture errorCapture) {
jw.writeByte(JsonWriter.OBJECT_START);

writeTimestamp(errorCapture.getTimestamp());

serializeTransactionSampled(errorCapture.isTransactionSampled());
if (errorCapture.getTraceContext().hasContent()) {
serializeTraceContext(errorCapture.getTraceContext(), true);
}
Expand All @@ -237,6 +237,14 @@ private void serializeError(ErrorCapture errorCapture) {
jw.writeByte(JsonWriter.OBJECT_END);
}

private void serializeTransactionSampled(boolean sampled) {
writeFieldName("transaction");
jw.writeByte(JsonWriter.OBJECT_START);
writeLastField("sampled", sampled);
jw.writeByte(JsonWriter.OBJECT_END);
jw.writeByte(COMMA);
}

private void serializeException(@Nullable Throwable exception) {
writeFieldName("exception");
jw.writeByte(JsonWriter.OBJECT_START);
Expand Down Expand Up @@ -284,6 +292,10 @@ public String toJsonString(final ErrorCapture error) {
return s;
}

public String toString() {
return jw.toString();
}

private void serializeTransactionPayload(final TransactionPayload payload) {
jw.writeByte(JsonWriter.OBJECT_START);
serializeService(payload.getService());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import co.elastic.apm.agent.impl.error.ErrorCapture;
import co.elastic.apm.agent.impl.sampling.ConstantSampler;
import co.elastic.apm.agent.impl.stacktrace.StacktraceConfiguration;
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
import co.elastic.apm.agent.impl.transaction.Span;
import co.elastic.apm.agent.impl.transaction.TraceContext;
import co.elastic.apm.agent.impl.transaction.Transaction;
Expand Down Expand Up @@ -163,26 +164,44 @@ void testRecordException() {
ErrorCapture error = reporter.getFirstError();
assertThat(error.getException()).isNotNull();
assertThat(error.getTraceContext().hasContent()).isFalse();
assertThat(error.isTransactionSampled()).isFalse();
}

@Test
void testRecordExceptionWithTrace() {
Transaction transaction = tracerImpl.startTransaction();
innerRecordExceptionWithTrace(true);
innerRecordExceptionWithTrace(false);
}

private void innerRecordExceptionWithTrace(boolean sampled) {
reporter.reset();
Transaction transaction = tracerImpl.startTransaction(TraceContext.asRoot(), null, ConstantSampler.of(sampled), -1);
try (Scope scope = transaction.activateInScope()) {
transaction.getContext().getRequest()
.addHeader("foo", "bar")
.withMethod("GET")
.getUrl()
.withPathname("/foo");
tracerImpl.currentTransaction().captureException(new Exception("test"));
assertThat(reporter.getErrors()).hasSize(1);
ErrorCapture error = reporter.getFirstError();
assertThat(error.getTraceContext().isChildOf(transaction.getTraceContext())).isTrue();
tracerImpl.currentTransaction().captureException(new Exception("from transaction"));
ErrorCapture error = validateError(transaction, sampled);
assertThat(error.getContext().getRequest().getHeaders().get("foo")).isEqualTo("bar");
reporter.reset();
Span span = transaction.createSpan().activate();
span.captureException(new Exception("from span"));
validateError(span, sampled);
span.deactivate().end();
transaction.end();
}
}

private ErrorCapture validateError(AbstractSpan span, boolean sampled) {
assertThat(reporter.getErrors()).hasSize(1);
ErrorCapture error = reporter.getFirstError();
assertThat(error.getTraceContext().isChildOf(span.getTraceContext())).isTrue();
assertThat(error.isTransactionSampled()).isEqualTo(sampled);
return error;
}

@Test
void testEnableDropSpans() {
when(tracerImpl.getConfig(CoreConfiguration.class).getTransactionMaxSpans()).thenReturn(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
*/
package co.elastic.apm.agent.report.serialize;

import co.elastic.apm.agent.MockTracer;
import co.elastic.apm.agent.impl.ElasticApmTracer;
import co.elastic.apm.agent.impl.error.ErrorCapture;
import co.elastic.apm.agent.impl.stacktrace.StacktraceConfiguration;
import co.elastic.apm.agent.impl.transaction.Transaction;
import com.dslplatform.json.JsonWriter;
Expand Down Expand Up @@ -64,6 +66,28 @@ void serializeTags() {
});
}

@Test
void testErrorSerialization() throws IOException {
ElasticApmTracer tracer = MockTracer.create();
Transaction transaction = new Transaction(tracer);
ErrorCapture error = new ErrorCapture(tracer).asChildOf(transaction).withTimestamp(5000);
error.setTransactionSampled(true);
error.setException(new Exception("test"));
error.getContext().getTags().put("foo", "bar");
String errorJson = serializer.toJsonString(error);
System.out.println("errorJson = " + errorJson);
JsonNode errorTree = objectMapper.readTree(errorJson);
assertThat(errorTree.get("timestamp").longValue()).isEqualTo(5000);
assertThat(errorTree.get("culprit").textValue()).startsWith(this.getClass().getName());
JsonNode context = errorTree.get("context");
assertThat(context.get("tags").get("foo").textValue()).isEqualTo("bar");
JsonNode exception = errorTree.get("exception");
assertThat(exception.get("message").textValue()).isEqualTo("test");
assertThat(exception.get("stacktrace")).isNotNull();
assertThat(exception.get("type").textValue()).isEqualTo(Exception.class.getName());
assertThat(errorTree.get("transaction").get("sampled").booleanValue()).isTrue();
}

@Test
void testLimitStringValueLength() throws IOException {
StringBuilder longValue = new StringBuilder(DslJsonSerializer.MAX_VALUE_LENGTH + 1);
Expand Down

0 comments on commit 03b566e

Please sign in to comment.