Skip to content

Commit aa86a9f

Browse files
committed
Report all AppStartMetrics spans
1 parent f4206aa commit aa86a9f

File tree

2 files changed

+68
-49
lines changed

2 files changed

+68
-49
lines changed

sentry-android-core/api/sentry-android-core.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public final class io/sentry/android/core/ApplicationExitInfoEventProcessor : io
218218
public final class io/sentry/android/core/ApplicationStartInfoIntegration : io/sentry/Integration, java/io/Closeable {
219219
public fun <init> (Landroid/content/Context;Lio/sentry/android/core/BuildInfoProvider;)V
220220
public fun close ()V
221-
public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
221+
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
222222
}
223223

224224
public final class io/sentry/android/core/BuildConfig {

sentry-android-core/src/main/java/io/sentry/android/core/ApplicationStartInfoIntegration.java

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import io.sentry.SpanDataConvention;
1919
import io.sentry.SpanId;
2020
import io.sentry.SpanStatus;
21+
import io.sentry.TracesSamplingDecision;
2122
import io.sentry.android.core.internal.util.AndroidThreadChecker;
23+
import io.sentry.android.core.performance.ActivityLifecycleTimeSpan;
2224
import io.sentry.android.core.performance.AppStartMetrics;
2325
import io.sentry.android.core.performance.TimeSpan;
2426
import io.sentry.protocol.SentryId;
@@ -28,6 +30,7 @@
2830
import io.sentry.protocol.TransactionNameSource;
2931
import io.sentry.util.AutoClosableReentrantLock;
3032
import io.sentry.util.IntegrationUtils;
33+
import io.sentry.util.Objects;
3134
import java.io.Closeable;
3235
import java.io.IOException;
3336
import java.util.Date;
@@ -52,7 +55,7 @@ public ApplicationStartInfoIntegration(
5255
final @NotNull Context context, final @NotNull BuildInfoProvider buildInfoProvider) {
5356
this.context = ContextUtils.getApplicationContext(context);
5457
this.buildInfoProvider =
55-
java.util.Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required");
58+
Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required");
5659
}
5760

5861
@Override
@@ -70,9 +73,9 @@ private void register(
7073
"ApplicationStartInfoIntegration enabled: %s",
7174
options.isEnableApplicationStartInfo());
7275

73-
// if (!options.isEnableApplicationStartInfo()) {
74-
// return;
75-
// }
76+
if (!options.isEnableApplicationStartInfo()) {
77+
return;
78+
}
7679

7780
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
7881
options
@@ -157,9 +160,7 @@ private void onApplicationStartInfoAvailable(
157160
final long unixTimeOffsetMs = currentUnixMs - currentRealtimeMs;
158161

159162
final Map<String, String> tags = extractTags(startInfo);
160-
final String transactionName = "app.start." + getReasonLabel(startInfo.getReason());
161163
final long startRealtimeMs = getStartTimestampMs(startInfo);
162-
163164
final long ttidRealtimeMs = getFirstFrameTimestampMs(startInfo);
164165
final long ttfdRealtimeMs = getFullyDrawnTimestampMs(startInfo);
165166
final long bindApplicationRealtimeMs = getBindApplicationTimestampMs(startInfo);
@@ -172,36 +173,30 @@ private void onApplicationStartInfoAvailable(
172173
? dateFromUnixTime(unixTimeOffsetMs + endTimestamp)
173174
: options.getDateProvider().now();
174175

175-
// Create trace context
176176
final SentryId traceId = new SentryId();
177177
final SpanId spanId = new SpanId();
178178
final SpanContext traceContext =
179-
new SpanContext(traceId, spanId, "app.startDate.info", null, null);
179+
new SpanContext(traceId, spanId, "app.start", null, new TracesSamplingDecision(true));
180180
traceContext.setStatus(SpanStatus.OK);
181181

182-
// Convert timestamps to seconds
183182
final double startTimestampSecs = dateToSeconds(startDate);
184183
final double endTimestampSecs = dateToSeconds(endDate);
185184

186-
// Create transaction directly
187185
final SentryTransaction transaction =
188186
new SentryTransaction(
189-
transactionName,
187+
"app.start",
190188
startTimestampSecs,
191189
endTimestampSecs,
192190
new java.util.ArrayList<>(),
193191
new HashMap<>(),
194192
new TransactionInfo(TransactionNameSource.COMPONENT.apiName()));
195193

196-
// Set trace context
197194
transaction.getContexts().setTrace(traceContext);
198195

199-
// Set tags
200196
for (Map.Entry<String, String> entry : tags.entrySet()) {
201197
transaction.setTag(entry.getKey(), entry.getValue());
202198
}
203199

204-
// Add spans
205200
if (bindApplicationRealtimeMs > 0) {
206201
transaction
207202
.getSpans()
@@ -215,6 +210,12 @@ private void onApplicationStartInfoAvailable(
215210
dateFromUnixTime(unixTimeOffsetMs + bindApplicationRealtimeMs)));
216211
}
217212

213+
if (startInfo.getStartType() == ApplicationStartInfo.START_TYPE_COLD) {
214+
attachColdStartInstrumentations(transaction, traceId, spanId);
215+
}
216+
217+
attachActivitySpans(transaction, traceId, spanId);
218+
218219
if (ttidRealtimeMs > 0) {
219220
transaction
220221
.getSpans()
@@ -241,26 +242,6 @@ private void onApplicationStartInfoAvailable(
241242
dateFromUnixTime(unixTimeOffsetMs + ttfdRealtimeMs)));
242243
}
243244

244-
attachAppStartMetrics(transaction, traceId, spanId, unixTimeOffsetMs);
245-
246-
// if application instrumentation was disabled, report app start info data
247-
final TimeSpan appOnCreateSpan = AppStartMetrics.getInstance().getApplicationOnCreateTimeSpan();
248-
if (!appOnCreateSpan.hasStarted() || appOnCreateSpan.hasStopped()) {
249-
final long applicationOnCreateRealtimeMs = getApplicationOnCreateTimestampMs(startInfo);
250-
if (applicationOnCreateRealtimeMs > 0) {
251-
transaction
252-
.getSpans()
253-
.add(
254-
createSpan(
255-
traceId,
256-
spanId,
257-
"application.onCreate",
258-
null,
259-
startDate,
260-
dateFromUnixTime(unixTimeOffsetMs + applicationOnCreateRealtimeMs)));
261-
}
262-
}
263-
264245
scopes.captureTransaction(transaction, null, null);
265246
}
266247

@@ -299,11 +280,10 @@ private static double dateToSeconds(final @NotNull SentryDate date) {
299280
}
300281

301282
@RequiresApi(api = 35)
302-
private void attachAppStartMetrics(
283+
private void attachColdStartInstrumentations(
303284
final @NotNull SentryTransaction transaction,
304285
final @NotNull SentryId traceId,
305-
final @NotNull SpanId parentSpanId,
306-
final long unixTimeOffsetMs) {
286+
final @NotNull SpanId parentSpanId) {
307287

308288
final @NotNull AppStartMetrics appStartMetrics = AppStartMetrics.getInstance();
309289
final @NotNull List<TimeSpan> contentProviderSpans =
@@ -320,7 +300,7 @@ private void attachAppStartMetrics(
320300
createSpan(
321301
traceId,
322302
parentSpanId,
323-
"contentprovider.load",
303+
"contentprovider.on_create",
324304
cpSpan.getDescription(),
325305
cpStartDate,
326306
cpEndDate));
@@ -342,13 +322,61 @@ private void attachAppStartMetrics(
342322
createSpan(
343323
traceId,
344324
parentSpanId,
345-
"application.onCreate",
325+
"application.on_create",
346326
appOnCreateDescription,
347327
appOnCreateStart,
348328
appOnCreateEnd));
349329
}
350330
}
351331

332+
@RequiresApi(api = 35)
333+
private void attachActivitySpans(
334+
final @NotNull SentryTransaction transaction,
335+
final @NotNull SentryId traceId,
336+
final @NotNull SpanId parentSpanId) {
337+
338+
final @NotNull AppStartMetrics appStartMetrics = AppStartMetrics.getInstance();
339+
final @NotNull List<ActivityLifecycleTimeSpan> activityLifecycleTimeSpans =
340+
appStartMetrics.getActivityLifecycleTimeSpans();
341+
342+
for (final ActivityLifecycleTimeSpan span : activityLifecycleTimeSpans) {
343+
final TimeSpan onCreate = span.getOnCreate();
344+
final TimeSpan onStart = span.getOnStart();
345+
346+
if (onCreate.hasStarted() && onCreate.hasStopped()) {
347+
final SentryDate start = dateFromUnixTime(onCreate.getStartTimestampMs());
348+
final SentryDate end = dateFromUnixTime(onCreate.getProjectedStopTimestampMs());
349+
350+
transaction
351+
.getSpans()
352+
.add(
353+
createSpan(
354+
traceId,
355+
parentSpanId,
356+
"activity.on_create",
357+
onCreate.getDescription(),
358+
start,
359+
end));
360+
}
361+
362+
if (onStart.hasStarted() && onStart.hasStopped()) {
363+
final SentryDate start = dateFromUnixTime(onStart.getStartTimestampMs());
364+
final SentryDate end = dateFromUnixTime(onStart.getProjectedStopTimestampMs());
365+
366+
transaction
367+
.getSpans()
368+
.add(
369+
createSpan(
370+
traceId,
371+
parentSpanId,
372+
"activity.on_start",
373+
onStart.getDescription(),
374+
start,
375+
end));
376+
}
377+
}
378+
}
379+
352380
@RequiresApi(api = 35)
353381
private @NotNull Map<String, String> extractTags(
354382
final @NotNull android.app.ApplicationStartInfo startInfo) {
@@ -437,15 +465,6 @@ private long getBindApplicationTimestampMs(
437465
return bindTime != null ? TimeUnit.NANOSECONDS.toMillis(bindTime) : 0;
438466
}
439467

440-
@RequiresApi(api = 35)
441-
private long getApplicationOnCreateTimestampMs(
442-
final @NotNull android.app.ApplicationStartInfo startInfo) {
443-
final Map<Integer, Long> timestamps = startInfo.getStartupTimestamps();
444-
final Long onCreateTime =
445-
timestamps.get(ApplicationStartInfo.START_TIMESTAMP_APPLICATION_ONCREATE);
446-
return onCreateTime != null ? TimeUnit.NANOSECONDS.toMillis(onCreateTime) : 0;
447-
}
448-
449468
@RequiresApi(api = 35)
450469
private long getFirstFrameTimestampMs(final @NotNull android.app.ApplicationStartInfo startInfo) {
451470
final Map<Integer, Long> timestamps = startInfo.getStartupTimestamps();

0 commit comments

Comments
 (0)