Skip to content

Commit

Permalink
Add more tracing sections to startup (#467)
Browse files Browse the repository at this point in the history
## Goal

Add more tracing sections to startup workflow to better profile SDK startup. 

A misleading log line was also removed regarding loading native files
  • Loading branch information
bidetofevil committed Mar 4, 2024
1 parent 199674f commit c68a4ee
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public final class Embrace implements EmbraceAndroidApi {
@NonNull
private static final Embrace embrace = new Embrace();

private static EmbraceImpl impl = Systrace.traceSynchronous("embrace-init", EmbraceImpl::new);
private static EmbraceImpl impl = Systrace.traceSynchronous("embrace-impl-init", EmbraceImpl::new);

@NonNull
private final InternalEmbraceLogger internalEmbraceLogger = InternalStaticEmbraceLogger.logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ private void startImpl(@NonNull Context context,
final long startTimeMs = sdkClock.now();
internalEmbraceLogger.logDeveloper("Embrace", "Starting SDK for framework " + framework.name());
moduleInitBootstrapper.init(context, enableIntegrationTesting, framework, startTimeMs, customAppId);
Systrace.startSynchronous("post-services-setup");
telemetryService = moduleInitBootstrapper.getInitModule().getTelemetryService();

final CoreModule coreModule = moduleInitBootstrapper.getCoreModule();
Expand Down Expand Up @@ -324,16 +325,17 @@ private void startImpl(@NonNull Context context,
sessionOrchestrator = sessionModule.getSessionOrchestrator();
sessionPropertiesService = sessionModule.getSessionPropertiesService();

Systrace.startSynchronous("send-cached-sessions");
// Send any sessions that were cached and not yet sent.
deliveryModule.getDeliveryService().sendCachedSessions(
nativeModule.getNdkService(),
essentialServiceModule.getSessionIdTracker()
);
Systrace.endSynchronous();

final CrashModule crashModule = moduleInitBootstrapper.getCrashModule();
loadCrashVerifier(crashModule, moduleInitBootstrapper.getWorkerThreadModule());

Systrace.startSynchronous("internal-interface-init");
internalInterfaceModule = new InternalInterfaceModuleImpl(
moduleInitBootstrapper.getInitModule(),
moduleInitBootstrapper.getOpenTelemetryModule(),
Expand All @@ -360,27 +362,26 @@ private void startImpl(@NonNull Context context,
internalInterfaceModule.getFlutterInternalInterface();
break;
}
Systrace.endSynchronous();


final String startMsg = "Embrace SDK started. App ID: " +
essentialServiceModule.getConfigService().getSdkModeBehavior().getAppId() + " Version: " + BuildConfig.VERSION_NAME;
internalEmbraceLogger.logInfo(startMsg);

final long endTimeMs = sdkClock.now();
started.set(true);
Systrace.endSynchronous();
Systrace.startSynchronous("startup-tracking");
dataCaptureServiceModule.getStartupService().setSdkStartupInfo(startTimeMs, endTimeMs);
Systrace.endSynchronous();

Systrace.startSynchronous("startup-moment");
// Attempt to send the startup event if the app is already in the foreground. We registered to send this when
// we went to the foreground, but if an activity had already gone to the foreground, we may have missed
// sending this, so to ensure the startup message is sent, we force it to be sent here.
if (!essentialServiceModule.getProcessStateService().isInBackground()) {
internalEmbraceLogger.logDeveloper("Embrace", "Sending startup moment");
dataContainerModule.getEventService().sendStartupMoment();
}
Systrace.endSynchronous();

// This should return immediately given that EmbraceSpansService initialization should be finished at this point
// Put in emergency timeout just in case something unexpected happens so as to fail the SDK startup.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import io.embrace.android.embracesdk.capture.thermalstate.NoOpThermalStatusServi
import io.embrace.android.embracesdk.capture.thermalstate.ThermalStatusService
import io.embrace.android.embracesdk.capture.webview.EmbraceWebViewService
import io.embrace.android.embracesdk.capture.webview.WebViewService
import io.embrace.android.embracesdk.internal.Systrace
import io.embrace.android.embracesdk.internal.utils.BuildVersionChecker
import io.embrace.android.embracesdk.internal.utils.VersionChecker
import io.embrace.android.embracesdk.worker.WorkerName
Expand Down Expand Up @@ -95,19 +96,23 @@ internal class DataCaptureServiceModuleImpl @JvmOverloads constructor(
}

override val componentCallbackService: ComponentCallbackService by singleton {
ComponentCallbackService(coreModule.application, memoryService)
Systrace.traceSynchronous("component-callback-service-init") {
ComponentCallbackService(coreModule.application, memoryService)
}
}

override val powerSaveModeService: PowerSaveModeService by singleton {
if (configService.autoDataCaptureBehavior.isPowerSaveModeServiceEnabled()) {
EmbracePowerSaveModeService(
coreModule.context,
backgroundWorker,
initModule.clock,
systemServiceModule.powerManager
)
} else {
NoOpPowerSaveModeService()
Systrace.traceSynchronous("power-service-init") {
if (configService.autoDataCaptureBehavior.isPowerSaveModeServiceEnabled()) {
EmbracePowerSaveModeService(
coreModule.context,
backgroundWorker,
initModule.clock,
systemServiceModule.powerManager
)
} else {
NoOpPowerSaveModeService()
}
}
}

Expand All @@ -116,12 +121,14 @@ internal class DataCaptureServiceModuleImpl @JvmOverloads constructor(
}

override val breadcrumbService: BreadcrumbService by singleton {
EmbraceBreadcrumbService(
initModule.clock,
configService,
essentialServiceModule.activityLifecycleTracker,
coreModule.logger
)
Systrace.traceSynchronous("breadcrumb-service-init") {
EmbraceBreadcrumbService(
initModule.clock,
configService,
essentialServiceModule.activityLifecycleTracker,
coreModule.logger
)
}
}

override val pushNotificationService: PushNotificationCaptureService by singleton {
Expand All @@ -132,23 +139,25 @@ internal class DataCaptureServiceModuleImpl @JvmOverloads constructor(
}

override val thermalStatusService: ThermalStatusService by singleton {
if (configService.autoDataCaptureBehavior.isThermalStatusCaptureEnabled() && versionChecker.isAtLeast(Build.VERSION_CODES.Q)) {
// Android API only accepts an executor. We don't want to directly expose those
// to everything in the codebase so we decorate the BackgroundWorker here as an
// alternative
val backgroundWorker = workerThreadModule.backgroundWorker(WorkerName.BACKGROUND_REGISTRATION)
val executor = Executor {
backgroundWorker.submit(runnable = it)
Systrace.traceSynchronous("thermal-service-init") {
if (configService.autoDataCaptureBehavior.isThermalStatusCaptureEnabled() && versionChecker.isAtLeast(Build.VERSION_CODES.Q)) {
// Android API only accepts an executor. We don't want to directly expose those
// to everything in the codebase so we decorate the BackgroundWorker here as an
// alternative
val backgroundWorker = workerThreadModule.backgroundWorker(WorkerName.BACKGROUND_REGISTRATION)
val executor = Executor {
backgroundWorker.submit(runnable = it)
}

EmbraceThermalStatusService(
executor,
initModule.clock,
coreModule.logger,
systemServiceModule.powerManager
)
} else {
NoOpThermalStatusService()
}

EmbraceThermalStatusService(
executor,
initModule.clock,
coreModule.logger,
systemServiceModule.powerManager
)
} else {
NoOpThermalStatusService()
}
}

Expand Down
Loading

0 comments on commit c68a4ee

Please sign in to comment.