-
-
Notifications
You must be signed in to change notification settings - Fork 435
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Measure app start time (#1487)
- Loading branch information
1 parent
97c6a66
commit 4af15fa
Showing
30 changed files
with
1,045 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
sentry-android-core/src/main/java/io/sentry/android/core/AppStartState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package io.sentry.android.core; | ||
|
||
import android.os.SystemClock; | ||
import java.util.Date; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.jetbrains.annotations.TestOnly; | ||
|
||
/** AppStartState holds the state of the App Start metric and appStartTime */ | ||
final class AppStartState { | ||
|
||
private static @NotNull AppStartState instance = new AppStartState(); | ||
|
||
private @Nullable Long appStartMillis; | ||
|
||
private @Nullable Long appStartEndMillis; | ||
|
||
/** The type of App start coldStart=true -> Cold start, coldStart=false -> Warm start */ | ||
private boolean coldStart; | ||
|
||
/** appStart as a Date used in the App's Context */ | ||
private @Nullable Date appStartTime; | ||
|
||
private AppStartState() {} | ||
|
||
static @NotNull AppStartState getInstance() { | ||
return instance; | ||
} | ||
|
||
@TestOnly | ||
void resetInstance() { | ||
instance = new AppStartState(); | ||
} | ||
|
||
synchronized void setAppStartEnd() { | ||
setAppStartEnd(SystemClock.uptimeMillis()); | ||
} | ||
|
||
@TestOnly | ||
void setAppStartEnd(final long appStartEndMillis) { | ||
this.appStartEndMillis = appStartEndMillis; | ||
} | ||
|
||
@Nullable | ||
synchronized Long getAppStartInterval() { | ||
if (appStartMillis == null || appStartEndMillis == null) { | ||
return null; | ||
} | ||
return appStartEndMillis - appStartMillis; | ||
} | ||
|
||
boolean isColdStart() { | ||
return coldStart; | ||
} | ||
|
||
synchronized void setColdStart(final boolean coldStart) { | ||
this.coldStart = coldStart; | ||
} | ||
|
||
@Nullable | ||
Date getAppStartTime() { | ||
return appStartTime; | ||
} | ||
|
||
synchronized void setAppStartTime(final long appStartMillis, final @NotNull Date appStartTime) { | ||
// method is synchronized because the SDK may by init. on a background thread. | ||
if (this.appStartTime != null && this.appStartMillis != null) { | ||
return; | ||
} | ||
this.appStartTime = appStartTime; | ||
this.appStartMillis = appStartMillis; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...y-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package io.sentry.android.core; | ||
|
||
import static io.sentry.android.core.ActivityLifecycleIntegration.APP_START_COLD; | ||
import static io.sentry.android.core.ActivityLifecycleIntegration.APP_START_WARM; | ||
|
||
import io.sentry.EventProcessor; | ||
import io.sentry.protocol.MeasurementValue; | ||
import io.sentry.protocol.SentrySpan; | ||
import io.sentry.protocol.SentryTransaction; | ||
import java.util.List; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** Event Processor responsible for adding Android metrics to transactions */ | ||
final class PerformanceAndroidEventProcessor implements EventProcessor { | ||
|
||
private final boolean tracingEnabled; | ||
|
||
private boolean sentStartMeasurement = false; | ||
|
||
PerformanceAndroidEventProcessor(final @NotNull SentryAndroidOptions options) { | ||
tracingEnabled = options.isTracingEnabled(); | ||
} | ||
|
||
@Override | ||
public synchronized @NotNull SentryTransaction process( | ||
@NotNull SentryTransaction transaction, @Nullable Object hint) { | ||
// the app start measurement is only sent once and only if the transaction has | ||
// the app.start span, which is automatically created by the SDK. | ||
if (!sentStartMeasurement && tracingEnabled && hasAppStartSpan(transaction.getSpans())) { | ||
final Long appStartUpInterval = AppStartState.getInstance().getAppStartInterval(); | ||
// if appStartUpInterval is null, metrics are not ready to be sent | ||
if (appStartUpInterval != null) { | ||
final MeasurementValue value = new MeasurementValue((float) appStartUpInterval); | ||
|
||
final String appStartKey = | ||
AppStartState.getInstance().isColdStart() ? "app_start_cold" : "app_start_warm"; | ||
|
||
transaction.getMeasurements().put(appStartKey, value); | ||
sentStartMeasurement = true; | ||
} | ||
} | ||
|
||
return transaction; | ||
} | ||
|
||
private boolean hasAppStartSpan(final @NotNull List<SentrySpan> spans) { | ||
for (final SentrySpan span : spans) { | ||
if (span.getOp().contentEquals(APP_START_COLD) | ||
|| span.getOp().contentEquals(APP_START_WARM)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.