Skip to content

Commit

Permalink
Add transaction processor (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonCropp committed Sep 22, 2022
1 parent c3d86d6 commit 2fac64b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

- Don't access Unity `AnalyticsSessionInfo.userId` on unknown platforms ([#971](https://github.com/getsentry/sentry-unity/pull/971))
- Keep previously set IL2CPP compiler arguments (i.e append instead of overwriting) ([#972](https://github.com/getsentry/sentry-unity/pull/972))
- Add transaction processor ([#978](https://github.com/getsentry/sentry-unity/pull/978))

### Dependencies

Expand Down
8 changes: 5 additions & 3 deletions src/Sentry.Unity/SentryUnityOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,19 @@ internal string? DefaultUserId
public SentryUnityOptions() : this(false, null, ApplicationAdapter.Instance) { }

internal SentryUnityOptions(bool isBuilding, ISentryUnityInfo? unityInfo, IApplication application) :
this(SentryMonoBehaviour.Instance, application, unityInfo, isBuilding)
this(SentryMonoBehaviour.Instance, application, isBuilding)
{ }

internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication application, ISentryUnityInfo? unityInfo, bool isBuilding)
internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication application, bool isBuilding)
{
// IL2CPP doesn't support Process.GetCurrentProcess().StartupTime
DetectStartupTime = StartupTimeDetectionMode.Fast;

this.AddInAppExclude("UnityEngine");
this.AddInAppExclude("UnityEditor");
this.AddEventProcessor(new UnityEventProcessor(this, behaviour));
var processor = new UnityEventProcessor(this, behaviour);
this.AddEventProcessor(processor);
this.AddTransactionProcessor(processor);

this.AddIntegration(new UnityLogHandlerIntegration());
this.AddIntegration(new AnrIntegration(behaviour));
Expand Down
82 changes: 48 additions & 34 deletions src/Sentry.Unity/UnityEventProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,80 @@

namespace Sentry.Unity
{
internal class UnityEventProcessor : ISentryEventProcessor
internal class UnityEventProcessor :
ISentryEventProcessor,
ISentryTransactionProcessor
{
private readonly SentryUnityOptions _sentryOptions;
private readonly MainThreadData _mainThreadData;


public UnityEventProcessor(SentryUnityOptions sentryOptions, SentryMonoBehaviour sentryMonoBehaviour)
{
_sentryOptions = sentryOptions;
_mainThreadData = sentryMonoBehaviour.MainThreadData;
}

public Transaction Process(Transaction transaction)
{
SetEventContext(transaction);
return transaction;
}

public SentryEvent Process(SentryEvent @event)
{
SetEventContext(@event);

@event.ServerName = null;

return @event;
}

private void SetEventContext(IEventLike sentryEvent)
{
try
{
PopulateDevice(@event.Contexts.Device);
PopulateDevice(sentryEvent.Contexts.Device);
// 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(@event.Sdk);
PopulateSdkIntegrations(sentryEvent.Sdk);
// TODO revisit which tags we should be adding by default
@event.SetTag("unity.is_main_thread", _mainThreadData.IsMainThread().ToTagValue());
sentryEvent.SetTag("unity.is_main_thread", _mainThreadData.IsMainThread().ToTagValue());
}
catch (Exception ex)
catch (Exception exception)
{
_sentryOptions.DiagnosticLogger?.LogError("{0} processing failed.", ex, nameof(SentryEvent));
_sentryOptions.DiagnosticLogger?.LogError("{0} processing failed.", exception, nameof(SentryEvent));
}

@event.ServerName = null;

return @event;
}

private void PopulateDevice(Device device)
{
if (_mainThreadData.IsMainThread())
if (!_mainThreadData.IsMainThread())
{
device.BatteryStatus = SystemInfo.batteryStatus.ToString();
return;
}

var batteryLevel = SystemInfo.batteryLevel;
if (batteryLevel > 0.0)
{
device.BatteryLevel = (short?)(batteryLevel * 100);
}
device.BatteryStatus = SystemInfo.batteryStatus.ToString();

switch (Input.deviceOrientation)
{
case UnityEngine.DeviceOrientation.Portrait:
case UnityEngine.DeviceOrientation.PortraitUpsideDown:
device.Orientation = DeviceOrientation.Portrait;
break;
case UnityEngine.DeviceOrientation.LandscapeLeft:
case UnityEngine.DeviceOrientation.LandscapeRight:
device.Orientation = DeviceOrientation.Landscape;
break;
case UnityEngine.DeviceOrientation.FaceUp:
case UnityEngine.DeviceOrientation.FaceDown:
// TODO: Add to protocol?
break;
}
var batteryLevel = SystemInfo.batteryLevel;
if (batteryLevel > 0.0)
{
device.BatteryLevel = (short?)(batteryLevel * 100);
}

switch (Input.deviceOrientation)
{
case UnityEngine.DeviceOrientation.Portrait:
case UnityEngine.DeviceOrientation.PortraitUpsideDown:
device.Orientation = DeviceOrientation.Portrait;
break;
case UnityEngine.DeviceOrientation.LandscapeLeft:
case UnityEngine.DeviceOrientation.LandscapeRight:
device.Orientation = DeviceOrientation.Landscape;
break;
case UnityEngine.DeviceOrientation.FaceUp:
case UnityEngine.DeviceOrientation.FaceDown:
// TODO: Add to protocol?
break;
}
}

Expand All @@ -80,6 +94,6 @@ private void PopulateSdkIntegrations(SdkVersion sdkVersion)

internal static class TagValueNormalizer
{
internal static string ToTagValue(this Boolean value) => value ? "true" : "false";
internal static string ToTagValue(this bool value) => value ? "true" : "false";
}
}
2 changes: 1 addition & 1 deletion test/Sentry.Unity.Tests/ContextWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void Arguments()

};
var context = new MockContextWriter();
var options = new SentryUnityOptions(_sentryMonoBehaviour, _testApplication, null, false)
var options = new SentryUnityOptions(_sentryMonoBehaviour, _testApplication, false)
{
Dsn = "http://publickey@localhost/12345",
Enabled = true,
Expand Down
14 changes: 10 additions & 4 deletions test/Sentry.Unity.Tests/UnityEventScopeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public void SentrySdkCaptureEvent(bool collectOnUiThread)
RenderingThreadingMode = new Lazy<string>(() => "MultiThreaded"),
StartTime = new(() => DateTimeOffset.UtcNow),
};
var options = new SentryUnityOptions(_sentryMonoBehaviour, _testApplication, null, false)
var options = new SentryUnityOptions(_sentryMonoBehaviour, _testApplication, false)
{
Dsn = "https://b8fd848b31444e80aa102e96d2a6a648@o510466.ingest.sentry.io/5606182",
Enabled = true,
Expand Down Expand Up @@ -326,8 +326,8 @@ public void Tags_Set()
_sentryMonoBehaviour.SentrySystemInfo = new TestSentrySystemInfo
{
SupportsDrawCallInstancing = true,
DeviceType = new Lazy<string>(() => "test type"),
DeviceUniqueIdentifier = new Lazy<string>(() => "f810306c-68db-4ebe-89ba-13c457449339"),
DeviceType = new(() => "test type"),
DeviceUniqueIdentifier = new(() => "f810306c-68db-4ebe-89ba-13c457449339"),
InstallMode = ApplicationInstallMode.Store.ToString()
};

Expand All @@ -336,16 +336,22 @@ public void Tags_Set()
var unityEventProcessor = new UnityEventProcessor(sentryOptions, _sentryMonoBehaviour);
var scope = new Scope(sentryOptions);
var sentryEvent = new SentryEvent();
var transaction = new Transaction("name", "operation");

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

// assert
var tags = sentryEvent.Tags;
AssertEventProcessorTags(sentryEvent.Tags);
AssertEventProcessorTags(transaction.Tags);
}

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

Expand Down

0 comments on commit 2fac64b

Please sign in to comment.