Skip to content

Commit 1df9f12

Browse files
committed
Wire up Metrics parts
1 parent b324629 commit 1df9f12

File tree

7 files changed

+142
-2
lines changed

7 files changed

+142
-2
lines changed

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
@@ -18,6 +18,7 @@ import io.sentry.SentryEnvelope
1818
import io.sentry.SentryEvent
1919
import io.sentry.SentryLogEvent
2020
import io.sentry.SentryLogEvents
21+
import io.sentry.SentryMetricsEvent
2122
import io.sentry.SentryMetricsEvents
2223
import io.sentry.SentryReplayEvent
2324
import io.sentry.Session
@@ -193,6 +194,10 @@ class SessionTrackingIntegrationTest {
193194
TODO("Not yet implemented")
194195
}
195196

197+
override fun captureMetric(event: SentryMetricsEvent, scope: IScope?) {
198+
TODO("Not yet implemented")
199+
}
200+
196201
override fun captureBatchedMetricsEvents(metricsEvents: SentryMetricsEvents) {
197202
TODO("Not yet implemented")
198203
}

sentry/api/sentry.api

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ public abstract interface class io/sentry/EventProcessor {
461461
public fun getOrder ()Ljava/lang/Long;
462462
public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
463463
public fun process (Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent;
464+
public fun process (Lio/sentry/SentryMetricsEvent;)Lio/sentry/SentryMetricsEvent;
464465
public fun process (Lio/sentry/SentryReplayEvent;Lio/sentry/Hint;)Lio/sentry/SentryReplayEvent;
465466
public fun process (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction;
466467
}
@@ -1045,6 +1046,7 @@ public abstract interface class io/sentry/ISentryClient {
10451046
public abstract fun captureLog (Lio/sentry/SentryLogEvent;Lio/sentry/IScope;)V
10461047
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;)Lio/sentry/protocol/SentryId;
10471048
public fun captureMessage (Ljava/lang/String;Lio/sentry/SentryLevel;Lio/sentry/IScope;)Lio/sentry/protocol/SentryId;
1049+
public abstract fun captureMetric (Lio/sentry/SentryMetricsEvent;Lio/sentry/IScope;)V
10481050
public abstract fun captureProfileChunk (Lio/sentry/ProfileChunk;Lio/sentry/IScope;)Lio/sentry/protocol/SentryId;
10491051
public abstract fun captureReplayEvent (Lio/sentry/SentryReplayEvent;Lio/sentry/IScope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
10501052
public fun captureSession (Lio/sentry/Session;)V
@@ -2859,6 +2861,7 @@ public final class io/sentry/SentryClient : io/sentry/ISentryClient {
28592861
public fun captureEvent (Lio/sentry/SentryEvent;Lio/sentry/IScope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
28602862
public fun captureFeedback (Lio/sentry/protocol/Feedback;Lio/sentry/Hint;Lio/sentry/IScope;)Lio/sentry/protocol/SentryId;
28612863
public fun captureLog (Lio/sentry/SentryLogEvent;Lio/sentry/IScope;)V
2864+
public fun captureMetric (Lio/sentry/SentryMetricsEvent;Lio/sentry/IScope;)V
28622865
public fun captureProfileChunk (Lio/sentry/ProfileChunk;Lio/sentry/IScope;)Lio/sentry/protocol/SentryId;
28632866
public fun captureReplayEvent (Lio/sentry/SentryReplayEvent;Lio/sentry/IScope;Lio/sentry/Hint;)Lio/sentry/protocol/SentryId;
28642867
public fun captureSession (Lio/sentry/Session;Lio/sentry/Hint;)V
@@ -3755,13 +3758,15 @@ public abstract interface class io/sentry/SentryOptions$Logs$BeforeSendLogCallba
37553758
public final class io/sentry/SentryOptions$Metrics {
37563759
public fun <init> ()V
37573760
public fun getBeforeSend ()Lio/sentry/SentryOptions$Metrics$BeforeSendMetricCallback;
3761+
public fun getMetricsBatchProcessorFactory ()Lio/sentry/metrics/IMetricsBatchProcessorFactory;
37583762
public fun isEnabled ()Z
37593763
public fun setBeforeSend (Lio/sentry/SentryOptions$Metrics$BeforeSendMetricCallback;)V
37603764
public fun setEnabled (Z)V
3765+
public fun setMetricsBatchProcessorFactory (Lio/sentry/metrics/IMetricsBatchProcessorFactory;)V
37613766
}
37623767

37633768
public abstract interface class io/sentry/SentryOptions$Metrics$BeforeSendMetricCallback {
3764-
public abstract fun execute (Lio/sentry/SentryMetricsEvents;)Lio/sentry/SentryMetricsEvents;
3769+
public abstract fun execute (Lio/sentry/SentryMetricsEvent;)Lio/sentry/SentryMetricsEvent;
37653770
}
37663771

37673772
public abstract interface class io/sentry/SentryOptions$OnDiscardCallback {

sentry/src/main/java/io/sentry/EventProcessor.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ default SentryLogEvent process(@NotNull SentryLogEvent event) {
5656
return event;
5757
}
5858

59+
/**
60+
* May mutate or drop a SentryMetricsEvent
61+
*
62+
* @param event the SentryMetricsEvent
63+
* @return the event itself, a mutated SentryMetricsEvent or null
64+
*/
65+
@Nullable
66+
default SentryMetricsEvent process(@NotNull SentryMetricsEvent event) {
67+
return event;
68+
}
69+
5970
/**
6071
* Controls when this EventProcessor is invoked.
6172
*

sentry/src/main/java/io/sentry/ISentryClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ SentryId captureProfileChunk(
305305

306306
void captureLog(@NotNull SentryLogEvent logEvent, @Nullable IScope scope);
307307

308+
void captureMetric(@NotNull SentryMetricsEvent logEvent, @Nullable IScope scope);
309+
308310
@ApiStatus.Internal
309311
void captureBatchedLogEvents(@NotNull SentryLogEvents logEvents);
310312

sentry/src/main/java/io/sentry/NoOpSentryClient.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ public void captureLog(@NotNull SentryLogEvent logEvent, @Nullable IScope scope)
8888
// do nothing
8989
}
9090

91+
@Override
92+
public void captureMetric(@NotNull SentryMetricsEvent metricsEvent, @Nullable IScope scope) {
93+
// do nothing
94+
}
95+
9196
@ApiStatus.Internal
9297
@Override
9398
public void captureBatchedLogEvents(@NotNull SentryLogEvents logEvents) {

sentry/src/main/java/io/sentry/SentryClient.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import io.sentry.hints.TransactionEnd;
1111
import io.sentry.logger.ILoggerBatchProcessor;
1212
import io.sentry.logger.NoOpLoggerBatchProcessor;
13+
import io.sentry.metrics.IMetricsBatchProcessor;
14+
import io.sentry.metrics.NoOpMetricsBatchProcessor;
1315
import io.sentry.protocol.Contexts;
1416
import io.sentry.protocol.DebugMeta;
1517
import io.sentry.protocol.FeatureFlags;
@@ -42,6 +44,7 @@ public final class SentryClient implements ISentryClient {
4244
private final @NotNull ITransport transport;
4345
private final @NotNull SortBreadcrumbsByDate sortBreadcrumbsByDate = new SortBreadcrumbsByDate();
4446
private final @NotNull ILoggerBatchProcessor loggerBatchProcessor;
47+
private final @NotNull IMetricsBatchProcessor metricsBatchProcessor;
4548

4649
@Override
4750
public boolean isEnabled() {
@@ -66,6 +69,12 @@ public SentryClient(final @NotNull SentryOptions options) {
6669
} else {
6770
loggerBatchProcessor = NoOpLoggerBatchProcessor.getInstance();
6871
}
72+
if (options.getMetrics().isEnabled()) {
73+
metricsBatchProcessor =
74+
options.getMetrics().getMetricsBatchProcessorFactory().create(options, this);
75+
} else {
76+
metricsBatchProcessor = NoOpMetricsBatchProcessor.getInstance();
77+
}
6978
}
7079

7180
private boolean shouldApplyScopeData(
@@ -506,6 +515,38 @@ private SentryLogEvent processLogEvent(
506515
return event;
507516
}
508517

518+
@Nullable
519+
private SentryMetricsEvent processMetricsEvent(
520+
@NotNull SentryMetricsEvent event, final @NotNull List<EventProcessor> eventProcessors) {
521+
for (final EventProcessor processor : eventProcessors) {
522+
try {
523+
event = processor.process(event);
524+
} catch (Throwable e) {
525+
options
526+
.getLogger()
527+
.log(
528+
SentryLevel.ERROR,
529+
e,
530+
"An exception occurred while processing metrics event by processor: %s",
531+
processor.getClass().getName());
532+
}
533+
534+
if (event == null) {
535+
options
536+
.getLogger()
537+
.log(
538+
SentryLevel.DEBUG,
539+
"Metrics event was dropped by a processor: %s",
540+
processor.getClass().getName());
541+
options
542+
.getClientReportRecorder()
543+
.recordLostEvent(DiscardReason.EVENT_PROCESSOR, DataCategory.TraceMetric);
544+
break;
545+
}
546+
}
547+
return event;
548+
}
549+
509550
private @Nullable SentryTransaction processTransaction(
510551
@NotNull SentryTransaction transaction,
511552
final @NotNull Hint hint,
@@ -1235,6 +1276,40 @@ public void captureBatchedLogEvents(final @NotNull SentryLogEvents logEvents) {
12351276
}
12361277
}
12371278

1279+
@ApiStatus.Experimental
1280+
@Override
1281+
public void captureMetric(@Nullable SentryMetricsEvent metricsEvent, @Nullable IScope scope) {
1282+
if (metricsEvent != null && scope != null) {
1283+
metricsEvent = processMetricsEvent(metricsEvent, scope.getEventProcessors());
1284+
if (metricsEvent == null) {
1285+
return;
1286+
}
1287+
}
1288+
1289+
if (metricsEvent != null) {
1290+
metricsEvent = processMetricsEvent(metricsEvent, options.getEventProcessors());
1291+
if (metricsEvent == null) {
1292+
return;
1293+
}
1294+
}
1295+
1296+
if (metricsEvent != null) {
1297+
metricsEvent = executeBeforeSendMetric(metricsEvent);
1298+
1299+
if (metricsEvent == null) {
1300+
options
1301+
.getLogger()
1302+
.log(SentryLevel.DEBUG, "Metrics Event was dropped by beforeSendMetrics");
1303+
options
1304+
.getClientReportRecorder()
1305+
.recordLostEvent(DiscardReason.BEFORE_SEND, DataCategory.TraceMetric);
1306+
return;
1307+
}
1308+
1309+
metricsBatchProcessor.add(metricsEvent);
1310+
}
1311+
}
1312+
12381313
@ApiStatus.Internal
12391314
@Override
12401315
public void captureBatchedMetricsEvents(final @NotNull SentryMetricsEvents metricsEvents) {
@@ -1550,6 +1625,27 @@ private void sortBreadcrumbsByDate(
15501625
return event;
15511626
}
15521627

1628+
private @Nullable SentryMetricsEvent executeBeforeSendMetric(@NotNull SentryMetricsEvent event) {
1629+
final SentryOptions.Metrics.BeforeSendMetricCallback beforeSendMetric =
1630+
options.getMetrics().getBeforeSend();
1631+
if (beforeSendMetric != null) {
1632+
try {
1633+
event = beforeSendMetric.execute(event);
1634+
} catch (Throwable e) {
1635+
options
1636+
.getLogger()
1637+
.log(
1638+
SentryLevel.ERROR,
1639+
"The BeforeSendMetric callback threw an exception. Dropping metrics event.",
1640+
e);
1641+
1642+
// drop event in case of an error in beforeSendMetric due to PII concerns
1643+
event = null;
1644+
}
1645+
}
1646+
return event;
1647+
}
1648+
15531649
@Override
15541650
public void close() {
15551651
close(false);

sentry/src/main/java/io/sentry/SentryOptions.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import io.sentry.internal.viewhierarchy.ViewHierarchyExporter;
1818
import io.sentry.logger.DefaultLoggerBatchProcessorFactory;
1919
import io.sentry.logger.ILoggerBatchProcessorFactory;
20+
import io.sentry.metrics.DefaultMetricsBatchProcessorFactory;
21+
import io.sentry.metrics.IMetricsBatchProcessorFactory;
2022
import io.sentry.protocol.SdkVersion;
2123
import io.sentry.protocol.SentryTransaction;
2224
import io.sentry.transport.ITransport;
@@ -3750,6 +3752,9 @@ public static final class Metrics {
37503752
*/
37513753
private @Nullable BeforeSendMetricCallback beforeSend;
37523754

3755+
private @NotNull IMetricsBatchProcessorFactory metricsBatchProcessorFactory =
3756+
new DefaultMetricsBatchProcessorFactory();
3757+
37533758
/**
37543759
* Whether Sentry Metrics feature is enabled and metrics are sent to Sentry.
37553760
*
@@ -3786,6 +3791,17 @@ public void setBeforeSend(@Nullable BeforeSendMetricCallback beforeSend) {
37863791
this.beforeSend = beforeSend;
37873792
}
37883793

3794+
@ApiStatus.Internal
3795+
public @NotNull IMetricsBatchProcessorFactory getMetricsBatchProcessorFactory() {
3796+
return metricsBatchProcessorFactory;
3797+
}
3798+
3799+
@ApiStatus.Internal
3800+
public void setMetricsBatchProcessorFactory(
3801+
final @NotNull IMetricsBatchProcessorFactory metricsBatchProcessorFactory) {
3802+
this.metricsBatchProcessorFactory = metricsBatchProcessorFactory;
3803+
}
3804+
37893805
public interface BeforeSendMetricCallback {
37903806

37913807
/**
@@ -3795,7 +3811,7 @@ public interface BeforeSendMetricCallback {
37953811
* @return the original metric, mutated metric or null if metric was dropped
37963812
*/
37973813
@Nullable
3798-
SentryMetricsEvents execute(@NotNull SentryMetricsEvents metric);
3814+
SentryMetricsEvent execute(@NotNull SentryMetricsEvent metric);
37993815
}
38003816
}
38013817

0 commit comments

Comments
 (0)