Skip to content

Commit

Permalink
feat: Runtime Init instrumentation (#991)
Browse files Browse the repository at this point in the history
* feat: scene-load transctions based on SceneManagerAPI

* Update package-dev/Runtime/SentryInitialization.cs

* creating span for loading

* capturing scene load transaction during startup

* refactored the self initialization flag

* creating spans through runtime initialzation and added test setup

* finished startup capture & added tests

* tweaked tests

* tests & naming

* test asmdef editor exclusive

* asmdef for runtime tests only

* removed argument check in smoketest configure

* logging cleanup

* disabling auto session tracking on WebGL

* removing expected session from smoketest

* initialize later on webgl

* Revert "Merge branch 'main' into feat/scene-load-tx"

This reverts commit 74a520c, reversing
changes made to bcd55a9.

* 2020 symbol upload expectations

* renamed runtime spans

* span remame

* uncompressed webgl builds for local convenience

* disabling runtime tracing on WebGL

* removed jetbrains annotations

* unity 2020.3 guard

* fixed broken merge

* rest of the merge

* Updated CHANGELOG.md

* just scene loading

* Updated CHANGELOG.md

* cleanup

* cleanup #2

* logging

* revolved broken class naming

* runtime init hooks

* Updated CHANGELOG.md

* Updated CHANGELOG.md

* span naming

* setting span name/desc

* first scene load name tweak

* cleanup

* cleanup

Co-authored-by: Ivan Dlugos <dlugos.ivan@gmail.com>
Co-authored-by: Ivan Dlugos <6349682+vaind@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 5, 2022
1 parent af421b2 commit 3083a58
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

### Features

- Automated Performance Instrumentation for Runtime Initialization ([#991](https://github.com/getsentry/sentry-unity/pull/991))
- Automated Performance Instrumentation for Scene Loading ([#768](https://github.com/getsentry/sentry-unity/pull/768))

### Dependencies
Expand Down
19 changes: 19 additions & 0 deletions package-dev/Runtime/SentryInitialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#endif

using System;
using Sentry.Extensibility;
#if UNITY_2020_3_OR_NEWER
using System.Buffers;
using System.Runtime.InteropServices;
Expand All @@ -40,6 +41,12 @@ namespace Sentry.Unity
{
public static class SentryInitialization
{
private 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)]
Expand Down Expand Up @@ -83,6 +90,18 @@ public static void Init()
{
SentrySdk.CaptureException(nativeInitException);
}

#if !SENTRY_WEBGL
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");
#endif
}
}
}
Expand Down
102 changes: 102 additions & 0 deletions package-dev/Runtime/SentryIntegrations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
#define SENTRY_SCENE_MANAGER_TRACING_INTEGRATION
#endif

#if !UNITY_EDITOR
#if UNITY_WEBGL
#define SENTRY_WEBGL
#endif
#endif

using Sentry.Extensibility;
using Sentry.Integrations;
using UnityEngine;
Expand All @@ -16,6 +22,10 @@ public static void Configure(SentryUnityOptions options)
#if SENTRY_SCENE_MANAGER_TRACING_INTEGRATION
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
options.AddIntegration(new StartupTracingIntegration());
#endif
options.AddIntegration(new SceneManagerTracingIntegration());
}
else
Expand All @@ -26,6 +36,98 @@ public static void Configure(SentryUnityOptions options)
}
}

#if !SENTRY_WEBGL
public class StartupTracingIntegration : ISdkIntegration
{
private static ISpan AfterAssembliesSpan;
private const string AfterAssembliesSpanOperation = "runtime.init.afterassemblies";
private static ISpan SplashScreenSpan;
private const string SplashScreenSpanOperation = "runtime.init.splashscreen";
private static ISpan FirstSceneLoadSpan;
private const string FirstSceneLoadSpanOperation = "runtime.init.firstscene";

// Flag to make sure we create spans through the runtime initialization only once
private static bool StartupAlreadyCaptured;
private static bool IntegrationRegistered;

private static IDiagnosticLogger Logger;

public void Register(IHub hub, SentryOptions options)
{
Logger = options.DiagnosticLogger;
IntegrationRegistered = true;
}

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
public static void AfterAssembliesLoaded()
{
if (!IntegrationRegistered || StartupAlreadyCaptured)
{
return;
}

SentryInitialization.SubSystemRegistrationSpan?.Finish(SpanStatus.Ok);
SentryInitialization.SubSystemRegistrationSpan = null;

Logger?.LogDebug("Creating '{0}' span.", AfterAssembliesSpanOperation);
AfterAssembliesSpan = SentryInitialization.InitSpan?.StartChild(AfterAssembliesSpanOperation, "after assemblies");
}

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
public static void BeforeSplashScreen()
{
if (!IntegrationRegistered || StartupAlreadyCaptured)
{
return;
}

AfterAssembliesSpan?.Finish(SpanStatus.Ok);
AfterAssembliesSpan = null;

Logger?.LogDebug("Creating '{0}' span.", SplashScreenSpanOperation);
SplashScreenSpan = SentryInitialization.InitSpan?.StartChild(SplashScreenSpanOperation, "splashscreen");
}

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void BeforeSceneLoad()
{
if (!IntegrationRegistered || StartupAlreadyCaptured)
{
return;
}

SplashScreenSpan?.Finish(SpanStatus.Ok);
SplashScreenSpan = null;

Logger?.LogDebug("Creating '{0}' span.", FirstSceneLoadSpanOperation);
FirstSceneLoadSpan = SentryInitialization.InitSpan?.StartChild(FirstSceneLoadSpanOperation, "first scene load");
}

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
public static void AfterSceneLoad()
{
if (!IntegrationRegistered || StartupAlreadyCaptured)
{
return;
}

FirstSceneLoadSpan?.Finish(SpanStatus.Ok);
FirstSceneLoadSpan = null;

SentryInitialization.InitSpan?.Finish(SpanStatus.Ok);
SentryInitialization.InitSpan = null;

Logger?.LogInfo("Finishing '{0}' transaction.", SentryInitialization.StartupTransactionOperation);
SentrySdk.ConfigureScope(s =>
{
s.Transaction?.Finish(SpanStatus.Ok);
});

StartupAlreadyCaptured = true;
}
}
#endif

#if SENTRY_SCENE_MANAGER_TRACING_INTEGRATION
public class SceneManagerTracingIntegration : ISdkIntegration
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public IEnumerator SceneManagerTracingIntegration_DuringSceneLoad_CreatesTransac
yield return SetupSceneCoroutine("1_Bugfarm");

var triggeredEvent = _testHttpClientHandler.GetEvent(TestEventType.SentryTransaction, _eventReceiveTimeout);

Assert.That(triggeredEvent, Does.Contain(SceneManagerTracingAPI.TransactionOperation));
}

Expand Down
6 changes: 3 additions & 3 deletions test/Scripts.Integration.Test/integration-test.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ┌───────────────────────────────────────────────────┐ #
# │ This script is for local use only, │ #
# ┌───────────────────────────────────────────────────┐ #
# │ This script is for local use only, │ #
# │ utilizing the scripts locally we use in CI. │ #
# └───────────────────────────────────────────────────┘ #
# └───────────────────────────────────────────────────┘ #

param(
[string] $UnityVersion,
Expand Down

0 comments on commit 3083a58

Please sign in to comment.