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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- The SDK automatically subscribes to and leaves breadcrumbs for `Application.lowMemory` events ([#2406](https://github.com/getsentry/sentry-unity/pull/2406))
- The SDK now also reports the currently allocated memory when reporting an event or transaction. ([#2398](https://github.com/getsentry/sentry-unity/pull/2398))
- The SDK defaults `EnvironmentUser` to sensible values based on the current platform. This is still guarded by the `SendDefaultPII` flag. ([#2402](https://github.com/getsentry/sentry-unity/pull/2402))

Expand Down
6 changes: 6 additions & 0 deletions src/Sentry.Unity/Integrations/IApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Sentry.Unity.Integrations;
internal interface IApplication
{
event Application.LogCallback LogMessageReceived;
event Action LowMemory;
event Action Quitting;
string ActiveSceneName { get; }
bool IsEditor { get; }
Expand All @@ -28,10 +29,12 @@ public sealed class ApplicationAdapter : IApplication
private ApplicationAdapter()
{
Application.logMessageReceivedThreaded += OnLogMessageReceived;
Application.lowMemory += OnLowMemory;
Application.quitting += OnQuitting;
}

public event Application.LogCallback? LogMessageReceived;
public event Action? LowMemory;

public event Action? Quitting;

Expand All @@ -54,6 +57,9 @@ private ApplicationAdapter()
private void OnLogMessageReceived(string condition, string stackTrace, LogType type)
=> LogMessageReceived?.Invoke(condition, stackTrace, type);

private void OnLowMemory()
=> LowMemory?.Invoke();

private void OnQuitting()
=> Quitting?.Invoke();
}
37 changes: 37 additions & 0 deletions src/Sentry.Unity/Integrations/LowMemoryIntegration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using Sentry.Integrations;

namespace Sentry.Unity.Integrations;

internal class LowMemoryIntegration : ISdkIntegration
{
private static readonly Dictionary<string, string> lowMemoryData = new() { { "action", "LOW_MEMORY" } };

private IHub _hub = null!;
private IApplication _application;

public LowMemoryIntegration(IApplication? application = null)
{
_application = application ?? ApplicationAdapter.Instance;
}

public void Register(IHub hub, SentryOptions options)
{
_hub = hub;

_application.LowMemory += () =>
{
if (!_hub.IsEnabled)
{
return;
}

hub.AddBreadcrumb(new Breadcrumb(
message: "Low memory",
type: "system",
data: lowMemoryData,
category: "device.event",
level: BreadcrumbLevel.Warning));
};
}
}
1 change: 1 addition & 0 deletions src/Sentry.Unity/SentryUnityOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ internal SentryUnityOptions(IApplication? application = null,
AddIntegration(new SceneManagerTracingIntegration());
AddIntegration(new LifeCycleIntegration(behaviour));
AddIntegration(new TraceGenerationIntegration(behaviour));
AddIntegration(new LowMemoryIntegration());

AddExceptionFilter(new UnityBadGatewayExceptionFilter());
AddExceptionFilter(new UnityWebExceptionFilter());
Expand Down
72 changes: 72 additions & 0 deletions test/Sentry.Unity.Tests/LowMemoryIntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Linq;
using NUnit.Framework;
using Sentry.Unity.Integrations;
using Sentry.Unity.Tests.Stubs;

namespace Sentry.Unity.Tests;

public class LowMemoryIntegrationTests
{
private class Fixture
{
public TestApplication Application { get; set; } = new();
public TestHub Hub { get; set; } = new();
public SentryUnityOptions Options { get; set; } = new();

public LowMemoryIntegration GetSut() => new(Application);
}

private Fixture _fixture = null!;

[SetUp]
public void SetUp()
{
_fixture = new Fixture();
}

[Test]
public void LowMemory_DisabledHub_NoBreadcrumbAdded()
{
_fixture.Hub = new TestHub(false);
var sut = _fixture.GetSut();

sut.Register(_fixture.Hub, _fixture.Options);
_fixture.Application.OnLowMemory();

Assert.Zero(_fixture.Hub.ConfigureScopeCalls.Count);
}

[Test]
public void LowMemory_EnabledHub_BreadcrumbAdded()
{
var sut = _fixture.GetSut();

sut.Register(_fixture.Hub, _fixture.Options);
_fixture.Application.OnLowMemory();

var configureScope = _fixture.Hub.ConfigureScopeCalls.Single();
var scope = new Scope(_fixture.Options);
configureScope(scope);
var actualCrumb = scope.Breadcrumbs.Single();

Assert.AreEqual("Low memory", actualCrumb.Message);
Assert.AreEqual("device.event", actualCrumb.Category);
Assert.AreEqual("system", actualCrumb.Type);
Assert.AreEqual(BreadcrumbLevel.Warning, actualCrumb.Level);
Assert.NotNull(actualCrumb.Data);
Assert.AreEqual("LOW_MEMORY", actualCrumb.Data?["action"]);
}

[Test]
public void LowMemory_MultipleTriggers_MultipleBreadcrumbsAdded()
{
var sut = _fixture.GetSut();

sut.Register(_fixture.Hub, _fixture.Options);
_fixture.Application.OnLowMemory();
_fixture.Application.OnLowMemory();
_fixture.Application.OnLowMemory();

Assert.AreEqual(3, _fixture.Hub.ConfigureScopeCalls.Count);
}
}
5 changes: 4 additions & 1 deletion test/SharedClasses/TestApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public TestApplication(
}

public event Application.LogCallback? LogMessageReceived;
public event Action? LowMemory;
public event Action? Quitting;
public string ActiveSceneName => "TestSceneName";
public bool IsEditor { get; set; }
Expand All @@ -34,8 +35,10 @@ public TestApplication(
public string UnityVersion { get; set; }
public string PersistentDataPath { get; set; }
public RuntimePlatform Platform { get; set; }
private void OnQuitting() => Quitting?.Invoke();

private void OnLogMessageReceived(string condition, string stacktrace, LogType type)
=> LogMessageReceived?.Invoke(condition, stacktrace, type);

public void OnLowMemory() => LowMemory?.Invoke();
private void OnQuitting() => Quitting?.Invoke();
}
Loading