Skip to content

Commit

Permalink
Open up some transaction methods (#2701)
Browse files Browse the repository at this point in the history
  • Loading branch information
lbloder committed May 10, 2023
1 parent 9fed939 commit e96a1b7
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- Auxiliary information (such as current memory load) at the time of ANR event.
- If you would like us to provide support for the old approach working alongside the new one on Android 11 and above (e.g. for raising events for slow code on main thread), consider upvoting [this issue](https://github.com/getsentry/sentry-java/issues/2693).
- The old watchdog implementation will continue working for older API versions (Android < 11)
- Open up `TransactionOptions`, `ITransaction` and `IHub` methods allowing consumers modify start/end timestamp of transactions and spans ([#2701](https://github.com/getsentry/sentry-java/pull/2701))

### Fixes

Expand Down
3 changes: 3 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ public abstract interface class io/sentry/ITransaction : io/sentry/ISpan {
public abstract fun setContext (Ljava/lang/String;Ljava/lang/Object;)V
public abstract fun setName (Ljava/lang/String;)V
public abstract fun setName (Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
public abstract fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;)Lio/sentry/ISpan;
}

public abstract interface class io/sentry/ITransactionProfiler {
Expand Down Expand Up @@ -924,6 +925,7 @@ public final class io/sentry/NoOpTransaction : io/sentry/ITransaction {
public fun setThrowable (Ljava/lang/Throwable;)V
public fun startChild (Ljava/lang/String;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;Lio/sentry/Instrumenter;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;Lio/sentry/Instrumenter;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
Expand Down Expand Up @@ -1916,6 +1918,7 @@ public final class io/sentry/SentryTracer : io/sentry/ITransaction {
public fun setThrowable (Ljava/lang/Throwable;)V
public fun startChild (Ljava/lang/String;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;Lio/sentry/Instrumenter;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryDate;Lio/sentry/Instrumenter;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
public fun startChild (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SpanOptions;)Lio/sentry/ISpan;
Expand Down
10 changes: 9 additions & 1 deletion sentry/src/main/java/io/sentry/IHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,15 @@ ITransaction startTransaction(
return startTransaction(name, operation, null);
}

@ApiStatus.Internal
/**
* Creates a Transaction and returns the instance. Based on the passed transaction context and
* transaction options the decision if transaction is sampled will be taken by {@link
* TracesSampler}.
*
* @param transactionContext the transaction context
* @param transactionOptions the transaction options
* @return created transaction.
*/
@NotNull
ITransaction startTransaction(
final @NotNull TransactionContext transactionContext,
Expand Down
12 changes: 12 additions & 0 deletions sentry/src/main/java/io/sentry/ITransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ public interface ITransaction extends ISpan {
@TestOnly
List<Span> getSpans();

/**
* Starts a child Span.
*
* @param operation - new span operation name
* @param description - the span description
* @param timestamp - the start timestamp of the span
* @return a new transaction span
*/
@NotNull
ISpan startChild(
@NotNull String operation, @Nullable String description, @Nullable SentryDate timestamp);

/**
* Returns if transaction is sampled.
*
Expand Down
6 changes: 6 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ public void setName(@NotNull String name, @NotNull TransactionNameSource transac
return Collections.emptyList();
}

@Override
public @NotNull ISpan startChild(
@NotNull String operation, @Nullable String description, @Nullable SentryDate timestamp) {
return NoOpSpan.getInstance();
}

@Override
public @Nullable Span getLatestActiveSpan() {
return null;
Expand Down
1 change: 0 additions & 1 deletion sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,6 @@ public static void endSession() {
* @param transactionOptions options for the transaction
* @return created transaction.
*/
@ApiStatus.Internal
public static @NotNull ITransaction startTransaction(
final @NotNull TransactionContext transactionContext,
final @NotNull TransactionOptions transactionOptions) {
Expand Down
8 changes: 8 additions & 0 deletions sentry/src/main/java/io/sentry/SentryTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,14 @@ private ISpan createChild(
return createChild(operation, description, timestamp, instrumenter, spanOptions);
}

@Override
public @NotNull ISpan startChild(
final @NotNull String operation,
@Nullable String description,
@Nullable SentryDate timestamp) {
return createChild(operation, description, timestamp, Instrumenter.SENTRY, new SpanOptions());
}

@Override
public @NotNull ISpan startChild(
final @NotNull String operation, final @Nullable String description) {
Expand Down
93 changes: 83 additions & 10 deletions sentry/src/main/java/io/sentry/TransactionOptions.java
Original file line number Diff line number Diff line change
@@ -1,76 +1,149 @@
package io.sentry;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Internal
/** Sentry Transaction options */
public final class TransactionOptions extends SpanOptions {

/**
* Arbitrary data used in {@link SamplingContext} to determine if transaction is going to be
* sampled.
*/
private @Nullable CustomSamplingContext customSamplingContext = null;

/** Defines if transaction should be bound to scope */
private boolean bindToScope = false;

/** The start timestamp of the transaction */
private @Nullable SentryDate startTimestamp = null;

/**
* When `waitForChildren` is set to `true`, tracer will finish only when both conditions are met
* (the order of meeting condition does not matter): - tracer itself is finished - all child spans
* are finished.
*/
private boolean waitForChildren = false;

/**
* The idle time, measured in ms, to wait until the transaction will be finished. The span will
* use the end timestamp of the last finished span as the endtime for the transaction.
*
* <p>When set to {@code null} the transaction must be finished manually.
*
* <p>The default is 3 seconds.
*/
private @Nullable Long idleTimeout = null;

/**
* When `waitForChildren` is set to `true` and this callback is set, it's called before the
* transaction is captured.
*/
private @Nullable TransactionFinishedCallback transactionFinishedCallback = null;

/**
* Gets the customSamplingContext
*
* @return customSamplingContext - the customSamplingContext
*/
public @Nullable CustomSamplingContext getCustomSamplingContext() {
return customSamplingContext;
}

/**
* Sets the customSamplingContext
*
* @param customSamplingContext - the customSamplingContext
*/
public void setCustomSamplingContext(@Nullable CustomSamplingContext customSamplingContext) {
this.customSamplingContext = customSamplingContext;
}

/**
* Checks if bindToScope is enabled
*
* @return true if enabled or false otherwise
*/
public boolean isBindToScope() {
return bindToScope;
}

/**
* Sets bindToScope to enabled or disabled
*
* @param bindToScope true if enabled or false otherwise
*/
public void setBindToScope(boolean bindToScope) {
this.bindToScope = bindToScope;
}

/**
* Gets the startTimestamp
*
* @return startTimestamp - the startTimestamp
*/
public @Nullable SentryDate getStartTimestamp() {
return startTimestamp;
}

/**
* Sets the startTimestamp
*
* @param startTimestamp - the startTimestamp
*/
public void setStartTimestamp(@Nullable SentryDate startTimestamp) {
this.startTimestamp = startTimestamp;
}

/**
* When `waitForChildren` is set to `true`, tracer will finish only when both conditions are met
* (the order of meeting condition does not matter): - tracer itself is finished - all child spans
* are finished.
* Checks if waitForChildren is enabled
*
* @return true if enabled or false otherwise
*/
public boolean isWaitForChildren() {
return waitForChildren;
}

/**
* Sets waitForChildren to enabled or disabled
*
* @param waitForChildren true if enabled or false otherwise
*/
public void setWaitForChildren(boolean waitForChildren) {
this.waitForChildren = waitForChildren;
}

/**
* The idle time, measured in ms, to wait until the transaction will be finished. The span will
* use the end timestamp of the last finished span as the endtime for the transaction.
*
* <p>When set to {@code null} the transaction must be finished manually.
* Gets the idleTimeout
*
* <p>The default is 3 seconds.
* @return idleTimeout - the idleTimeout
*/
public @Nullable Long getIdleTimeout() {
return idleTimeout;
}

/**
* Sets the idleTimeout
*
* @param idleTimeout - the idleTimeout
*/
public void setIdleTimeout(@Nullable Long idleTimeout) {
this.idleTimeout = idleTimeout;
}

/**
* Gets the transactionFinishedCallback callback
*
* @return transactionFinishedCallback - the transactionFinishedCallback callback
*/
public @Nullable TransactionFinishedCallback getTransactionFinishedCallback() {
return transactionFinishedCallback;
}

/**
* Sets the transactionFinishedCallback callback
*
* @param transactionFinishedCallback - the transactionFinishedCallback callback
*/
public void setTransactionFinishedCallback(
@Nullable TransactionFinishedCallback transactionFinishedCallback) {
this.transactionFinishedCallback = transactionFinishedCallback;
Expand Down
4 changes: 4 additions & 0 deletions sentry/src/test/java/io/sentry/NoOpTransactionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class NoOpTransactionTest {
fun `startChild does not return null`() {
assertNotNull(transaction.startChild("op"))
assertNotNull(transaction.startChild("op", "desc"))
assertNotNull(transaction.startChild("op", "desc", SpanOptions()))
assertNotNull(transaction.startChild("op", "desc", SentryNanotimeDate()))
assertNotNull(transaction.startChild("op", "desc", SentryNanotimeDate(), Instrumenter.SENTRY))
assertNotNull(transaction.startChild("op", "desc", SentryNanotimeDate(), Instrumenter.SENTRY, SpanOptions()))
}

@Test
Expand Down
21 changes: 21 additions & 0 deletions sentry/src/test/java/io/sentry/SentryTracerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,27 @@ class SentryTracerTest {
assertEquals(tracer.root.traceId, span.traceId)
}

@Test
fun `starting child with operation, description and timestamp creates a new span`() {
val tracer = fixture.getSut()
val sentryDate = SentryNanotimeDate()
val span = tracer.startChild("op", "description", sentryDate) as Span
assertNotNull(span)
assertNotNull(span.spanId)
assertNotNull(span.startDate)
assertEquals("op", span.operation)
assertEquals("description", span.description)
assertEquals(sentryDate, span.startDate)
}

@Test
fun `sstarting child with operation, description and timestamp adds a span to transaction`() {
val tracer = fixture.getSut()
val span = tracer.startChild("op", "description", SentryNanotimeDate())
assertEquals(1, tracer.children.size)
assertEquals(span, tracer.children.first())
}

@Test
fun `setting op sets op on TraceContext`() {
val tracer = fixture.getSut()
Expand Down

0 comments on commit e96a1b7

Please sign in to comment.