Skip to content

Commit 7408c08

Browse files
committed
Add property to render stacktrace using jvm default
1 parent 30d25a2 commit 7408c08

File tree

2 files changed

+102
-7
lines changed

2 files changed

+102
-7
lines changed

sdk/common/src/main/java/io/opentelemetry/sdk/internal/DefaultExceptionAttributeResolver.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.sdk.internal;
77

8+
import io.opentelemetry.api.internal.ConfigUtil;
89
import java.io.PrintWriter;
910
import java.io.StringWriter;
1011

@@ -15,10 +16,19 @@
1516
*/
1617
public final class DefaultExceptionAttributeResolver implements ExceptionAttributeResolver {
1718

19+
private static final String ENABLE_JVM_STACKTRACE_PROPERTY =
20+
"otel.experimental.sdk.jvm_stacktrace";
21+
1822
private static final DefaultExceptionAttributeResolver INSTANCE =
19-
new DefaultExceptionAttributeResolver();
23+
new DefaultExceptionAttributeResolver(
24+
Boolean.parseBoolean(ConfigUtil.getString(ENABLE_JVM_STACKTRACE_PROPERTY, "false")));
25+
26+
private final boolean jvmStacktraceEnabled;
2027

21-
private DefaultExceptionAttributeResolver() {}
28+
// Visible for testing
29+
DefaultExceptionAttributeResolver(boolean jvmStacktraceEnabled) {
30+
this.jvmStacktraceEnabled = jvmStacktraceEnabled;
31+
}
2232

2333
public static ExceptionAttributeResolver getInstance() {
2434
return INSTANCE;
@@ -37,14 +47,23 @@ public void setExceptionAttributes(
3747
attributeSetter.setAttribute(ExceptionAttributeResolver.EXCEPTION_MESSAGE, exceptionMessage);
3848
}
3949

50+
String exceptionStacktrace =
51+
jvmStacktraceEnabled
52+
? jvmStacktrace(throwable)
53+
: limitsAwareStacktrace(throwable, maxAttributeLength);
54+
attributeSetter.setAttribute(
55+
ExceptionAttributeResolver.EXCEPTION_STACKTRACE, exceptionStacktrace);
56+
}
57+
58+
private static String jvmStacktrace(Throwable throwable) {
4059
StringWriter stringWriter = new StringWriter();
4160
try (PrintWriter printWriter = new PrintWriter(stringWriter)) {
4261
throwable.printStackTrace(printWriter);
4362
}
44-
String exceptionStacktrace = stringWriter.toString();
45-
if (exceptionStacktrace != null) {
46-
attributeSetter.setAttribute(
47-
ExceptionAttributeResolver.EXCEPTION_STACKTRACE, exceptionStacktrace);
48-
}
63+
return stringWriter.toString();
64+
}
65+
66+
private static String limitsAwareStacktrace(Throwable throwable, int maxAttributeLength) {
67+
return new StackTraceRenderer(throwable, maxAttributeLength).render();
4968
}
5069
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.internal;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
import io.opentelemetry.api.common.AttributeKey;
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
import java.util.function.Predicate;
14+
import java.util.stream.Stream;
15+
import javax.annotation.Nullable;
16+
import org.junit.jupiter.params.ParameterizedTest;
17+
import org.junit.jupiter.params.provider.Arguments;
18+
import org.junit.jupiter.params.provider.MethodSource;
19+
20+
class DefaultExceptionAttributeResolverTest {
21+
22+
@ParameterizedTest
23+
@MethodSource("setExceptionAttributesArgs")
24+
void setExceptionAttributes(
25+
boolean jvmStacktraceEnabled,
26+
Throwable throwable,
27+
int maxAttributeLength,
28+
String expectedMessage,
29+
String expectedType,
30+
Predicate<String> validStacktrace) {
31+
DefaultExceptionAttributeResolver resolver =
32+
new DefaultExceptionAttributeResolver(jvmStacktraceEnabled);
33+
Map<String, Object> attributes = new HashMap<>();
34+
35+
resolver.setExceptionAttributes(
36+
new ExceptionAttributeResolver.AttributeSetter() {
37+
@Override
38+
public <T> void setAttribute(AttributeKey<T> key, @Nullable T value) {
39+
attributes.put(key.toString(), value);
40+
}
41+
},
42+
throwable,
43+
maxAttributeLength);
44+
45+
assertThat(attributes.get(ExceptionAttributeResolver.EXCEPTION_MESSAGE.getKey()))
46+
.isEqualTo(expectedMessage);
47+
assertThat(attributes.get(ExceptionAttributeResolver.EXCEPTION_TYPE.getKey()))
48+
.isEqualTo(expectedType);
49+
assertThat((String) attributes.get(ExceptionAttributeResolver.EXCEPTION_STACKTRACE.getKey()))
50+
.matches(validStacktrace);
51+
}
52+
53+
private static Stream<Arguments> setExceptionAttributesArgs() {
54+
return Stream.of(
55+
// When jvmStacktraceEnabled=true, limit is ignored
56+
Arguments.of(
57+
true,
58+
new Exception("error"),
59+
10,
60+
"error",
61+
"java.lang.Exception",
62+
predicate(stacktrace -> stacktrace.length() > 10)),
63+
// When jvmStacktraceEnabled=false, limit is adhered
64+
Arguments.of(
65+
false,
66+
new Exception("error"),
67+
10,
68+
"error",
69+
"java.lang.Exception",
70+
predicate(stacktrace -> stacktrace.length() == 10)));
71+
}
72+
73+
private static Predicate<String> predicate(Predicate<String> predicate) {
74+
return predicate;
75+
}
76+
}

0 commit comments

Comments
 (0)