Skip to content

Commit 884b55b

Browse files
authored
chore: Move startup tracing into the SDK (#2234)
1 parent 2d83793 commit 884b55b

File tree

10 files changed

+378
-171
lines changed

10 files changed

+378
-171
lines changed

package-dev/Runtime/SentryInitialization.cs

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ namespace Sentry.Unity
4141
{
4242
public static class SentryInitialization
4343
{
44-
public const string StartupTransactionOperation = "app.start";
45-
public static ISpan InitSpan;
46-
private const string InitSpanOperation = "runtime.init";
47-
public static ISpan SubSystemRegistrationSpan;
48-
private const string SubSystemSpanOperation = "runtime.init.subsystem";
49-
5044
#if SENTRY_WEBGL
5145
// On WebGL SubsystemRegistration is too early for the UnityWebRequestTransport and errors with 'URI empty'
5246
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
@@ -60,14 +54,9 @@ public static void Init()
6054
var options = ScriptableSentryUnityOptions.LoadSentryUnityOptions(unityInfo);
6155
if (options != null && options.ShouldInitializeSdk())
6256
{
63-
// Certain integrations require access to preprocessor directives so we provide them as `.cs` and
64-
// compile them with the game instead of precompiling them with the rest of the SDK.
65-
// i.e. SceneManagerAPI requires UNITY_2020_3_OR_NEWER
66-
SentryIntegrations.Configure(options);
6757
// Configures scope sync and (by default) initializes the native SDK.
6858
SetupNativeSdk(options, unityInfo);
6959
SentryUnity.Init(options);
70-
SetupStartupTracing(options);
7160
}
7261
else
7362
{
@@ -92,7 +81,7 @@ private static void SetupNativeSdk(SentryUnityOptions options, SentryUnityInfo u
9281
#elif SENTRY_NATIVE
9382
SentryNative.Configure(options, unityInfo);
9483
#elif SENTRY_WEBGL
95-
SentryWebGL.Configure(options);
84+
SentryWebGL.Configure(options);
9685
#endif
9786
}
9887
catch (DllNotFoundException e)
@@ -106,26 +95,6 @@ private static void SetupNativeSdk(SentryUnityOptions options, SentryUnityInfo u
10695
options.DiagnosticLogger?.LogError(e, "Sentry native error capture configuration failed.");
10796
}
10897
}
109-
110-
private static void SetupStartupTracing(SentryUnityOptions options)
111-
{
112-
#if !SENTRY_WEBGL
113-
if (options.TracesSampleRate > 0.0f && options.AutoStartupTraces)
114-
{
115-
options.DiagnosticLogger?.LogInfo("Creating '{0}' transaction for runtime initialization.",
116-
StartupTransactionOperation);
117-
118-
var runtimeStartTransaction =
119-
SentrySdk.StartTransaction("runtime.initialization", StartupTransactionOperation);
120-
SentrySdk.ConfigureScope(scope => scope.Transaction = runtimeStartTransaction);
121-
122-
options.DiagnosticLogger?.LogDebug("Creating '{0}' span.", InitSpanOperation);
123-
InitSpan = runtimeStartTransaction.StartChild(InitSpanOperation, "runtime initialization");
124-
options.DiagnosticLogger?.LogDebug("Creating '{0}' span.", SubSystemSpanOperation);
125-
SubSystemRegistrationSpan = InitSpan.StartChild(SubSystemSpanOperation, "subsystem registration");
126-
}
127-
#endif
128-
}
12998
}
13099

131100
public class SentryUnityInfo : ISentryUnityInfo

package-dev/Runtime/SentryIntegrations.cs

Lines changed: 0 additions & 122 deletions
This file was deleted.

samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ MonoBehaviour:
1919
<DebounceTimeLog>k__BackingField: 1000
2020
<DebounceTimeWarning>k__BackingField: 1000
2121
<DebounceTimeError>k__BackingField: 1000
22-
<TracesSampleRate>k__BackingField: 0
22+
<TracesSampleRate>k__BackingField: 1
2323
<AutoStartupTraces>k__BackingField: 1
2424
<AutoSceneLoadTraces>k__BackingField: 1
2525
<AutoAwakeTraces>k__BackingField: 0
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
using Sentry.Extensibility;
2+
using Sentry.Integrations;
3+
using UnityEngine;
4+
5+
namespace Sentry.Unity.Integrations;
6+
7+
internal class StartupTracingIntegration : ISdkIntegration
8+
{
9+
private const string StartupTransactionOperation = "app.start";
10+
internal static ISpan? InitSpan;
11+
private const string InitSpanOperation = "runtime.init";
12+
internal static ISpan? SubSystemRegistrationSpan;
13+
private const string SubSystemSpanOperation = "runtime.init.subsystem";
14+
internal static ISpan? AfterAssembliesSpan;
15+
private const string AfterAssembliesSpanOperation = "runtime.init.afterassemblies";
16+
internal static ISpan? SplashScreenSpan;
17+
private const string SplashScreenSpanOperation = "runtime.init.splashscreen";
18+
internal static ISpan? FirstSceneLoadSpan;
19+
private const string FirstSceneLoadSpanOperation = "runtime.init.firstscene";
20+
21+
internal static bool IsGameStartupFinished; // Flag to make sure we only create spans during the game's startup.
22+
internal static bool IsIntegrationRegistered;
23+
24+
private static IDiagnosticLogger? Logger;
25+
26+
// For testing. Methods with the RuntimeLoad attribute cannot have arguments
27+
internal static IApplication? Application = null;
28+
29+
public void Register(IHub hub, SentryOptions options)
30+
{
31+
Logger = options.DiagnosticLogger;
32+
33+
if (options is SentryUnityOptions { TracesSampleRate: > 0, AutoStartupTraces: true })
34+
{
35+
IsIntegrationRegistered = true;
36+
}
37+
}
38+
39+
internal static bool IsStartupTracingAllowed()
40+
{
41+
Application ??= ApplicationAdapter.Instance;
42+
if (!Application.IsEditor
43+
&& Application.Platform != RuntimePlatform.WebGLPlayer // Startup Tracing does not properly work on WebGL
44+
&& IsIntegrationRegistered
45+
&& !IsGameStartupFinished)
46+
{
47+
return true;
48+
}
49+
50+
return false;
51+
}
52+
53+
public static void StartTracing()
54+
{
55+
if (!IsStartupTracingAllowed())
56+
{
57+
return;
58+
}
59+
60+
Logger?.LogInfo("Creating '{0}' transaction for runtime initialization.",
61+
StartupTransactionOperation);
62+
63+
var runtimeStartTransaction =
64+
SentrySdk.StartTransaction("runtime.initialization", StartupTransactionOperation);
65+
SentrySdk.ConfigureScope(scope => scope.Transaction = runtimeStartTransaction);
66+
67+
Logger?.LogDebug("Creating '{0}' span.", InitSpanOperation);
68+
InitSpan = runtimeStartTransaction.StartChild(InitSpanOperation, "runtime initialization");
69+
Logger?.LogDebug("Creating '{0}' span.", SubSystemSpanOperation);
70+
SubSystemRegistrationSpan = InitSpan.StartChild(SubSystemSpanOperation, "subsystem registration");
71+
}
72+
73+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
74+
public static void AfterAssembliesLoaded()
75+
{
76+
if (!IsStartupTracingAllowed())
77+
{
78+
return;
79+
}
80+
81+
SubSystemRegistrationSpan?.Finish(SpanStatus.Ok);
82+
SubSystemRegistrationSpan = null;
83+
84+
Logger?.LogDebug("Creating '{0}' span.", AfterAssembliesSpanOperation);
85+
AfterAssembliesSpan = InitSpan?.StartChild(AfterAssembliesSpanOperation, "after assemblies");
86+
}
87+
88+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
89+
public static void BeforeSplashScreen()
90+
{
91+
if (!IsStartupTracingAllowed())
92+
{
93+
return;
94+
}
95+
96+
AfterAssembliesSpan?.Finish(SpanStatus.Ok);
97+
AfterAssembliesSpan = null;
98+
99+
Logger?.LogDebug("Creating '{0}' span.", SplashScreenSpanOperation);
100+
SplashScreenSpan = InitSpan?.StartChild(SplashScreenSpanOperation, "splashscreen");
101+
}
102+
103+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
104+
public static void BeforeSceneLoad()
105+
{
106+
if (!IsStartupTracingAllowed())
107+
{
108+
return;
109+
}
110+
111+
SplashScreenSpan?.Finish(SpanStatus.Ok);
112+
SplashScreenSpan = null;
113+
114+
Logger?.LogDebug("Creating '{0}' span.", FirstSceneLoadSpanOperation);
115+
FirstSceneLoadSpan = InitSpan?.StartChild(FirstSceneLoadSpanOperation, "first scene load");
116+
}
117+
118+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
119+
public static void AfterSceneLoad()
120+
{
121+
if (!IsStartupTracingAllowed())
122+
{
123+
// To make sure late init calls don't try to trace the startup
124+
IsGameStartupFinished = true;
125+
return;
126+
}
127+
128+
FirstSceneLoadSpan?.Finish(SpanStatus.Ok);
129+
FirstSceneLoadSpan = null;
130+
131+
InitSpan?.Finish(SpanStatus.Ok);
132+
InitSpan = null;
133+
134+
Logger?.LogInfo("Finishing '{0}' transaction.", StartupTransactionOperation);
135+
SentrySdk.ConfigureScope(s => s.Transaction?.Finish(SpanStatus.Ok));
136+
137+
IsGameStartupFinished = true;
138+
}
139+
}

src/Sentry.Unity/SentryUnity.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.ComponentModel;
33
using Sentry.Extensibility;
4+
using UnityEngine;
45

56
namespace Sentry.Unity;
67

src/Sentry.Unity/SentryUnityOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication applicat
315315

316316
this.AddIntegration(new UnityLogHandlerIntegration(this));
317317
this.AddIntegration(new UnityApplicationLoggingIntegration());
318+
this.AddIntegration(new StartupTracingIntegration());
318319
this.AddIntegration(new AnrIntegration(behaviour));
319320
this.AddIntegration(new UnityScopeIntegration(application, unityInfo));
320321
this.AddIntegration(new UnityBeforeSceneLoadIntegration());

src/Sentry.Unity/SentryUnitySDK.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ private SentryUnitySdk(SentryUnityOptions options)
5151

5252
unitySdk._dotnetSdk = SentrySdk.Init(options);
5353

54+
// We can safely call this during initialization. If the SDK self-initialized we're right on time. If the SDK
55+
// was initialized manually, the RuntimeOnLoad attributes already triggered, making this call a no-op.
56+
StartupTracingIntegration.StartTracing();
57+
5458
if (options.NativeContextWriter is { } contextWriter)
5559
{
5660
SentrySdk.ConfigureScope((scope) =>

test/Scripts.Tests/package-release.zip.snapshot

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,8 +1572,6 @@ Runtime/Sentry.xml
15721572
Runtime/Sentry.xml.meta
15731573
Runtime/SentryInitialization.cs
15741574
Runtime/SentryInitialization.cs.meta
1575-
Runtime/SentryIntegrations.cs
1576-
Runtime/SentryIntegrations.cs.meta
15771575
Runtime/SentryUserFeedback.cs
15781576
Runtime/SentryUserFeedback.cs.meta
15791577
Samples~/unity-of-bugs/Scenes.meta

0 commit comments

Comments
 (0)