-
-
Notifications
You must be signed in to change notification settings - Fork 56
Rework Initialization #2227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Rework Initialization #2227
Changes from 27 commits
14427b6
bb4dbc0
0f97f0b
a76e957
e494279
df211a3
19c4e78
00e788a
bfcd0f1
4448334
232833c
bcbb551
deb6aa7
a66a5a6
857e492
eefad70
16c9fcf
6542706
b48e60d
76e05b2
3fa372c
1f5e5cc
83deeec
011ba1d
2a46b5f
7ac68be
43f5ae9
ad0ae02
bb6f80a
c53ccb5
d100d4f
7faafb9
490e033
2f42440
d2709d1
326dc32
1183370
f1388b4
594dc4a
3bfc5fa
0843ba5
a4cbc59
32876ac
c6cbb0c
3a2328b
2e4b3db
99bbb4d
d67b2b9
ac366e7
76868b8
1f520ee
a47872d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,9 @@ | |
#endif | ||
|
||
using System; | ||
using Sentry.Unity; | ||
using Sentry.Extensibility; | ||
using Sentry.Unity.NativeUtils; | ||
#if UNITY_2020_3_OR_NEWER | ||
using System.Buffers; | ||
using System.Runtime.InteropServices; | ||
|
@@ -39,91 +41,55 @@ | |
|
||
namespace Sentry.Unity | ||
{ | ||
public static class SentryInitialization | ||
internal static class SentryInitialization | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can safely make this |
||
{ | ||
public const string StartupTransactionOperation = "app.start"; | ||
public static ISpan InitSpan; | ||
private const string InitSpanOperation = "runtime.init"; | ||
public static ISpan SubSystemRegistrationSpan; | ||
private const string SubSystemSpanOperation = "runtime.init.subsystem"; | ||
|
||
#if SENTRY_WEBGL | ||
// On WebGL SubsystemRegistration is too early for the UnityWebRequestTransport and errors with 'URI empty' | ||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] | ||
#else | ||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] | ||
#endif | ||
public static void Init() | ||
internal static void Init() | ||
bitsandfoxes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
var unityInfo = new SentryUnityInfo(); | ||
// We're setting up `UnityInfo` and the platform specific configure callbacks as the very first thing to be | ||
// available during initialization. | ||
SetupPlatformConfiguration(); | ||
|
||
// Loading the options invokes the ScriptableOption`Configure` callback. Users can disable the SDK via code. | ||
var options = ScriptableSentryUnityOptions.LoadSentryUnityOptions(unityInfo); | ||
var options = ScriptableSentryUnityOptions.LoadSentryUnityOptions(); | ||
if (options != null && options.ShouldInitializeSdk()) | ||
{ | ||
// Certain integrations require access to preprocessor directives so we provide them as `.cs` and | ||
// compile them with the game instead of precompiling them with the rest of the SDK. | ||
// i.e. SceneManagerAPI requires UNITY_2020_3_OR_NEWER | ||
SentryIntegrations.Configure(options); | ||
// Configures scope sync and (by default) initializes the native SDK. | ||
SetupNativeSdk(options, unityInfo); | ||
SentryUnity.Init(options); | ||
SetupStartupTracing(options); | ||
// We have to keep the StartupTracing outside the SDK as the integration relies on the `RuntimeInitializeOnLoadMethod` | ||
// attribute. | ||
SentryStartupTracing.SetUpTracingIntration(options); | ||
|
||
SentrySdk.Init(options); | ||
|
||
SentryStartupTracing.StartTracing(); | ||
} | ||
else | ||
{ | ||
// If the SDK is not `enabled` we're closing down the native layer as well. This is especially relevant | ||
// in a `built-time-initialization` scenario where the native SDKs self-initialize. | ||
#if SENTRY_NATIVE_COCOA | ||
SentryNativeCocoa.Close(options, unityInfo); | ||
SentryNativeCocoa.Close(options, SentryPlatformServices.UnityInfo); | ||
#elif SENTRY_NATIVE_ANDROID | ||
SentryNativeAndroid.Close(options, unityInfo); | ||
SentryNativeAndroid.Close(options, SentryPlatformServices.UnityInfo); | ||
#endif | ||
} | ||
} | ||
|
||
private static void SetupNativeSdk(SentryUnityOptions options, SentryUnityInfo unityInfo) | ||
private static void SetupPlatformConfiguration() | ||
{ | ||
try | ||
{ | ||
SentryPlatformServices.UnityInfo = new SentryUnityInfo(); | ||
#if SENTRY_NATIVE_COCOA | ||
SentryNativeCocoa.Configure(options, unityInfo); | ||
SentryPlatformServices.PlatformConfiguration = SentryNativeCocoa.Configure; | ||
#elif SENTRY_NATIVE_ANDROID | ||
SentryNativeAndroid.Configure(options, unityInfo); | ||
SentryPlatformServices.PlatformConfiguration = SentryNativeAndroid.Configure; | ||
#elif SENTRY_NATIVE | ||
SentryNative.Configure(options, unityInfo); | ||
SentryPlatformServices.PlatformConfiguration = SentryNative.Configure; | ||
#elif SENTRY_WEBGL | ||
SentryWebGL.Configure(options); | ||
#endif | ||
} | ||
catch (DllNotFoundException e) | ||
{ | ||
options.DiagnosticLogger?.LogError(e, | ||
"Sentry native-error capture configuration failed to load a native library. This usually " + | ||
"means the library is missing from the application bundle or the installation directory."); | ||
} | ||
catch (Exception e) | ||
{ | ||
options.DiagnosticLogger?.LogError(e, "Sentry native error capture configuration failed."); | ||
} | ||
} | ||
|
||
private static void SetupStartupTracing(SentryUnityOptions options) | ||
{ | ||
#if !SENTRY_WEBGL | ||
if (options.TracesSampleRate > 0.0f && options.AutoStartupTraces) | ||
{ | ||
options.DiagnosticLogger?.LogInfo("Creating '{0}' transaction for runtime initialization.", | ||
StartupTransactionOperation); | ||
|
||
var runtimeStartTransaction = | ||
SentrySdk.StartTransaction("runtime.initialization", StartupTransactionOperation); | ||
SentrySdk.ConfigureScope(scope => scope.Transaction = runtimeStartTransaction); | ||
|
||
options.DiagnosticLogger?.LogDebug("Creating '{0}' span.", InitSpanOperation); | ||
InitSpan = runtimeStartTransaction.StartChild(InitSpanOperation, "runtime initialization"); | ||
options.DiagnosticLogger?.LogDebug("Creating '{0}' span.", SubSystemSpanOperation); | ||
SubSystemRegistrationSpan = InitSpan.StartChild(SubSystemSpanOperation, "subsystem registration"); | ||
} | ||
SentryPlatformServices.PlatformConfiguration = SentryWebGL.Configure; | ||
#endif | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,30 +7,50 @@ | |
using Sentry.Extensibility; | ||
using Sentry.Integrations; | ||
using UnityEngine; | ||
using UnityEngine.SceneManagement; | ||
|
||
namespace Sentry.Unity | ||
{ | ||
public static class SentryIntegrations | ||
internal static class SentryStartupTracing | ||
{ | ||
public static void Configure(SentryUnityOptions options) | ||
#if !SENTRY_WEBGL | ||
private static StartupTracingIntegration StartupTracingIntegration; | ||
#endif | ||
|
||
public static void SetUpTracingIntration(SentryUnityOptions options) | ||
{ | ||
if (options.TracesSampleRate > 0.0) | ||
{ | ||
// On WebGL the SDK initializes on BeforeScene so the Startup Tracing won't work properly. https://github.com/getsentry/sentry-unity/issues/1000 | ||
#if !SENTRY_WEBGL | ||
if (options.AutoStartupTraces) | ||
{ | ||
options.AddIntegration(new StartupTracingIntegration()); | ||
StartupTracingIntegration = new StartupTracingIntegration(); | ||
options.AddIntegration(StartupTracingIntegration); | ||
} | ||
#endif | ||
} | ||
} | ||
|
||
public static void StartTracing() | ||
{ | ||
#if !SENTRY_WEBGL | ||
if (StartupTracingIntegration != null) | ||
{ | ||
StartupTracingIntegration.StartTracing(); | ||
} | ||
#endif | ||
} | ||
|
||
} | ||
|
||
#if !SENTRY_WEBGL | ||
public class StartupTracingIntegration : ISdkIntegration | ||
internal class StartupTracingIntegration : ISdkIntegration | ||
{ | ||
private const string StartupTransactionOperation = "app.start"; | ||
private static ISpan InitSpan; | ||
private const string InitSpanOperation = "runtime.init"; | ||
public static ISpan SubSystemRegistrationSpan; | ||
private const string SubSystemSpanOperation = "runtime.init.subsystem"; | ||
private static ISpan AfterAssembliesSpan; | ||
private const string AfterAssembliesSpanOperation = "runtime.init.afterassemblies"; | ||
private static ISpan SplashScreenSpan; | ||
|
@@ -50,6 +70,26 @@ public void Register(IHub hub, SentryOptions options) | |
IntegrationRegistered = true; | ||
} | ||
|
||
public static void StartTracing() | ||
{ | ||
if (!IntegrationRegistered || StartupAlreadyCaptured) | ||
{ | ||
return; | ||
} | ||
|
||
Logger.LogInfo("Creating '{0}' transaction for runtime initialization.", | ||
StartupTransactionOperation); | ||
|
||
var runtimeStartTransaction = | ||
SentrySdk.StartTransaction("runtime.initialization", StartupTransactionOperation); | ||
SentrySdk.ConfigureScope(scope => scope.Transaction = runtimeStartTransaction); | ||
|
||
Logger.LogDebug("Creating '{0}' span.", InitSpanOperation); | ||
InitSpan = runtimeStartTransaction.StartChild(InitSpanOperation, "runtime initialization"); | ||
Logger.LogDebug("Creating '{0}' span.", SubSystemSpanOperation); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could these two be combined in 1 log message? Debug log can be overwhelming at times |
||
SubSystemRegistrationSpan = InitSpan.StartChild(SubSystemSpanOperation, "subsystem registration"); | ||
} | ||
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] | ||
public static void AfterAssembliesLoaded() | ||
{ | ||
|
@@ -58,11 +98,11 @@ public static void AfterAssembliesLoaded() | |
return; | ||
} | ||
|
||
SentryInitialization.SubSystemRegistrationSpan?.Finish(SpanStatus.Ok); | ||
SentryInitialization.SubSystemRegistrationSpan = null; | ||
SubSystemRegistrationSpan?.Finish(SpanStatus.Ok); | ||
SubSystemRegistrationSpan = null; | ||
|
||
Logger?.LogDebug("Creating '{0}' span.", AfterAssembliesSpanOperation); | ||
AfterAssembliesSpan = SentryInitialization.InitSpan?.StartChild(AfterAssembliesSpanOperation, "after assemblies"); | ||
AfterAssembliesSpan = InitSpan?.StartChild(AfterAssembliesSpanOperation, "after assemblies"); | ||
} | ||
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)] | ||
|
@@ -77,7 +117,7 @@ public static void BeforeSplashScreen() | |
AfterAssembliesSpan = null; | ||
|
||
Logger?.LogDebug("Creating '{0}' span.", SplashScreenSpanOperation); | ||
SplashScreenSpan = SentryInitialization.InitSpan?.StartChild(SplashScreenSpanOperation, "splashscreen"); | ||
SplashScreenSpan = InitSpan?.StartChild(SplashScreenSpanOperation, "splashscreen"); | ||
} | ||
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] | ||
|
@@ -92,7 +132,7 @@ public static void BeforeSceneLoad() | |
SplashScreenSpan = null; | ||
|
||
Logger?.LogDebug("Creating '{0}' span.", FirstSceneLoadSpanOperation); | ||
FirstSceneLoadSpan = SentryInitialization.InitSpan?.StartChild(FirstSceneLoadSpanOperation, "first scene load"); | ||
FirstSceneLoadSpan = InitSpan?.StartChild(FirstSceneLoadSpanOperation, "first scene load"); | ||
} | ||
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] | ||
|
@@ -106,10 +146,10 @@ public static void AfterSceneLoad() | |
FirstSceneLoadSpan?.Finish(SpanStatus.Ok); | ||
FirstSceneLoadSpan = null; | ||
|
||
SentryInitialization.InitSpan?.Finish(SpanStatus.Ok); | ||
SentryInitialization.InitSpan = null; | ||
InitSpan?.Finish(SpanStatus.Ok); | ||
InitSpan = null; | ||
|
||
Logger?.LogInfo("Finishing '{0}' transaction.", SentryInitialization.StartupTransactionOperation); | ||
Logger?.LogInfo("Finishing '{0}' transaction.", StartupTransactionOperation); | ||
SentrySdk.ConfigureScope(s => | ||
{ | ||
s.Transaction?.Finish(SpanStatus.Ok); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,7 +86,7 @@ public void SendFeedback() | |
else | ||
{ | ||
// Since there is no screenshot added we can capture the feedback right away | ||
SentryUnity.CaptureFeedback(_description.text, _email.text, _name.text, addScreenshot: false); | ||
SentrySdk.CaptureFeedback(_description.text, _email.text, _name.text, addScreenshot: false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the desired effect. All things reside within |
||
} | ||
} | ||
|
||
|
@@ -99,7 +99,7 @@ private IEnumerator HideFormAndCaptureFeedback() | |
// We're waiting for the EndOfFrame so the FeedbackForm gets updated before capturing the screenshot | ||
yield return new WaitForEndOfFrame(); | ||
|
||
SentryUnity.CaptureFeedback(_description.text, _email.text, _name.text, addScreenshot: true); | ||
SentrySdk.CaptureFeedback(_description.text, _email.text, _name.text, addScreenshot: true); | ||
|
||
ResetUserFeedback(); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
|
||
namespace Sentry.Unity.NativeUtils; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Putting the services into a very distinctive namespace to "discourage" usage. |
||
|
||
/// <summary> | ||
/// These are SDK's services that are only available at runtime and cannot be baked into the SDK. The | ||
/// <c>SentryInitialization.cs</c> is provided as <c>.cs</c> and gets compiled with the game. It sets <c>IUnityInfo</c> | ||
/// and the <c>PlatformConfiguration</c> callback during the game's startup so that they are available during initializtion. | ||
/// </summary> | ||
/// <remarks>Consider this <c>internal</c>.</remarks> | ||
public static class SentryPlatformServices | ||
{ | ||
public static ISentryUnityInfo? UnityInfo { get; set; } | ||
public static Action<SentryUnityOptions, ISentryUnityInfo>? PlatformConfiguration { get; set; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
using System.Collections.Generic; | ||
using Sentry.Extensibility; | ||
using Sentry.Unity.Integrations; | ||
using Sentry.Unity.NativeUtils; | ||
using UnityEngine; | ||
|
||
namespace Sentry.Unity; | ||
|
@@ -120,12 +121,12 @@ public static string GetConfigPath(string? notDefaultConfigName = null) | |
/// <remarks> | ||
/// Used for loading the SentryUnityOptions from the ScriptableSentryUnityOptions during runtime. | ||
/// </remarks> | ||
public static SentryUnityOptions? LoadSentryUnityOptions(ISentryUnityInfo unityInfo) | ||
public static SentryUnityOptions? LoadSentryUnityOptions() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We no longer need to provide the |
||
{ | ||
var scriptableOptions = Resources.Load<ScriptableSentryUnityOptions>($"{ConfigRootFolder}/{ConfigName}"); | ||
if (scriptableOptions is not null) | ||
{ | ||
return scriptableOptions.ToSentryUnityOptions(false, unityInfo); | ||
return scriptableOptions.ToSentryUnityOptions(false, SentryPlatformServices.UnityInfo); | ||
} | ||
|
||
return null; | ||
|
Uh oh!
There was an error while loading. Please reload this page.