Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Behavioural Changes

- The SDK no longer sets tags automatically. The promotion of contexts to tags now happens exclusively in Sentry. The `Unity` context got extended by `IsMainThread` for this. The tags `unity.device.unique_identifier` and `unity.gpu.supports_instancing` no longer exist and have no replacement. ([#2459](https://github.com/getsentry/sentry-unity/pull/2459))

### Breaking Changes

- Renamed the option `AttachBreadcrumbsToEvents` to `AddBreadcrumbsWithStructuredLogs` to better reflect its purpose. The option controls if the SDK does BOTH: attach logs as breadcrumbs to events and send them as structured logs ([#2455](https://github.com/getsentry/sentry-unity/pull/2455))
Expand Down
25 changes: 0 additions & 25 deletions src/Sentry.Unity/Integrations/UnityScopeIntegration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public void ConfigureScope(Scope scope)
PopulateUnity(unity);
scope.Contexts.Add(Protocol.Unity.Type, unity);

PopulateTags(scope.SetTag);
PopulateUser(scope);
}

Expand Down Expand Up @@ -158,30 +157,6 @@ private void PopulateUnity(Protocol.Unity unity)
unity.RenderingThreadingMode = MainThreadData.RenderingThreadingMode;
}

private void PopulateTags(Action<string, string> setTag)
{
// TODO revisit which tags we should be adding by default
if (MainThreadData.InstallMode is { } installMode)
{
setTag("unity.install_mode", installMode);
}

if (MainThreadData.SupportsDrawCallInstancing.HasValue)
{
setTag("unity.gpu.supports_instancing", MainThreadData.SupportsDrawCallInstancing.Value.ToTagValue());
}

if (MainThreadData.DeviceType is { } deviceType)
{
setTag("unity.device.device_type", deviceType);
}

if (_options.SendDefaultPii && MainThreadData.DeviceUniqueIdentifier is { } deviceUniqueIdentifier)
{
setTag("unity.device.unique_identifier", deviceUniqueIdentifier);
}
}

private void PopulateUser(Scope scope)
{
if (_options.DefaultUserId is not null)
Expand Down
16 changes: 14 additions & 2 deletions src/Sentry.Unity/Protocol/Unity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public sealed class Unity : ISentryJsonSerializable
public const string Type = "unity";

/// <summary>
/// The Unity editor version
/// The Unity editor version.
/// </summary>
/// <example>
/// 2019.4.40f1
Expand All @@ -29,6 +29,11 @@ public sealed class Unity : ISentryJsonSerializable
/// </example>
public string? InstallMode { get; set; }

/// <summary>
/// Whether this was happening on the main thread or not.
/// </summary>
public bool? IsMainThread { get; set; }

/// <summary>
/// Support for various copy texture cases.
/// </summary>
Expand All @@ -53,14 +58,15 @@ public sealed class Unity : ISentryJsonSerializable
public string? TargetFrameRate { get; set; }

/// <summary>
/// The active scene's name
/// The active scene's name.
/// </summary>
public string? ActiveSceneName { get; set; }

internal Unity Clone()
=> new()
{
InstallMode = InstallMode,
IsMainThread = IsMainThread,
CopyTextureSupport = CopyTextureSupport,
RenderingThreadingMode = RenderingThreadingMode,
TargetFrameRate = TargetFrameRate,
Expand All @@ -83,6 +89,11 @@ public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger)
writer.WriteString("install_mode", InstallMode);
}

if (IsMainThread is not null)
{
writer.WriteBoolean("is_main_thread", IsMainThread.Value);
}

if (!string.IsNullOrWhiteSpace(CopyTextureSupport))
{
writer.WriteString("copy_texture_support", CopyTextureSupport);
Expand Down Expand Up @@ -111,6 +122,7 @@ public static Unity FromJson(JsonElement json)
{
EditorVersion = json.GetPropertyOrNull("editor_version")?.GetString(),
InstallMode = json.GetPropertyOrNull("install_mode")?.GetString(),
IsMainThread = json.GetPropertyOrNull("is_main_thread")?.GetBoolean(),
CopyTextureSupport = json.GetPropertyOrNull("copy_texture_support")?.GetString(),
RenderingThreadingMode = json.GetPropertyOrNull("rendering_threading_mode")?.GetString(),
TargetFrameRate = json.GetPropertyOrNull("target_frame_rate")?.GetString(),
Expand Down
9 changes: 2 additions & 7 deletions src/Sentry.Unity/UnityEventProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ private void SetEventContext(IEventLike sentryEvent)
// Populating the SDK Integrations here (for now) instead of UnityScopeIntegration because it cannot be guaranteed
// that it got added last or that there was not an integration added at a later point
PopulateSdkIntegrations(sentryEvent.Sdk);
// TODO revisit which tags we should be adding by default
sentryEvent.SetTag("unity.is_main_thread", MainThreadData.IsMainThread().ToTagValue());
}
catch (Exception exception)
{
Expand Down Expand Up @@ -117,6 +115,8 @@ private void PopulateDevice(Device device)

private void PopulateUnity(Protocol.Unity unity)
{
unity.IsMainThread = MainThreadData.IsMainThread();

if (!MainThreadData.IsMainThread())
{
return;
Expand All @@ -137,8 +137,3 @@ private void PopulateSdkIntegrations(SdkVersion sdkVersion)
}
}
}

internal static class TagValueNormalizer
{
internal static string ToTagValue(this bool value) => value ? "true" : "false";
}
12 changes: 4 additions & 8 deletions test/Sentry.Unity.Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public IEnumerator DebugLogError_OnMainThread_IsCapturedAndIsMainThreadIsTrue()

var triggeredEvent = _testHttpClientHandler.GetEvent(_identifyingEventValueAttribute, _eventReceiveTimeout);
Assert.That(triggeredEvent, Does.Contain(_identifyingEventValueAttribute));
Assert.That(triggeredEvent, Does.Contain("unity.is_main_thread\":\"true\""));
Assert.That(triggeredEvent, Does.Contain("is_main_thread\":true"));
}

[UnityTest]
Expand All @@ -259,24 +259,22 @@ public IEnumerator DebugLogError_InTask_IsCapturedAndIsMainThreadIsFalse()

var triggeredEvent = _testHttpClientHandler.GetEvent(_identifyingEventValueAttribute, _eventReceiveTimeout);
Assert.That(triggeredEvent, Does.Contain(_identifyingEventValueAttribute));
Assert.That(triggeredEvent, Does.Contain("unity.is_main_thread\":\"false\""));
Assert.That(triggeredEvent, Does.Contain("is_main_thread\":false"));
}

[UnityTest]
public IEnumerator DebugLogException_OnMainThread_IsCapturedAndIsMainThreadIsTrue()
{
yield return SetupSceneCoroutine("1_BugFarm");

var expectedAttribute = CreateAttribute("unity.is_main_thread", "true");

using var _ = InitSentrySdk();
var testBehaviour = new GameObject("TestHolder").AddComponent<TestMonoBehaviour>();

testBehaviour.gameObject.SendMessage(nameof(testBehaviour.DebugLogException), _eventMessage);

var triggeredEvent = _testHttpClientHandler.GetEvent(_identifyingEventValueAttribute, _eventReceiveTimeout);
Assert.That(triggeredEvent, Does.Contain(_identifyingEventValueAttribute));
Assert.That(triggeredEvent, Does.Contain(expectedAttribute));
Assert.That(triggeredEvent, Does.Contain("is_main_thread\":true"));
}

[UnityTest]
Expand All @@ -289,16 +287,14 @@ public IEnumerator DebugLogException_InTask_IsCapturedAndIsMainThreadIsFalse()

yield return SetupSceneCoroutine("1_BugFarm");

var expectedAttribute = CreateAttribute("unity.is_main_thread", "false");

using var _ = InitSentrySdk();
var testBehaviour = new GameObject("TestHolder").AddComponent<TestMonoBehaviour>();

testBehaviour.gameObject.SendMessage(nameof(testBehaviour.DebugLogExceptionInTask), _eventMessage);

var triggeredEvent = _testHttpClientHandler.GetEvent(_identifyingEventValueAttribute, _eventReceiveTimeout);
Assert.That(triggeredEvent, Does.Contain(_identifyingEventValueAttribute));
Assert.That(triggeredEvent, Does.Contain(expectedAttribute));
Assert.That(triggeredEvent, Does.Contain("is_main_thread\":false"));
}

[UnityTest]
Expand Down
5 changes: 5 additions & 0 deletions test/Sentry.Unity.Tests/Protocol/UnityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject()
var sut = new Unity.Protocol.Unity
{
InstallMode = "DeveloperBuild",
IsMainThread = false,
CopyTextureSupport = "Copy3D",
RenderingThreadingMode = "MultiThreaded",
TargetFrameRate = "30",
Expand All @@ -31,6 +32,7 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject()
Assert.AreEqual(
"{\"type\":\"unity\"," +
"\"install_mode\":\"DeveloperBuild\"," +
"\"is_main_thread\":false," +
"\"copy_texture_support\":\"Copy3D\"," +
"\"rendering_threading_mode\":\"MultiThreaded\"," +
"\"target_frame_rate\":\"30\"," +
Expand All @@ -44,6 +46,7 @@ public void Clone_CopyValues()
var sut = new Unity.Protocol.Unity
{
InstallMode = "DeveloperBuild",
IsMainThread = false,
CopyTextureSupport = "Copy3D",
RenderingThreadingMode = "MultiThreaded",
TargetFrameRate = "30",
Expand All @@ -53,6 +56,7 @@ public void Clone_CopyValues()
var clone = sut.Clone();

Assert.AreEqual(sut.InstallMode, clone.InstallMode);
Assert.AreEqual(sut.IsMainThread, clone.IsMainThread);
Assert.AreEqual(sut.CopyTextureSupport, clone.CopyTextureSupport);
Assert.AreEqual(sut.RenderingThreadingMode, clone.RenderingThreadingMode);
Assert.AreEqual(sut.TargetFrameRate, clone.TargetFrameRate);
Expand All @@ -71,6 +75,7 @@ public void SerializeObject_TestCase_SerializesAsExpected((Unity.Protocol.Unity
{
new object[] { (new Unity.Protocol.Unity(), "{\"type\":\"unity\"}") },
new object[] { (new Unity.Protocol.Unity { InstallMode = "Adhoc" }, "{\"type\":\"unity\",\"install_mode\":\"Adhoc\"}") },
new object[] { (new Unity.Protocol.Unity { IsMainThread = false }, "{\"type\":\"unity\",\"is_main_thread\":false}") },
new object[] { (new Unity.Protocol.Unity { CopyTextureSupport = "TextureToRT" }, "{\"type\":\"unity\",\"copy_texture_support\":\"TextureToRT\"}") },
new object[] { (new Unity.Protocol.Unity { RenderingThreadingMode = "NativeGraphicsJobs" }, "{\"type\":\"unity\",\"rendering_threading_mode\":\"NativeGraphicsJobs\"}") },
new object[] { (new Unity.Protocol.Unity { TargetFrameRate = "30" }, "{\"type\":\"unity\",\"target_frame_rate\":\"30\"}") },
Expand Down
60 changes: 0 additions & 60 deletions test/Sentry.Unity.Tests/UnityEventScopeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,66 +354,6 @@ public void UserId_UnchangedIfNonEmpty()
Assert.AreEqual(scope.User.Id, "bar");
}

[Test]
public void Tags_Set()
{
// arrange
var systemInfo = new TestSentrySystemInfo
{
SupportsDrawCallInstancing = true,
DeviceType = new(() => "test type"),
DeviceUniqueIdentifier = new(() => "f810306c-68db-4ebe-89ba-13c457449339"),
InstallMode = ApplicationInstallMode.Store.ToString()
};
MainThreadData.SentrySystemInfo = systemInfo;
MainThreadData.CollectData();

var sentryOptions = new SentryUnityOptions { SendDefaultPii = true };
var scopeUpdater = new UnityScopeUpdater(sentryOptions, _testApplication);
var unityInfo = new TestUnityInfo { IL2CPP = true };
var unityEventProcessor = new UnityEventProcessor(sentryOptions, unityInfo);
var scope = new Scope(sentryOptions);
var sentryEvent = new SentryEvent();
var transaction = new SentryTransaction("name", "operation");

// act
scopeUpdater.ConfigureScope(scope);
scope.Apply(sentryEvent);
scope.Apply(transaction);
unityEventProcessor.Process(sentryEvent);
unityEventProcessor.Process(transaction);

// assert
AssertEventProcessorTags(systemInfo, sentryEvent.Tags);
AssertEventProcessorTags(systemInfo, transaction.Tags);
}

private void AssertEventProcessorTags(ISentrySystemInfo systemInfo, IReadOnlyDictionary<string, string> tags)
{
Assert.IsNotNull(tags);
Assert.NotZero(tags.Count);

var unityInstallMode = tags.SingleOrDefault(t => t.Key == "unity.install_mode");
Assert.NotNull(unityInstallMode);
Assert.AreEqual(systemInfo.InstallMode, unityInstallMode.Value);

var supportsInstancing = tags.SingleOrDefault(t => t.Key == "unity.gpu.supports_instancing");
Assert.NotNull(supportsInstancing);
Assert.AreEqual(systemInfo.SupportsDrawCallInstancing, bool.Parse(supportsInstancing.Value));

var deviceType = tags.SingleOrDefault(t => t.Key == "unity.device.device_type");
Assert.NotNull(deviceType);
Assert.AreEqual(systemInfo.DeviceType!.Value, deviceType.Value);

var deviceUniqueIdentifier = tags.SingleOrDefault(t => t.Key == "unity.device.unique_identifier");
Assert.NotNull(deviceUniqueIdentifier);
Assert.AreEqual(systemInfo.DeviceUniqueIdentifier!.Value, deviceUniqueIdentifier.Value);

var isMainThread = tags.SingleOrDefault(t => t.Key == "unity.is_main_thread");
Assert.NotNull(isMainThread);
Assert.AreEqual("true", isMainThread.Value);
}

[Test]
public void OperatingSystemProtocol_Assigned()
{
Expand Down
Loading