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

Feat: Add tracestate HTTP header support. #1683

Merged
merged 20 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ class SentryOkHttpInterceptor(

var code: Int? = null
try {
val requestBuilder = request.newBuilder()
span?.toSentryTrace()?.let {
request = request.newBuilder().addHeader(it.name, it.value).build()
requestBuilder.addHeader(it.name, it.value)
}
hub.traceStateHeader()?.let {
requestBuilder.addHeader(it.name, it.value)
}
request = requestBuilder.build()
response = chain.proceed(request)
code = response.code
span?.status = SpanStatus.fromHttpStatusCode(code)
Expand Down
39 changes: 39 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public final class io/sentry/Hub : io/sentry/IHub {
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;ZLjava/util/Date;)Lio/sentry/ITransaction;
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;ZLjava/util/Date;ZLio/sentry/TransactionFinishedCallback;)Lio/sentry/ITransaction;
public fun traceHeaders ()Lio/sentry/SentryTraceHeader;
public fun traceStateHeader ()Lio/sentry/TraceStateHeader;
public fun withScope (Lio/sentry/ScopeCallback;)V
}

Expand Down Expand Up @@ -178,6 +179,7 @@ public final class io/sentry/HubAdapter : io/sentry/IHub {
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;ZLjava/util/Date;)Lio/sentry/ITransaction;
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;ZLjava/util/Date;ZLio/sentry/TransactionFinishedCallback;)Lio/sentry/ITransaction;
public fun traceHeaders ()Lio/sentry/SentryTraceHeader;
public fun traceStateHeader ()Lio/sentry/TraceStateHeader;
public fun withScope (Lio/sentry/ScopeCallback;)V
}

Expand Down Expand Up @@ -240,6 +242,7 @@ public abstract interface class io/sentry/IHub {
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Ljava/util/Date;ZLio/sentry/TransactionFinishedCallback;)Lio/sentry/ITransaction;
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/ITransaction;
public abstract fun traceHeaders ()Lio/sentry/SentryTraceHeader;
public abstract fun traceStateHeader ()Lio/sentry/TraceStateHeader;
public abstract fun withScope (Lio/sentry/ScopeCallback;)V
}

Expand Down Expand Up @@ -387,6 +390,7 @@ public final class io/sentry/NoOpHub : io/sentry/IHub {
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;ZLjava/util/Date;)Lio/sentry/ITransaction;
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/CustomSamplingContext;ZLjava/util/Date;ZLio/sentry/TransactionFinishedCallback;)Lio/sentry/ITransaction;
public fun traceHeaders ()Lio/sentry/SentryTraceHeader;
public fun traceStateHeader ()Lio/sentry/TraceStateHeader;
public fun withScope (Lio/sentry/ScopeCallback;)V
}

Expand Down Expand Up @@ -680,8 +684,10 @@ public final class io/sentry/SentryEnvelopeHeader {
public fun <init> ()V
public fun <init> (Lio/sentry/protocol/SentryId;)V
public fun <init> (Lio/sentry/protocol/SentryId;Lio/sentry/protocol/SdkVersion;)V
public fun <init> (Lio/sentry/protocol/SentryId;Lio/sentry/protocol/SdkVersion;Lio/sentry/TraceState;)V
public fun getEventId ()Lio/sentry/protocol/SentryId;
public fun getSdkVersion ()Lio/sentry/protocol/SdkVersion;
public fun getTrace ()Lio/sentry/TraceState;
}

public final class io/sentry/SentryEnvelopeHeaderAdapter : com/google/gson/TypeAdapter {
Expand Down Expand Up @@ -1116,6 +1122,23 @@ public final class io/sentry/SystemOutLogger : io/sentry/ILogger {
public fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
}

public final class io/sentry/TraceState {
public fun <init> (Lio/sentry/protocol/SentryId;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/sentry/TraceState$TraceStateUser;Ljava/lang/String;)V
public fun getEnvironment ()Ljava/lang/String;
public fun getPublicKey ()Ljava/lang/String;
public fun getRelease ()Ljava/lang/String;
public fun getTraceId ()Lio/sentry/protocol/SentryId;
public fun getTransaction ()Ljava/lang/String;
public fun getUser ()Lio/sentry/TraceState$TraceStateUser;
}

public final class io/sentry/TraceStateHeader {
public fun <init> (Ljava/lang/String;)V
public static fun fromTraceState (Lio/sentry/TraceState;Lio/sentry/ISerializer;Lio/sentry/ILogger;)Lio/sentry/TraceStateHeader;
public fun getName ()Ljava/lang/String;
public fun getValue ()Ljava/lang/String;
}

public final class io/sentry/TransactionContext : io/sentry/SpanContext {
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;)V
Expand Down Expand Up @@ -1923,3 +1946,19 @@ public final class io/sentry/util/StringUtils {
public static fun removeSurrounding (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
}

public class io/sentry/vendor/Base64 {
public static final field CRLF I
public static final field DEFAULT I
public static final field NO_CLOSE I
public static final field NO_PADDING I
public static final field NO_WRAP I
public static final field URL_SAFE I
public static fun decode (Ljava/lang/String;I)[B
public static fun decode ([BI)[B
public static fun decode ([BIII)[B
public static fun encode ([BI)[B
public static fun encode ([BIII)[B
public static fun encodeToString ([BI)Ljava/lang/String;
public static fun encodeToString ([BIII)Ljava/lang/String;
}

1 change: 1 addition & 0 deletions sentry/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,5 @@ tasks.withType<JavaCompile>() {
check("NullAway", net.ltgt.gradle.errorprone.CheckSeverity.ERROR)
option("NullAway:AnnotatedPackages", "io.sentry")
}
options.errorprone.errorproneArgs.add("-XepExcludedPaths:.*/io/sentry/vendor/.*")
}
21 changes: 21 additions & 0 deletions sentry/src/main/java/io/sentry/Hub.java
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,27 @@ public void flush(long timeoutMillis) {
return traceHeader;
}

@Override
public @Nullable TraceStateHeader traceStateHeader() {
marandaneto marked this conversation as resolved.
Show resolved Hide resolved
TraceStateHeader header = null;
if (!isEnabled()) {
options
.getLogger()
.log(
SentryLevel.WARNING,
"Instance is disabled and this 'traceStateHeader' call is a no-op.");
} else {
final Scope scope = stack.peek().getScope();
final TraceState traceState = TraceState.create(scope, options);
if (traceState != null) {
header =
TraceStateHeader.fromTraceState(
traceState, options.getSerializer(), options.getLogger());
}
}
return header;
}

@Override
public @Nullable ISpan getSpan() {
ISpan span = null;
Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/HubAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ public void flush(long timeoutMillis) {
return Sentry.traceHeaders();
}

@Override
public @Nullable TraceStateHeader traceStateHeader() {
return Sentry.getCurrentHub().traceStateHeader();
}

@Override
public void setSpanContext(
final @NotNull Throwable throwable,
Expand Down
3 changes: 3 additions & 0 deletions sentry/src/main/java/io/sentry/IHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,9 @@ ITransaction startTransaction(
@Nullable
SentryTraceHeader traceHeaders();

@Nullable
TraceStateHeader traceStateHeader();

/**
* Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine
* in which trace the exception has been thrown in framework integrations.
Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ public void flush(long timeoutMillis) {}
return new SentryTraceHeader(SentryId.EMPTY_ID, SpanId.EMPTY_ID, true);
}

@Override
public @Nullable TraceStateHeader traceStateHeader() {
return null;
}

@Override
public void setSpanContext(
final @NotNull Throwable throwable,
Expand Down
21 changes: 11 additions & 10 deletions sentry/src/main/java/io/sentry/SentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ private boolean shouldApplyScopeData(
}

try {
final SentryEnvelope envelope = buildEnvelope(event, getAttachmentsFromScope(scope), session);
final SentryEnvelope envelope =
buildEnvelope(
event, getAttachmentsFromScope(scope), session, TraceState.create(scope, options));

if (envelope != null) {
transport.send(envelope, hint);
Expand All @@ -151,16 +153,11 @@ private boolean shouldApplyScopeData(
}
}

private @Nullable SentryEnvelope buildEnvelope(
final @Nullable SentryBaseEvent event, final @Nullable List<Attachment> attachments)
throws IOException {
return this.buildEnvelope(event, attachments, null);
}

private @Nullable SentryEnvelope buildEnvelope(
final @Nullable SentryBaseEvent event,
final @Nullable List<Attachment> attachments,
final @Nullable Session session)
final @Nullable Session session,
final @Nullable TraceState traceState)
throws IOException {
SentryId sentryId = null;

Expand Down Expand Up @@ -189,7 +186,7 @@ private boolean shouldApplyScopeData(

if (!envelopeItems.isEmpty()) {
final SentryEnvelopeHeader envelopeHeader =
new SentryEnvelopeHeader(sentryId, options.getSdkVersion());
new SentryEnvelopeHeader(sentryId, options.getSdkVersion(), traceState);
return new SentryEnvelope(envelopeHeader, envelopeItems);
}

Expand Down Expand Up @@ -437,7 +434,11 @@ public void captureSession(final @NotNull Session session, final @Nullable Objec

try {
final SentryEnvelope envelope =
buildEnvelope(transaction, filterForTransaction(getAttachmentsFromScope(scope)));
buildEnvelope(
transaction,
filterForTransaction(getAttachmentsFromScope(scope)),
null,
scope != null ? TraceState.create(transaction, scope, options) : null);
bruno-garcia marked this conversation as resolved.
Show resolved Hide resolved
if (envelope != null) {
transport.send(envelope, hint);
} else {
Expand Down
14 changes: 14 additions & 0 deletions sentry/src/main/java/io/sentry/SentryEnvelopeHeader.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,20 @@ public final class SentryEnvelopeHeader {

private final @Nullable SdkVersion sdkVersion;

private final @Nullable TraceState trace;

public SentryEnvelopeHeader(
final @Nullable SentryId eventId, final @Nullable SdkVersion sdkVersion) {
this(eventId, sdkVersion, null);
}

public SentryEnvelopeHeader(
final @Nullable SentryId eventId,
final @Nullable SdkVersion sdkVersion,
final @Nullable TraceState trace) {
this.eventId = eventId;
this.sdkVersion = sdkVersion;
this.trace = trace;
}

public SentryEnvelopeHeader(final @Nullable SentryId eventId) {
Expand All @@ -34,4 +44,8 @@ public SentryEnvelopeHeader() {
public @Nullable SdkVersion getSdkVersion() {
return sdkVersion;
}

public @Nullable TraceState getTrace() {
return trace;
}
}
28 changes: 28 additions & 0 deletions sentry/src/main/java/io/sentry/SentryEnvelopeHeaderAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,34 @@ public void write(final @NotNull JsonWriter writer, final @Nullable SentryEnvelo
writer.endObject();
}
}
TraceState trace = value.getTrace();
if (trace != null) {
writer.name("trace");
writer.beginObject();
writer.name("trace_id").value(trace.getTraceId().toString());
writer.name("public_key").value(trace.getPublicKey());
if (trace.getRelease() != null) {
writer.name("release").value(trace.getRelease());
}
if (trace.getEnvironment() != null) {
writer.name("environment").value(trace.getEnvironment());
}
if (trace.getTransaction() != null) {
writer.name("transaction").value(trace.getTransaction());
}
if (trace.getUser() != null) {
writer.name("user");
writer.beginObject();
if (trace.getUser().getId() != null) {
writer.name("id").value(trace.getUser().getId());
}
if (trace.getUser().getSegment() != null) {
writer.name("segment").value(trace.getUser().getSegment());
}
writer.endObject();
}
bruno-garcia marked this conversation as resolved.
Show resolved Hide resolved
writer.endObject();
}

writer.endObject();
}
Expand Down
Loading