Skip to content

Commit b387fed

Browse files
authored
Merge 917b2e3 into 5231140
2 parents 5231140 + 917b2e3 commit b387fed

File tree

3 files changed

+363
-1
lines changed

3 files changed

+363
-1
lines changed

sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,58 @@ public final class io/sentry/opentelemetry/OtelSpanFactory : io/sentry/ISpanFact
3939
public fun createTransaction (Lio/sentry/TransactionContext;Lio/sentry/IScopes;Lio/sentry/TransactionOptions;Lio/sentry/TransactionPerformanceCollector;)Lio/sentry/ITransaction;
4040
}
4141

42+
public final class io/sentry/opentelemetry/OtelStrongRefSpanWrapper : io/sentry/opentelemetry/IOtelSpanWrapper {
43+
public fun <init> (Lio/opentelemetry/api/trace/Span;Lio/sentry/opentelemetry/IOtelSpanWrapper;)V
44+
public fun finish ()V
45+
public fun finish (Lio/sentry/SpanStatus;)V
46+
public fun finish (Lio/sentry/SpanStatus;Lio/sentry/SentryDate;)V
47+
public fun getContexts ()Lio/sentry/protocol/Contexts;
48+
public fun getData ()Ljava/util/Map;
49+
public fun getData (Ljava/lang/String;)Ljava/lang/Object;
50+
public fun getDescription ()Ljava/lang/String;
51+
public fun getFinishDate ()Lio/sentry/SentryDate;
52+
public fun getMeasurements ()Ljava/util/Map;
53+
public fun getOperation ()Ljava/lang/String;
54+
public fun getSamplingDecision ()Lio/sentry/TracesSamplingDecision;
55+
public fun getScopes ()Lio/sentry/IScopes;
56+
public fun getSpanContext ()Lio/sentry/SpanContext;
57+
public fun getStartDate ()Lio/sentry/SentryDate;
58+
public fun getStatus ()Lio/sentry/SpanStatus;
59+
public fun getTag (Ljava/lang/String;)Ljava/lang/String;
60+
public fun getTags ()Ljava/util/Map;
61+
public fun getThrowable ()Ljava/lang/Throwable;
62+
public fun getTraceId ()Lio/sentry/protocol/SentryId;
63+
public fun getTransactionName ()Ljava/lang/String;
64+
public fun getTransactionNameSource ()Lio/sentry/protocol/TransactionNameSource;
65+
public fun isFinished ()Z
66+
public fun isNoOp ()Z
67+
public fun isProfileSampled ()Ljava/lang/Boolean;
68+
public fun isSampled ()Ljava/lang/Boolean;
69+
public fun makeCurrent ()Lio/sentry/ISentryLifecycleToken;
70+
public fun setContext (Ljava/lang/String;Ljava/lang/Object;)V
71+
public fun setData (Ljava/lang/String;Ljava/lang/Object;)V
72+
public fun setDescription (Ljava/lang/String;)V
73+
public fun setMeasurement (Ljava/lang/String;Ljava/lang/Number;)V
74+
public fun setMeasurement (Ljava/lang/String;Ljava/lang/Number;Lio/sentry/MeasurementUnit;)V
75+
public fun setOperation (Ljava/lang/String;)V
76+
public fun setStatus (Lio/sentry/SpanStatus;)V
77+
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
78+
public fun setThrowable (Ljava/lang/Throwable;)V
79+
public fun setTransactionName (Ljava/lang/String;)V
80+
public fun setTransactionName (Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
81+
public fun startChild (Lio/sentry/SpanContext;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
82+
public fun startChild (Ljava/lang/String;)Lio/sentry/ISpan;
83+
public fun startChild (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ISpan;
84+
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;Lio/sentry/Instrumenter;)Lio/sentry/ISpan;
85+
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;Lio/sentry/Instrumenter;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
86+
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
87+
public fun storeInContext (Lio/opentelemetry/context/Context;)Lio/opentelemetry/context/Context;
88+
public fun toBaggageHeader (Ljava/util/List;)Lio/sentry/BaggageHeader;
89+
public fun toSentryTrace ()Lio/sentry/SentryTraceHeader;
90+
public fun traceContext ()Lio/sentry/TraceContext;
91+
public fun updateEndDate (Lio/sentry/SentryDate;)Z
92+
}
93+
4294
public final class io/sentry/opentelemetry/OtelTransactionSpanForwarder : io/sentry/ITransaction {
4395
public fun <init> (Lio/sentry/opentelemetry/IOtelSpanWrapper;)V
4496
public fun finish ()V

sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanFactory.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@ public OtelSpanFactory() {
158158
sentrySpan.getSpanContext().setOrigin(spanOptions.getOrigin());
159159
}
160160

161-
return sentrySpan;
161+
if (sentrySpan == null) {
162+
return null;
163+
} else {
164+
return new OtelStrongRefSpanWrapper(otelSpan, sentrySpan);
165+
}
162166
}
163167

164168
private @NotNull Tracer getTracer() {
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
package io.sentry.opentelemetry;
2+
3+
import io.opentelemetry.api.trace.Span;
4+
import io.opentelemetry.context.Context;
5+
import io.sentry.BaggageHeader;
6+
import io.sentry.IScopes;
7+
import io.sentry.ISentryLifecycleToken;
8+
import io.sentry.ISpan;
9+
import io.sentry.Instrumenter;
10+
import io.sentry.MeasurementUnit;
11+
import io.sentry.SentryDate;
12+
import io.sentry.SentryTraceHeader;
13+
import io.sentry.SpanContext;
14+
import io.sentry.SpanOptions;
15+
import io.sentry.SpanStatus;
16+
import io.sentry.TraceContext;
17+
import io.sentry.TracesSamplingDecision;
18+
import io.sentry.protocol.Contexts;
19+
import io.sentry.protocol.MeasurementValue;
20+
import io.sentry.protocol.SentryId;
21+
import io.sentry.protocol.TransactionNameSource;
22+
import java.util.List;
23+
import java.util.Map;
24+
import org.jetbrains.annotations.ApiStatus;
25+
import org.jetbrains.annotations.NotNull;
26+
import org.jetbrains.annotations.Nullable;
27+
28+
/**
29+
* This holds a strong reference to the OpenTelemetry span, preventing it from being garbage
30+
* collected.
31+
*
32+
* <p>IMPORTANT: Only use this carefully. Please read below.
33+
*
34+
* <p>This class should only be used in cases where Sentry SDK is used to create an OpenTelemetry
35+
* span under the hood that no one holds a reference to otherwise.
36+
*
37+
* <p>e.g. ITransaction transaction = Sentry.startTransaction(...) Sentry creates an OTel span under
38+
* the hood, but no one would reference it unless this class is used and returned to the user. By
39+
* doing this, we tie the OTel span to the returned Sentry span/transaction which the user can hold
40+
* on to.
41+
*/
42+
@ApiStatus.Internal
43+
public final class OtelStrongRefSpanWrapper implements IOtelSpanWrapper {
44+
45+
@SuppressWarnings("UnusedVariable")
46+
private final @NotNull Span otelSpan;
47+
48+
private final @NotNull IOtelSpanWrapper delegate;
49+
50+
public OtelStrongRefSpanWrapper(@NotNull Span otelSpan, IOtelSpanWrapper delegate) {
51+
this.otelSpan = otelSpan;
52+
this.delegate = delegate;
53+
}
54+
55+
@Override
56+
public void setTransactionName(@NotNull String name) {
57+
delegate.setTransactionName(name);
58+
}
59+
60+
@Override
61+
public void setTransactionName(@NotNull String name, @NotNull TransactionNameSource nameSource) {
62+
delegate.setTransactionName(name, nameSource);
63+
}
64+
65+
@Override
66+
public @Nullable TransactionNameSource getTransactionNameSource() {
67+
return delegate.getTransactionNameSource();
68+
}
69+
70+
@Override
71+
public @Nullable String getTransactionName() {
72+
return delegate.getTransactionName();
73+
}
74+
75+
@Override
76+
public @NotNull SentryId getTraceId() {
77+
return delegate.getTraceId();
78+
}
79+
80+
@Override
81+
public @NotNull Map<String, Object> getData() {
82+
return delegate.getData();
83+
}
84+
85+
@Override
86+
public @NotNull Map<String, MeasurementValue> getMeasurements() {
87+
return delegate.getMeasurements();
88+
}
89+
90+
@Override
91+
public @Nullable Boolean isProfileSampled() {
92+
return delegate.isProfileSampled();
93+
}
94+
95+
@Override
96+
public @NotNull IScopes getScopes() {
97+
return delegate.getScopes();
98+
}
99+
100+
@Override
101+
public @NotNull Map<String, String> getTags() {
102+
return delegate.getTags();
103+
}
104+
105+
@Override
106+
public @NotNull Context storeInContext(Context context) {
107+
return delegate.storeInContext(context);
108+
}
109+
110+
@Override
111+
public @NotNull ISpan startChild(@NotNull String operation) {
112+
return delegate.startChild(operation);
113+
}
114+
115+
@Override
116+
public @NotNull ISpan startChild(
117+
@NotNull String operation, @Nullable String description, @NotNull SpanOptions spanOptions) {
118+
return delegate.startChild(operation, description, spanOptions);
119+
}
120+
121+
@Override
122+
public @NotNull ISpan startChild(
123+
@NotNull SpanContext spanContext, @NotNull SpanOptions spanOptions) {
124+
return delegate.startChild(spanContext, spanOptions);
125+
}
126+
127+
@Override
128+
public @NotNull ISpan startChild(
129+
@NotNull String operation,
130+
@Nullable String description,
131+
@Nullable SentryDate timestamp,
132+
@NotNull Instrumenter instrumenter) {
133+
return delegate.startChild(operation, description, timestamp, instrumenter);
134+
}
135+
136+
@Override
137+
public @NotNull ISpan startChild(
138+
@NotNull String operation,
139+
@Nullable String description,
140+
@Nullable SentryDate timestamp,
141+
@NotNull Instrumenter instrumenter,
142+
@NotNull SpanOptions spanOptions) {
143+
return delegate.startChild(operation, description, timestamp, instrumenter, spanOptions);
144+
}
145+
146+
@Override
147+
public @NotNull ISpan startChild(@NotNull String operation, @Nullable String description) {
148+
return delegate.startChild(operation, description);
149+
}
150+
151+
@Override
152+
public @NotNull SentryTraceHeader toSentryTrace() {
153+
return delegate.toSentryTrace();
154+
}
155+
156+
@Override
157+
public @Nullable TraceContext traceContext() {
158+
return delegate.traceContext();
159+
}
160+
161+
@Override
162+
public @Nullable BaggageHeader toBaggageHeader(@Nullable List<String> thirdPartyBaggageHeaders) {
163+
return delegate.toBaggageHeader(thirdPartyBaggageHeaders);
164+
}
165+
166+
@Override
167+
public void finish() {
168+
delegate.finish();
169+
}
170+
171+
@Override
172+
public void finish(@Nullable SpanStatus status) {
173+
delegate.finish(status);
174+
}
175+
176+
@Override
177+
public void finish(@Nullable SpanStatus status, @Nullable SentryDate timestamp) {
178+
delegate.finish(status, timestamp);
179+
}
180+
181+
@Override
182+
public void setOperation(@NotNull String operation) {
183+
delegate.setOperation(operation);
184+
}
185+
186+
@Override
187+
public @NotNull String getOperation() {
188+
return delegate.getOperation();
189+
}
190+
191+
@Override
192+
public void setDescription(@Nullable String description) {
193+
delegate.setDescription(description);
194+
}
195+
196+
@Override
197+
public @Nullable String getDescription() {
198+
return delegate.getDescription();
199+
}
200+
201+
@Override
202+
public void setStatus(@Nullable SpanStatus status) {
203+
delegate.setStatus(status);
204+
}
205+
206+
@Override
207+
public @Nullable SpanStatus getStatus() {
208+
return delegate.getStatus();
209+
}
210+
211+
@Override
212+
public void setThrowable(@Nullable Throwable throwable) {
213+
delegate.setThrowable(throwable);
214+
}
215+
216+
@Override
217+
public @Nullable Throwable getThrowable() {
218+
return delegate.getThrowable();
219+
}
220+
221+
@Override
222+
public @NotNull SpanContext getSpanContext() {
223+
return delegate.getSpanContext();
224+
}
225+
226+
@Override
227+
public void setTag(@NotNull String key, @NotNull String value) {
228+
delegate.setTag(key, value);
229+
}
230+
231+
@Override
232+
public @Nullable String getTag(@NotNull String key) {
233+
return delegate.getTag(key);
234+
}
235+
236+
@Override
237+
public boolean isFinished() {
238+
return delegate.isFinished();
239+
}
240+
241+
@Override
242+
public void setData(@NotNull String key, @NotNull Object value) {
243+
delegate.setData(key, value);
244+
}
245+
246+
@Override
247+
public @Nullable Object getData(@NotNull String key) {
248+
return delegate.getData(key);
249+
}
250+
251+
@Override
252+
public void setMeasurement(@NotNull String name, @NotNull Number value) {
253+
delegate.setMeasurement(name, value);
254+
}
255+
256+
@Override
257+
public void setMeasurement(
258+
@NotNull String name, @NotNull Number value, @NotNull MeasurementUnit unit) {
259+
delegate.setMeasurement(name, value, unit);
260+
}
261+
262+
@Override
263+
public boolean updateEndDate(@NotNull SentryDate date) {
264+
return delegate.updateEndDate(date);
265+
}
266+
267+
@Override
268+
public @NotNull SentryDate getStartDate() {
269+
return delegate.getStartDate();
270+
}
271+
272+
@Override
273+
public @Nullable SentryDate getFinishDate() {
274+
return delegate.getFinishDate();
275+
}
276+
277+
@Override
278+
public boolean isNoOp() {
279+
return delegate.isNoOp();
280+
}
281+
282+
@Override
283+
public void setContext(@NotNull String key, @NotNull Object context) {
284+
delegate.setContext(key, context);
285+
}
286+
287+
@Override
288+
public @NotNull Contexts getContexts() {
289+
return delegate.getContexts();
290+
}
291+
292+
@Override
293+
public @Nullable Boolean isSampled() {
294+
return delegate.isSampled();
295+
}
296+
297+
@Override
298+
public @Nullable TracesSamplingDecision getSamplingDecision() {
299+
return delegate.getSamplingDecision();
300+
}
301+
302+
@Override
303+
public @NotNull ISentryLifecycleToken makeCurrent() {
304+
return delegate.makeCurrent();
305+
}
306+
}

0 commit comments

Comments
 (0)