Automatic Instrumentation

Android's Activity Instrumentation

The Activity's instrumentation, once enabled, captures transactions for each launch of an Activity. The SDK sets the Transaction name to the name of the Activity, for example, MainActivity, and Transaction operation to ui.load.

The transaction starts before each Activity's onCreate method is called.

The Activity's instrumentation is enabled by default, but you may disable it by setting:

AndroidManifest.xml
Copied
<manifest>
    <meta-data android:name="io.sentry.traces.activity.enable" android:value="false" />
</manifest>

The transaction finishes after each Activity's onResume method is executed.

The transaction finishes automatically, but you may disable it by setting:

AndroidManifest.xml
Copied
<manifest>
    <meta-data android:name="io.sentry.traces.activity.auto-finish.enable" android:value="false" />
</manifest>

We offer the possibility to finish the transaction manually. For example, you might want to finish the transaction after an API call triggered on Activity's onCreate and shown the data to the user. To achieve that you can do:

Copied
import io.sentry.Sentry;

ISpan span = Sentry.getSpan();
if (span != null) {
  span.finish();
}

In case that the user left this Activity before you've finished the transaction manually, the SDK finishes the transaction automatically when the onDestroy method is called.

Transactions are always bound to the Scope automatically if there's none set. Because of that, you may create spans using manual instrumentation, and those spans will be automatically associated with the Activity's running transaction.

Copied
import java.lang.Exception;

import io.sentry.ISpan;
import io.sentry.Sentry;
import io.sentry.SpanStatus;

void displayUserData() {
  ISpan span = Sentry.getSpan();
  if (span != null) {
    ISpan innerSpan = span.startChild("displayUserData");
    try {
      // omitted code
    } catch (Exception e) {
      innerSpan.setThrowable(e);
      innerSpan.setStatus(SpanStatus.NOT_FOUND);
      throw e;
    } finally {
      innerSpan.finish();
    }
  }
}

When you didn't finish the transaction yet, but you start a new Activity, the SDK always automatically finishes the previous Activity transaction. This is due to the fact that only one transaction at a time can be bound to the Scope. To work around that, you may create transactions manually using the custom instrumentation and its instance to start spans instead of the Static API.

Android's Fragment Instrumentation

Once enabled, Android's Fragment Instrumentation starts a span for each launch of a fragment. The SDK sets the span operation to ui.load and the span description to the fragment's name, for example, LoginFragment.

The span starts after each fragment's onCreate method is called and before its onCreateView method is called.

The span finishes after each fragment's onResume method is executed.

Android's Fragment Instrumentation depends on having an active transaction bound to the scope, and ideally it'd be used along with Android's Activity Instrumentation, which starts a transaction and binds it to the scope automatically.

Learn more in our Fragment documentation.

App Start Instrumentation

The App Start Instrumentation provides insight into how long your application takes to launch. It adds a span from the application launch to the first auto-generated UI transaction.

The SDK differentiates between a cold and a warm start, but doesn't track hot starts/resumes.

  • Cold start: A cold start refers to an app’s starting from scratch: the system’s process has not, until this start, created the app’s process. Cold starts happen in cases such as your app’s being launched for the first time since the device booted, or since the system killed the app.
  • Warm start: A warm start encompasses some subset of the operations that take place during a cold start; at the same time, it represents more overhead than a hot start. For instance: The user backs out of your app, but then re-launches it. The process may have continued to run, but the app must recreate the activity from scratch via a call to onCreate().

The SDK sets the Span operation to app.start.cold for Cold start_ and app.start.warm for Warm start.

The SDK uses the SentryPerformanceProvider (ContentProvider) creation time as the beginning of the app start and the first Activity#onResume call as the end.

You can opt out of Android's Activity Instrumentation and App Start Instrumentation using options:

AndroidManifest.xml
Copied
<manifest>
    <meta-data android:name="io.sentry.traces.activity.enable" android:value="false" />
</manifest>

Cold and warm start are Mobile Vitals, which you can learn about in the full documentation.

Slow and Frozen Frames

Unresponsive UI and animation hitches annoy users and degrade the user experience. Two measurements to track these types of experiences are slow frames and frozen frames. If you want your app to run smoothly, you should try to avoid both. The SDK adds these two measurements for the Android's Activity transactions.

  • Slow frames: Slow frames are captured by the SDK when the app takes more than 16 ms to render a frame. Typically, a phone or tablet renders 60 frames per second (fps). At 60 fps, every frame has 16 ms to render; slower than that, and the app has slow frames.
  • Frozen frames: Frozen frames are UI frames that take longer than 700 ms to render.

Slow and frozen frames are Mobile Vitals, which you can learn about in the full documentation.

AndroidX Support

Sentry uses the androidx.core library for detecting slow and frozen frames. This is necessary to produce accurate results across all Android OS versions.

We check for availability at runtime, so if you're not using androidx.core, you can remove it from Sentry's transitive dependencies.

Copied
implementation ('io.sentry:sentry-android:7.13.0') {
    exclude group: 'androidx.core', module: 'core'
}

Note that by removing this transitive dependency, slow and frozen frames won't be reported.

OkHttp Library Instrumentation

The OkHttp's instrumentation, once added the SentryOkHttpInterceptor, starts a span out of the active span bound to the scope for each HTTP Request. The SDK sets the span operation to http.client and description to request $method and $URL; for example, GET https://sentry.io.

The span finishes once the request has been executed. The span status depends on either the HTTP Response code or SpanStatus.INTERNAL_ERROR if the code does not match any of Sentry's SpanStatus.

When the HTTP request throws an IOException, Sentry's SDK associates this exception to the running span. If you haven't set the SDK to swallow the exception and capture it, the span and SentryEvent will be linked when viewing it on the Issue Details page in sentry.io.

For more information see our OkHttp integration.

SQLite and Room Instrumentation

The Sentry Android Gradle Plugin does the tracing auto instrumentation using bytecode manipulation for androidx.sqlite and androidx.room libraries.

The Plugin injects a code snippet that starts a span out of the active span bound to the scope for each CRUD operation. The SDK sets the span operation to db and description to the SQL Query if available.

The span finishes once the operation has been executed. The span status is set to SpanStatus.OK if successful or SpanStatus.INTERNAL_ERROR if there was any error.

When the operation throws an Exception, Sentry's SDK associates this exception to the running span. If you haven't set the SDK to swallow the exception and capture it, the span and SentryEvent will be linked when viewing it on the Issue Details page in sentry.io.