Skip to content

Commit 081960d

Browse files
committed
Merge branch 'main' of https://github.com/open-telemetry/opentelemetry-java into lazy-evaluate-exception
2 parents 37e47a2 + 9cb6365 commit 081960d

File tree

46 files changed

+1375
-47
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1375
-47
lines changed

api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public ExtendedLogRecordBuilder setEventName(String eventName) {
4040
return this;
4141
}
4242

43+
@Override
44+
public ExtendedLogRecordBuilder setException(Throwable throwable) {
45+
return this;
46+
}
47+
4348
@Override
4449
public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
4550
return this;

api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ public interface ExtendedLogRecordBuilder extends LogRecordBuilder {
1919
* record with a non-empty event name is an Event.
2020
*/
2121
ExtendedLogRecordBuilder setEventName(String eventName);
22+
23+
/** Set standard {@code exception.*} attributes based on the {@code throwable}. */
24+
ExtendedLogRecordBuilder setException(Throwable throwable);
2225
}
Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,61 @@
11
Comparing source compatibility of opentelemetry-sdk-metrics-1.50.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.49.0.jar
2-
No changes.
2+
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.data.DelegatingMetricData (not serializable)
3+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
4+
+++ NEW INTERFACE: io.opentelemetry.sdk.metrics.data.MetricData
5+
+++ NEW SUPERCLASS: java.lang.Object
6+
+++ NEW METHOD: PUBLIC(+) boolean equals(java.lang.Object)
7+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.data.Data<?> getData()
8+
+++ NEW METHOD: PUBLIC(+) java.lang.String getDescription()
9+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.InstrumentationScopeInfo getInstrumentationScopeInfo()
10+
+++ NEW METHOD: PUBLIC(+) java.lang.String getName()
11+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource getResource()
12+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.data.MetricDataType getType()
13+
+++ NEW METHOD: PUBLIC(+) java.lang.String getUnit()
14+
+++ NEW METHOD: PUBLIC(+) int hashCode()
15+
+++ NEW METHOD: PUBLIC(+) java.lang.String toString()
16+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.DoubleExemplarData (not serializable)
17+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
18+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.DoubleExemplarData create(io.opentelemetry.api.common.Attributes, long, io.opentelemetry.api.trace.SpanContext, double)
19+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.DoublePointData (not serializable)
20+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
21+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.DoublePointData create(long, long, io.opentelemetry.api.common.Attributes, double, java.util.List<io.opentelemetry.sdk.metrics.data.DoubleExemplarData>)
22+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets (not serializable)
23+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
24+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets create(int, int, java.util.List<java.lang.Long>)
25+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.ExponentialHistogramData (not serializable)
26+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
27+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.ExponentialHistogramData create(io.opentelemetry.sdk.metrics.data.AggregationTemporality, java.util.Collection<io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData>)
28+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData (not serializable)
29+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
30+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData create(int, double, long, boolean, double, boolean, double, io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets, io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets, long, long, io.opentelemetry.api.common.Attributes, java.util.List<io.opentelemetry.sdk.metrics.data.DoubleExemplarData>)
31+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.GaugeData (not serializable)
32+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
33+
GENERIC TEMPLATES: === T:io.opentelemetry.sdk.metrics.data.PointData
34+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.GaugeData<io.opentelemetry.sdk.metrics.data.DoublePointData> createDoubleGaugeData(java.util.Collection<io.opentelemetry.sdk.metrics.data.DoublePointData>)
35+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.GaugeData<io.opentelemetry.sdk.metrics.data.LongPointData> createLongGaugeData(java.util.Collection<io.opentelemetry.sdk.metrics.data.LongPointData>)
36+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.HistogramData (not serializable)
37+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
38+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.HistogramData create(io.opentelemetry.sdk.metrics.data.AggregationTemporality, java.util.Collection<io.opentelemetry.sdk.metrics.data.HistogramPointData>)
39+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.HistogramPointData (not serializable)
40+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
41+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.HistogramPointData create(long, long, io.opentelemetry.api.common.Attributes, double, boolean, double, boolean, double, java.util.List<java.lang.Double>, java.util.List<java.lang.Long>)
42+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.LongExemplarData (not serializable)
43+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
44+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.LongExemplarData create(io.opentelemetry.api.common.Attributes, long, io.opentelemetry.api.trace.SpanContext, long)
45+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.LongPointData (not serializable)
46+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
47+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.LongPointData create(long, long, io.opentelemetry.api.common.Attributes, long)
48+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.SumData (not serializable)
49+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
50+
GENERIC TEMPLATES: === T:io.opentelemetry.sdk.metrics.data.PointData
51+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.SumData<io.opentelemetry.sdk.metrics.data.DoublePointData> createDoubleSumData(boolean, io.opentelemetry.sdk.metrics.data.AggregationTemporality, java.util.Collection<io.opentelemetry.sdk.metrics.data.DoublePointData>)
52+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.SumData<io.opentelemetry.sdk.metrics.data.LongPointData> createLongSumData(boolean, io.opentelemetry.sdk.metrics.data.AggregationTemporality, java.util.Collection<io.opentelemetry.sdk.metrics.data.LongPointData>)
53+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.SummaryData (not serializable)
54+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
55+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.SummaryData create(java.util.Collection<io.opentelemetry.sdk.metrics.data.SummaryPointData>)
56+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.SummaryPointData (not serializable)
57+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
58+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.SummaryPointData create(long, long, io.opentelemetry.api.common.Attributes, long, double, java.util.List<io.opentelemetry.sdk.metrics.data.ValueAtQuantile>)
59+
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.data.ValueAtQuantile (not serializable)
60+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
61+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.data.ValueAtQuantile create(double, double)
Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,23 @@
11
Comparing source compatibility of opentelemetry-sdk-testing-1.50.0-SNAPSHOT.jar against opentelemetry-sdk-testing-1.49.0.jar
2-
No changes.
2+
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.metrics.TestMetricData (not serializable)
3+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
4+
+++ NEW SUPERCLASS: java.lang.Object
5+
+++ NEW CONSTRUCTOR: PUBLIC(+) TestMetricData()
6+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder builder()
7+
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) STATIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder (not serializable)
8+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
9+
+++ NEW SUPERCLASS: java.lang.Object
10+
+++ NEW CONSTRUCTOR: PUBLIC(+) TestMetricData$Builder()
11+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData build()
12+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setDescription(java.lang.String)
13+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setDoubleGaugeData(io.opentelemetry.sdk.metrics.data.GaugeData<io.opentelemetry.sdk.metrics.data.DoublePointData>)
14+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setDoubleSumData(io.opentelemetry.sdk.metrics.data.SumData<io.opentelemetry.sdk.metrics.data.DoublePointData>)
15+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setExponentialHistogramData(io.opentelemetry.sdk.metrics.data.ExponentialHistogramData)
16+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setHistogramData(io.opentelemetry.sdk.metrics.data.HistogramData)
17+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setInstrumentationScopeInfo(io.opentelemetry.sdk.common.InstrumentationScopeInfo)
18+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setLongGaugeData(io.opentelemetry.sdk.metrics.data.GaugeData<io.opentelemetry.sdk.metrics.data.LongPointData>)
19+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setLongSumData(io.opentelemetry.sdk.metrics.data.SumData<io.opentelemetry.sdk.metrics.data.LongPointData>)
20+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setName(java.lang.String)
21+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setResource(io.opentelemetry.sdk.resources.Resource)
22+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setSummaryData(io.opentelemetry.sdk.metrics.data.SummaryData)
23+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.testing.metrics.TestMetricData$Builder setUnit(java.lang.String)

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,28 @@
88
import io.opentelemetry.api.common.AttributeKey;
99
import io.opentelemetry.api.common.Attributes;
1010
import io.opentelemetry.api.common.AttributesBuilder;
11+
import java.io.PrintWriter;
12+
import java.io.StringWriter;
1113
import java.util.ArrayList;
1214
import java.util.List;
1315
import java.util.Map;
16+
import java.util.function.BiConsumer;
1417
import java.util.function.Predicate;
18+
import javax.annotation.Nullable;
1519

1620
/**
1721
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
1822
* any time.
1923
*/
2024
public final class AttributeUtil {
2125

26+
private static final AttributeKey<String> EXCEPTION_TYPE =
27+
AttributeKey.stringKey("exception.type");
28+
private static final AttributeKey<String> EXCEPTION_MESSAGE =
29+
AttributeKey.stringKey("exception.message");
30+
private static final AttributeKey<String> EXCEPTION_STACKTRACE =
31+
AttributeKey.stringKey("exception.stacktrace");
32+
2233
private AttributeUtil() {}
2334

2435
/**
@@ -95,4 +106,32 @@ public static Object applyAttributeLengthLimit(Object value, int lengthLimit) {
95106
}
96107
return value;
97108
}
109+
110+
public static void addExceptionAttributes(
111+
BiConsumer<AttributeKey<String>, String> attributeConsumer, Throwable exception) {
112+
addExceptionAttributes(attributeConsumer, exception, exception.getMessage());
113+
}
114+
115+
public static void addExceptionAttributes(
116+
BiConsumer<AttributeKey<String>, String> attributeConsumer,
117+
Throwable exception,
118+
@Nullable String exceptionMessage) {
119+
String exceptionType = exception.getClass().getCanonicalName();
120+
if (exceptionType != null) {
121+
attributeConsumer.accept(EXCEPTION_TYPE, exceptionType);
122+
}
123+
124+
if (exceptionMessage != null) {
125+
attributeConsumer.accept(EXCEPTION_MESSAGE, exceptionMessage);
126+
}
127+
128+
StringWriter stringWriter = new StringWriter();
129+
try (PrintWriter printWriter = new PrintWriter(stringWriter)) {
130+
exception.printStackTrace(printWriter);
131+
}
132+
String stackTrace = stringWriter.toString();
133+
if (stackTrace != null) {
134+
attributeConsumer.accept(EXCEPTION_STACKTRACE, stackTrace);
135+
}
136+
}
98137
}

sdk/logs/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ testing {
2828
dependencies {
2929
implementation(project(":sdk:testing"))
3030
implementation(project(":api:incubator"))
31+
implementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating")
3132
implementation("com.google.guava:guava")
3233
}
3334
}

sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ public ExtendedSdkLogRecordBuilder setEventName(String eventName) {
2929
return this;
3030
}
3131

32+
@Override
33+
public ExtendedSdkLogRecordBuilder setException(Throwable throwable) {
34+
super.setException(throwable);
35+
return this;
36+
}
37+
3238
@Override
3339
public ExtendedSdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
3440
super.setTimestamp(timestamp, unit);

sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.opentelemetry.api.trace.Span;
1313
import io.opentelemetry.context.Context;
1414
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
15+
import io.opentelemetry.sdk.internal.AttributeUtil;
1516
import io.opentelemetry.sdk.internal.AttributesMap;
1617
import java.time.Instant;
1718
import java.util.concurrent.TimeUnit;
@@ -46,6 +47,17 @@ SdkLogRecordBuilder setEventName(String eventName) {
4647
return this;
4748
}
4849

50+
// accessible via ExtendedSdkLogRecordBuilder
51+
SdkLogRecordBuilder setException(Throwable throwable) {
52+
if (throwable == null) {
53+
return this;
54+
}
55+
56+
AttributeUtil.addExceptionAttributes(this::setAttribute, throwable);
57+
58+
return this;
59+
}
60+
4961
@Override
5062
public SdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
5163
this.timestampEpochNanos = unit.toNanos(timestamp);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.logs;
7+
8+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
9+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
10+
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
11+
import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_MESSAGE;
12+
import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_STACKTRACE;
13+
import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_TYPE;
14+
15+
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
16+
import io.opentelemetry.api.logs.Logger;
17+
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
18+
import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
19+
import org.junit.jupiter.api.Test;
20+
21+
class ExtendedLoggerBuilderTest {
22+
23+
private final InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create();
24+
private final SdkLoggerProviderBuilder loggerProviderBuilder =
25+
SdkLoggerProvider.builder().addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter));
26+
27+
@Test
28+
void setException() {
29+
Logger logger = loggerProviderBuilder.build().get("logger");
30+
31+
((ExtendedLogRecordBuilder) logger.logRecordBuilder())
32+
.setException(new Exception("error"))
33+
.emit();
34+
35+
assertThat(exporter.getFinishedLogRecordItems())
36+
.satisfiesExactly(
37+
logRecord ->
38+
assertThat(logRecord)
39+
.hasAttributesSatisfyingExactly(
40+
equalTo(EXCEPTION_TYPE, "java.lang.Exception"),
41+
equalTo(EXCEPTION_MESSAGE, "error"),
42+
satisfies(
43+
EXCEPTION_STACKTRACE,
44+
stacktrace ->
45+
stacktrace.startsWith(
46+
"java.lang.Exception: error" + System.lineSeparator()))));
47+
}
48+
}

0 commit comments

Comments
 (0)