Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sampled to Dynamic Sampling Context #2869

Merged
merged 3 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Add `sampled` to Dynamic Sampling Context ([#2869](https://github.com/getsentry/sentry-java/pull/2869))

## 6.27.0

### Features
Expand Down
6 changes: 6 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public final class io/sentry/Baggage {
public fun getRelease ()Ljava/lang/String;
public fun getSampleRate ()Ljava/lang/String;
public fun getSampleRateDouble ()Ljava/lang/Double;
public fun getSampled ()Ljava/lang/String;
public fun getThirdPartyHeader ()Ljava/lang/String;
public fun getTraceId ()Ljava/lang/String;
public fun getTransaction ()Ljava/lang/String;
Expand All @@ -59,6 +60,7 @@ public final class io/sentry/Baggage {
public fun setPublicKey (Ljava/lang/String;)V
public fun setRelease (Ljava/lang/String;)V
public fun setSampleRate (Ljava/lang/String;)V
public fun setSampled (Ljava/lang/String;)V
public fun setTraceId (Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUserId (Ljava/lang/String;)V
Expand All @@ -74,6 +76,7 @@ public final class io/sentry/Baggage$DSCKeys {
public static final field ENVIRONMENT Ljava/lang/String;
public static final field PUBLIC_KEY Ljava/lang/String;
public static final field RELEASE Ljava/lang/String;
public static final field SAMPLED Ljava/lang/String;
public static final field SAMPLE_RATE Ljava/lang/String;
public static final field TRACE_ID Ljava/lang/String;
public static final field TRANSACTION Ljava/lang/String;
Expand Down Expand Up @@ -2293,6 +2296,7 @@ public final class io/sentry/TraceContext : io/sentry/JsonSerializable, io/sentr
public fun getPublicKey ()Ljava/lang/String;
public fun getRelease ()Ljava/lang/String;
public fun getSampleRate ()Ljava/lang/String;
public fun getSampled ()Ljava/lang/String;
public fun getTraceId ()Lio/sentry/protocol/SentryId;
public fun getTransaction ()Ljava/lang/String;
public fun getUnknown ()Ljava/util/Map;
Expand All @@ -2312,6 +2316,7 @@ public final class io/sentry/TraceContext$JsonKeys {
public static final field ENVIRONMENT Ljava/lang/String;
public static final field PUBLIC_KEY Ljava/lang/String;
public static final field RELEASE Ljava/lang/String;
public static final field SAMPLED Ljava/lang/String;
public static final field SAMPLE_RATE Ljava/lang/String;
public static final field TRACE_ID Ljava/lang/String;
public static final field TRANSACTION Ljava/lang/String;
Expand Down Expand Up @@ -4305,6 +4310,7 @@ public final class io/sentry/util/StringUtils {
public static fun join (Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;
public static fun normalizeUUID (Ljava/lang/String;)Ljava/lang/String;
public static fun removeSurrounding (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
public static fun toString (Ljava/lang/Object;)Ljava/lang/String;
}

public final class io/sentry/util/TracingUtils {
Expand Down
28 changes: 26 additions & 2 deletions sentry/src/main/java/io/sentry/Baggage.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public static Baggage fromEvent(
baggage.setTransaction(event.getTransaction());
// we don't persist sample rate
baggage.setSampleRate(null);
baggage.setSampled(null);
baggage.freeze();
return baggage;
}
Expand Down Expand Up @@ -329,11 +330,21 @@ public void setTransaction(final @Nullable String transaction) {
return get(DSCKeys.SAMPLE_RATE);
}

@ApiStatus.Internal
public @Nullable String getSampled() {
return get(DSCKeys.SAMPLED);
}

@ApiStatus.Internal
public void setSampleRate(final @Nullable String sampleRate) {
set(DSCKeys.SAMPLE_RATE, sampleRate);
}

@ApiStatus.Internal
public void setSampled(final @Nullable String sampled) {
set(DSCKeys.SAMPLED, sampled);
}

@ApiStatus.Internal
public void set(final @NotNull String key, final @Nullable String value) {
if (mutable) {
Expand Down Expand Up @@ -374,6 +385,7 @@ public void setValuesFromTransaction(
? transaction.getName()
: null);
setSampleRate(sampleRateToString(sampleRate(samplingDecision)));
setSampled(StringUtils.toString(sampled(samplingDecision)));
}

@ApiStatus.Internal
Expand All @@ -387,6 +399,7 @@ public void setValuesFromScope(final @NotNull Scope scope, final @NotNull Sentry
setUserSegment(user != null ? getSegment(user) : null);
setTransaction(null);
setSampleRate(null);
setSampled(null);
}

private static @Nullable String getSegment(final @NotNull User user) {
Expand Down Expand Up @@ -420,6 +433,14 @@ public void setValuesFromScope(final @NotNull Scope scope, final @NotNull Sentry
return df.format(sampleRateAsDouble);
}

private static @Nullable Boolean sampled(@Nullable TracesSamplingDecision samplingDecision) {
if (samplingDecision == null) {
return null;
}

return samplingDecision.getSampled();
}

private static boolean isHighQualityTransactionName(
@Nullable TransactionNameSource transactionNameSource) {
return transactionNameSource != null
Expand Down Expand Up @@ -458,7 +479,8 @@ public TraceContext toTraceContext() {
getUserId(),
getUserSegment(),
getTransaction(),
getSampleRate());
getSampleRate(),
getSampled());
traceContext.setUnknown(getUnknown());
return traceContext;
} else {
Expand All @@ -476,6 +498,7 @@ public static final class DSCKeys {
public static final String USER_SEGMENT = "sentry-user_segment";
public static final String TRANSACTION = "sentry-transaction";
public static final String SAMPLE_RATE = "sentry-sample_rate";
public static final String SAMPLED = "sentry-sampled";

public static final List<String> ALL =
Arrays.asList(
Expand All @@ -486,6 +509,7 @@ public static final class DSCKeys {
ENVIRONMENT,
USER_SEGMENT,
TRANSACTION,
SAMPLE_RATE);
SAMPLE_RATE,
SAMPLED);
}
}
22 changes: 19 additions & 3 deletions sentry/src/main/java/io/sentry/TraceContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ public final class TraceContext implements JsonUnknown, JsonSerializable {
private final @Nullable String userSegment;
private final @Nullable String transaction;
private final @Nullable String sampleRate;
private final @Nullable String sampled;

@SuppressWarnings("unused")
private @Nullable Map<String, @NotNull Object> unknown;

TraceContext(@NotNull SentryId traceId, @NotNull String publicKey) {
this(traceId, publicKey, null, null, null, null, null, null);
this(traceId, publicKey, null, null, null, null, null, null, null);
}

TraceContext(
Expand All @@ -36,7 +37,8 @@ public final class TraceContext implements JsonUnknown, JsonSerializable {
@Nullable String userId,
@Nullable String userSegment,
@Nullable String transaction,
@Nullable String sampleRate) {
@Nullable String sampleRate,
@Nullable String sampled) {
this.traceId = traceId;
this.publicKey = publicKey;
this.release = release;
Expand All @@ -45,6 +47,7 @@ public final class TraceContext implements JsonUnknown, JsonSerializable {
this.userSegment = userSegment;
this.transaction = transaction;
this.sampleRate = sampleRate;
this.sampled = sampled;
}

@SuppressWarnings("UnusedMethod")
Expand Down Expand Up @@ -89,6 +92,10 @@ public final class TraceContext implements JsonUnknown, JsonSerializable {
return sampleRate;
}

public @Nullable String getSampled() {
return sampled;
}

/**
* @deprecated only here to support parsing legacy JSON with non flattened user
*/
Expand Down Expand Up @@ -190,6 +197,7 @@ public static final class JsonKeys {
public static final String USER_SEGMENT = "user_segment";
public static final String TRANSACTION = "transaction";
public static final String SAMPLE_RATE = "sample_rate";
public static final String SAMPLED = "sampled";
}

@Override
Expand All @@ -216,6 +224,9 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger
if (sampleRate != null) {
writer.name(TraceContext.JsonKeys.SAMPLE_RATE).value(sampleRate);
}
if (sampled != null) {
writer.name(TraceContext.JsonKeys.SAMPLED).value(sampled);
}
if (unknown != null) {
for (String key : unknown.keySet()) {
Object value = unknown.get(key);
Expand All @@ -241,6 +252,7 @@ public static final class Deserializer implements JsonDeserializer<TraceContext>
String userSegment = null;
String transaction = null;
String sampleRate = null;
String sampled = null;

Map<String, Object> unknown = null;
while (reader.peek() == JsonToken.NAME) {
Expand Down Expand Up @@ -273,6 +285,9 @@ public static final class Deserializer implements JsonDeserializer<TraceContext>
case TraceContext.JsonKeys.SAMPLE_RATE:
sampleRate = reader.nextStringOrNull();
break;
case TraceContext.JsonKeys.SAMPLED:
sampled = reader.nextStringOrNull();
break;
default:
if (unknown == null) {
unknown = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -304,7 +319,8 @@ public static final class Deserializer implements JsonDeserializer<TraceContext>
userId,
userSegment,
transaction,
sampleRate);
sampleRate,
sampled);
traceContext.setUnknown(unknown);
reader.endObject();
return traceContext;
Expand Down
8 changes: 8 additions & 0 deletions sentry/src/main/java/io/sentry/util/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,12 @@ public static String join(

return stringBuilder.toString();
}

public static @Nullable String toString(final @Nullable Object object) {
if (object == null) {
return null;
}

return object.toString();
}
}
3 changes: 2 additions & 1 deletion sentry/src/test/java/io/sentry/BaggageTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,9 @@ class BaggageTest {
baggage.setUserId(userId)
baggage.setUserSegment("segmentA")
baggage.setSampleRate((1.0 / 3.0).toString())
baggage.setSampled("true")

assertEquals("sentry-environment=production,sentry-public_key=$publicKey,sentry-release=1.0-rc.1,sentry-sample_rate=0.3333333333333333,sentry-trace_id=$traceId,sentry-transaction=TX,sentry-user_id=$userId,sentry-user_segment=segmentA", baggage.toHeaderString(null))
assertEquals("sentry-environment=production,sentry-public_key=$publicKey,sentry-release=1.0-rc.1,sentry-sample_rate=0.3333333333333333,sentry-sampled=true,sentry-trace_id=$traceId,sentry-transaction=TX,sentry-user_id=$userId,sentry-user_segment=segmentA", baggage.toHeaderString(null))
}

@Test
Expand Down
8 changes: 4 additions & 4 deletions sentry/src/test/java/io/sentry/JsonSerializerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,16 @@ class JsonSerializerTest {

@Test
fun `serializes trace context`() {
val traceContext = SentryEnvelopeHeader(null, null, TraceContext(SentryId("3367f5196c494acaae85bbbd535379ac"), "key", "release", "environment", "userId", "segment", "transaction", "0.5"))
val expected = """{"trace":{"trace_id":"3367f5196c494acaae85bbbd535379ac","public_key":"key","release":"release","environment":"environment","user_id":"userId","user_segment":"segment","transaction":"transaction","sample_rate":"0.5"}}"""
val traceContext = SentryEnvelopeHeader(null, null, TraceContext(SentryId("3367f5196c494acaae85bbbd535379ac"), "key", "release", "environment", "userId", "segment", "transaction", "0.5", "true"))
val expected = """{"trace":{"trace_id":"3367f5196c494acaae85bbbd535379ac","public_key":"key","release":"release","environment":"environment","user_id":"userId","user_segment":"segment","transaction":"transaction","sample_rate":"0.5","sampled":"true"}}"""
val json = serializeToString(traceContext)
assertEquals(expected, json)
}

@Test
fun `serializes trace context with user having null id and segment`() {
val traceContext = SentryEnvelopeHeader(null, null, TraceContext(SentryId("3367f5196c494acaae85bbbd535379ac"), "key", "release", "environment", null, null, "transaction", "0.6"))
val expected = """{"trace":{"trace_id":"3367f5196c494acaae85bbbd535379ac","public_key":"key","release":"release","environment":"environment","transaction":"transaction","sample_rate":"0.6"}}"""
val traceContext = SentryEnvelopeHeader(null, null, TraceContext(SentryId("3367f5196c494acaae85bbbd535379ac"), "key", "release", "environment", null, null, "transaction", "0.6", "false"))
val expected = """{"trace":{"trace_id":"3367f5196c494acaae85bbbd535379ac","public_key":"key","release":"release","environment":"environment","transaction":"transaction","sample_rate":"0.6","sampled":"false"}}"""
val json = serializeToString(traceContext)
assertEquals(expected, json)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class TraceContextSerializationTest {
"c052c566-6619-45f5-a61f-172802afa39a",
"f7d8662b-5551-4ef8-b6a8-090f0561a530",
"0252ec25-cd0a-4230-bd2f-936a4585637e",
"0.00000021"
"0.00000021",
"true"
)
}
private val fixture = Fixture()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"user_id": "c052c566-6619-45f5-a61f-172802afa39a",
"user_segment": "f7d8662b-5551-4ef8-b6a8-090f0561a530",
"transaction": "0252ec25-cd0a-4230-bd2f-936a4585637e",
"sample_rate": "0.00000021"
"sample_rate": "0.00000021",
"sampled": "true"
},
"sent_at": "2020-02-07T14:16:00.000Z"
}
3 changes: 2 additions & 1 deletion sentry/src/test/resources/json/trace_state.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"user_id": "c052c566-6619-45f5-a61f-172802afa39a",
"user_segment": "f7d8662b-5551-4ef8-b6a8-090f0561a530",
"transaction": "0252ec25-cd0a-4230-bd2f-936a4585637e",
"sample_rate": "0.00000021"
"sample_rate": "0.00000021",
"sampled": "true"
}