Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
- Fix "class ch.qos.logback.classic.spi.ThrowableProxyVO cannot be cast to class ch.qos.logback.classic.spi.ThrowableProxy" ([#4206](https://github.com/getsentry/sentry-java/pull/4206))
- In this case we cannot report the `Throwable` to Sentry as it's not available
- If you are using OpenTelemetry v1 `OpenTelemetryAppender`, please consider upgrading to v2
- Pass OpenTelemetry span attributes into TracesSampler callback ([#4253](https://github.com/getsentry/sentry-java/pull/4253))
- `SamplingContext` now has a `getAttribute` method that grants access to OpenTelemetry span attributes via their String key (e.g. `http.request.method`)

### Features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import io.sentry.TransactionContext;
import io.sentry.clientreport.DiscardReason;
import io.sentry.protocol.SentryId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -64,13 +66,15 @@ public SamplingResult shouldSample(
if (samplingDecision != null) {
return new SentrySamplingResult(samplingDecision);
} else {
return handleRootOtelSpan(traceId, parentContext);
return handleRootOtelSpan(traceId, parentContext, attributes);
}
}
}

private @NotNull SamplingResult handleRootOtelSpan(
final @NotNull String traceId, final @NotNull Context parentContext) {
final @NotNull String traceId,
final @NotNull Context parentContext,
final @NotNull Attributes attributes) {
if (!scopes.getOptions().isTracingEnabled()) {
return SamplingResult.create(SamplingDecision.RECORD_ONLY);
}
Expand All @@ -96,7 +100,11 @@ public SamplingResult shouldSample(
.getOptions()
.getInternalTracesSampler()
.sample(
new SamplingContext(transactionContext, null, propagationContext.getSampleRand()));
new SamplingContext(
transactionContext,
null,
propagationContext.getSampleRand(),
toMapWithStringKeys(attributes)));

if (!sentryDecision.getSampled()) {
scopes
Expand Down Expand Up @@ -135,6 +143,22 @@ public SamplingResult shouldSample(
}
}

private @NotNull Map<String, Object> toMapWithStringKeys(final @NotNull Attributes attributes) {
final @NotNull Map<String, Object> mapWithStringKeys = new HashMap<>(attributes.size());

if (attributes != null) {
attributes.forEach(
(key, value) -> {
if (key != null) {
final @NotNull String stringKey = key.getKey();
mapWithStringKeys.put(stringKey, value);
}
});
}

return mapWithStringKeys;
}

@Override
public String getDescription() {
return "SentrySampler";
Expand Down
3 changes: 2 additions & 1 deletion sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -2023,7 +2023,8 @@ public final class io/sentry/RequestDetails {

public final class io/sentry/SamplingContext {
public fun <init> (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;)V
public fun <init> (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;Ljava/lang/Double;)V
public fun <init> (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;Ljava/lang/Double;Ljava/util/Map;)V
public fun getAttribute (Ljava/lang/String;)Ljava/lang/Object;
public fun getCustomSamplingContext ()Lio/sentry/CustomSamplingContext;
public fun getSampleRand ()Ljava/lang/Double;
public fun getTransactionContext ()Lio/sentry/TransactionContext;
Expand Down
16 changes: 14 additions & 2 deletions sentry/src/main/java/io/sentry/SamplingContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import io.sentry.util.Objects;
import io.sentry.util.SentryRandom;
import java.util.Collections;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -14,6 +16,7 @@ public final class SamplingContext {
private final @NotNull TransactionContext transactionContext;
private final @Nullable CustomSamplingContext customSamplingContext;
private final @NotNull Double sampleRand;
private final @NotNull Map<String, Object> attributes;

@Deprecated
@SuppressWarnings("InlineMeSuggester")
Expand All @@ -23,18 +26,20 @@ public final class SamplingContext {
public SamplingContext(
final @NotNull TransactionContext transactionContext,
final @Nullable CustomSamplingContext customSamplingContext) {
this(transactionContext, customSamplingContext, SentryRandom.current().nextDouble());
this(transactionContext, customSamplingContext, SentryRandom.current().nextDouble(), null);
}

@ApiStatus.Internal
public SamplingContext(
final @NotNull TransactionContext transactionContext,
final @Nullable CustomSamplingContext customSamplingContext,
final @NotNull Double sampleRand) {
final @NotNull Double sampleRand,
final @Nullable Map<String, Object> attributes) {
this.transactionContext =
Objects.requireNonNull(transactionContext, "transactionContexts is required");
this.customSamplingContext = customSamplingContext;
this.sampleRand = sampleRand;
this.attributes = attributes == null ? Collections.emptyMap() : attributes;
}

public @Nullable CustomSamplingContext getCustomSamplingContext() {
Expand All @@ -48,4 +53,11 @@ public SamplingContext(
public @NotNull Double getSampleRand() {
return sampleRand;
}

public @Nullable Object getAttribute(final @Nullable String key) {
if (key == null) {
return null;
}
return this.attributes.get(key);
}
}
2 changes: 1 addition & 1 deletion sentry/src/main/java/io/sentry/Scopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ public void flush(long timeoutMillis) {
final Double sampleRand = getSampleRand(transactionContext);
final SamplingContext samplingContext =
new SamplingContext(
transactionContext, transactionOptions.getCustomSamplingContext(), sampleRand);
transactionContext, transactionOptions.getCustomSamplingContext(), sampleRand, null);
final @NotNull TracesSampler tracesSampler = getOptions().getInternalTracesSampler();
@NotNull TracesSamplingDecision samplingDecision = tracesSampler.sample(samplingContext);
transactionContext.setSamplingDecision(samplingDecision);
Expand Down
3 changes: 2 additions & 1 deletion sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,8 @@ private static void handleAppStartProfilingConfig(
TransactionContext appStartTransactionContext = new TransactionContext("app.launch", "profile");
appStartTransactionContext.setForNextAppStart(true);
SamplingContext appStartSamplingContext =
new SamplingContext(appStartTransactionContext, null, SentryRandom.current().nextDouble());
new SamplingContext(
appStartTransactionContext, null, SentryRandom.current().nextDouble(), null);
return options.getInternalTracesSampler().sample(appStartSamplingContext);
}

Expand Down
Loading
Loading