Skip to content

Commit 32460b3

Browse files
authored
Merge branch 'main' into feat/span-level-measurement
2 parents afde400 + 39e3ed7 commit 32460b3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3251
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- Fix hub restore point in wrappers: SentryWrapper, SentryTaskDecorator and SentryScheduleHook ([#3225](https://github.com/getsentry/sentry-java/pull/3225))
1616
- We now reset the hub to its previous value on the thread where the `Runnable`/`Callable`/`Supplier` is executed instead of setting it to the hub that was used on the thread where the `Runnable`/`Callable`/`Supplier` was created.
1717
- Fix add missing thread name/id to app start spans ([#3226](https://github.com/getsentry/sentry-java/pull/3226))
18+
- Experimental: Add Metrics API ([#3205](https://github.com/getsentry/sentry-java/pull/3205))
1819

1920
## 7.4.0
2021

sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ class ActivityLifecycleIntegrationTest {
10241024
// Assert the ttfd span is running and a timeout autoCancel task has been scheduled
10251025
assertNotNull(ttfdSpan)
10261026
assertFalse(ttfdSpan.isFinished)
1027-
assertTrue(deferredExecutorService.scheduledRunnables.isNotEmpty())
1027+
assertTrue(deferredExecutorService.hasScheduledRunnables())
10281028

10291029
// Run the autoClose task and assert the ttfd span is finished with deadlineExceeded
10301030
deferredExecutorService.runAll()

sentry-android-core/src/test/java/io/sentry/android/core/SessionTrackingIntegrationTest.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.test.core.app.ApplicationProvider
88
import androidx.test.ext.junit.runners.AndroidJUnit4
99
import io.sentry.CheckIn
1010
import io.sentry.Hint
11+
import io.sentry.IMetricsAggregator
1112
import io.sentry.IScope
1213
import io.sentry.ISentryClient
1314
import io.sentry.ProfilingTraceData
@@ -174,5 +175,9 @@ class SessionTrackingIntegrationTest {
174175
override fun getRateLimiter(): RateLimiter? {
175176
TODO("Not yet implemented")
176177
}
178+
179+
override fun getMetricsAggregator(): IMetricsAggregator {
180+
TODO("Not yet implemented")
181+
}
177182
}
178183
}

sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MyApplication.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.app.Application;
44
import android.os.StrictMode;
5+
import io.sentry.Sentry;
56

67
/** Apps. main Application. */
78
public class MyApplication extends Application {
@@ -24,6 +25,8 @@ public void onCreate() {
2425
// });
2526
// */
2627
// });
28+
29+
Sentry.metrics().increment("app.start.cold");
2730
}
2831

2932
private void strictMode() {

sentry-test-support/api/sentry-test-support.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public final class io/sentry/SkipError : java/lang/Error {
1414
public final class io/sentry/test/DeferredExecutorService : io/sentry/ISentryExecutorService {
1515
public fun <init> ()V
1616
public fun close (J)V
17-
public final fun getScheduledRunnables ()Ljava/util/ArrayList;
17+
public final fun hasScheduledRunnables ()Z
1818
public fun isClosed ()Z
1919
public final fun runAll ()V
2020
public fun schedule (Ljava/lang/Runnable;J)Ljava/util/concurrent/Future;

sentry-test-support/src/main/kotlin/io/sentry/test/Mocks.kt

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,40 @@ class ImmediateExecutorService : ISentryExecutorService {
2828

2929
class DeferredExecutorService : ISentryExecutorService {
3030

31-
private val runnables = ArrayList<Runnable>()
32-
val scheduledRunnables = ArrayList<Runnable>()
31+
private var runnables = ArrayList<Runnable>()
32+
private var scheduledRunnables = ArrayList<Runnable>()
3333

3434
fun runAll() {
35-
runnables.forEach { it.run() }
36-
scheduledRunnables.forEach { it.run() }
35+
// take a snapshot of the runnable list in case
36+
// executing the runnable itself schedules more runnables
37+
val currentRunnableList = runnables
38+
val currentScheduledRunnableList = scheduledRunnables
39+
40+
synchronized(this) {
41+
runnables = ArrayList()
42+
scheduledRunnables = ArrayList()
43+
}
44+
45+
currentRunnableList.forEach { it.run() }
46+
currentScheduledRunnableList.forEach { it.run() }
3747
}
3848

3949
override fun submit(runnable: Runnable): Future<*> {
40-
runnables.add(runnable)
50+
synchronized(this) {
51+
runnables.add(runnable)
52+
}
4153
return mock()
4254
}
4355

4456
override fun <T> submit(callable: Callable<T>): Future<T> = mock()
4557
override fun schedule(runnable: Runnable, delayMillis: Long): Future<*> {
46-
scheduledRunnables.add(runnable)
58+
synchronized(this) {
59+
scheduledRunnables.add(runnable)
60+
}
4761
return mock()
4862
}
4963
override fun close(timeoutMillis: Long) {}
5064
override fun isClosed(): Boolean = false
65+
66+
fun hasScheduledRunnables(): Boolean = scheduledRunnables.isNotEmpty()
5167
}

sentry/api/sentry.api

Lines changed: 203 additions & 2 deletions
Large diffs are not rendered by default.

sentry/src/main/java/io/sentry/Hub.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.sentry.clientreport.DiscardReason;
55
import io.sentry.hints.SessionEndHint;
66
import io.sentry.hints.SessionStartHint;
7+
import io.sentry.metrics.MetricsApi;
78
import io.sentry.protocol.SentryId;
89
import io.sentry.protocol.SentryTransaction;
910
import io.sentry.protocol.User;
@@ -17,14 +18,16 @@
1718
import java.io.IOException;
1819
import java.lang.ref.WeakReference;
1920
import java.util.Collections;
21+
import java.util.HashMap;
2022
import java.util.List;
2123
import java.util.Map;
2224
import java.util.WeakHashMap;
2325
import org.jetbrains.annotations.ApiStatus;
2426
import org.jetbrains.annotations.NotNull;
2527
import org.jetbrains.annotations.Nullable;
2628

27-
public final class Hub implements IHub {
29+
public final class Hub implements IHub, MetricsApi.IMetricsInterface {
30+
2831
private volatile @NotNull SentryId lastEventId;
2932
private final @NotNull SentryOptions options;
3033
private volatile boolean isEnabled;
@@ -33,10 +36,10 @@ public final class Hub implements IHub {
3336
private final @NotNull Map<Throwable, Pair<WeakReference<ISpan>, String>> throwableToSpan =
3437
Collections.synchronizedMap(new WeakHashMap<>());
3538
private final @NotNull TransactionPerformanceCollector transactionPerformanceCollector;
39+
private final @NotNull MetricsApi metricsApi;
3640

3741
public Hub(final @NotNull SentryOptions options) {
3842
this(options, createRootStackItem(options));
39-
4043
// Integrations are no longer registered on Hub ctor, but on Sentry.init
4144
}
4245

@@ -52,6 +55,8 @@ private Hub(final @NotNull SentryOptions options, final @NotNull Stack stack) {
5255
// Integrations will use this Hub instance once registered.
5356
// Make sure Hub ready to be used then.
5457
this.isEnabled = true;
58+
59+
this.metricsApi = new MetricsApi(this);
5560
}
5661

5762
private Hub(final @NotNull SentryOptions options, final @NotNull StackItem rootStackItem) {
@@ -937,4 +942,22 @@ private IScope buildLocalScope(
937942
final StackItem item = stack.peek();
938943
return item.getClient().getRateLimiter();
939944
}
945+
946+
@Override
947+
public @NotNull MetricsApi metrics() {
948+
return metricsApi;
949+
}
950+
951+
@Override
952+
public @NotNull IMetricsAggregator getMetricsAggregator() {
953+
return stack.peek().getClient().getMetricsAggregator();
954+
}
955+
956+
@Override
957+
public @NotNull Map<String, String> getDefaultTagsForMetrics() {
958+
final Map<String, String> tags = new HashMap<>(2);
959+
tags.put("release", options.getRelease());
960+
tags.put("environment", options.getEnvironment());
961+
return tags;
962+
}
940963
}

sentry/src/main/java/io/sentry/HubAdapter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry;
22

3+
import io.sentry.metrics.MetricsApi;
34
import io.sentry.protocol.SentryId;
45
import io.sentry.protocol.SentryTransaction;
56
import io.sentry.protocol.User;
@@ -272,4 +273,9 @@ public void reportFullyDisplayed() {
272273
public @Nullable RateLimiter getRateLimiter() {
273274
return Sentry.getCurrentHub().getRateLimiter();
274275
}
276+
277+
@Override
278+
public @NotNull MetricsApi metrics() {
279+
return Sentry.getCurrentHub().metrics();
280+
}
275281
}

sentry/src/main/java/io/sentry/IHub.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry;
22

3+
import io.sentry.metrics.MetricsApi;
34
import io.sentry.protocol.SentryId;
45
import io.sentry.protocol.SentryTransaction;
56
import io.sentry.protocol.User;
@@ -582,4 +583,8 @@ TransactionContext continueTrace(
582583
@ApiStatus.Internal
583584
@Nullable
584585
RateLimiter getRateLimiter();
586+
587+
@ApiStatus.Experimental
588+
@NotNull
589+
MetricsApi metrics();
585590
}

0 commit comments

Comments
 (0)