Skip to content

Commit

Permalink
Android Scope Sync (#1737)
Browse files Browse the repository at this point in the history
* Add AndroidScopeObserver

* Update CHANGELOG.md
  • Loading branch information
mattjohnsonpint authored Jun 21, 2022
1 parent 36ccacf commit 610dee8
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Android Scope Sync ([#1737](https://github.com/getsentry/sentry-dotnet/pull/1737))

## Sentry.Maui 3.18.0-preview.1

### Features
Expand Down
19 changes: 18 additions & 1 deletion samples/Sentry.Samples.Android/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,25 @@ protected override void OnCreate(Bundle? savedInstanceState)
{
SentrySdk.Init(this, o =>
{
o.Debug = true;
o.Dsn = "https://eb18e953812b41c3aeb042e666fd3b5c@o447951.ingest.sentry.io/5428537";
o.SendDefaultPii = true; // adds the user's IP address automatically
});

// Here's an example of adding custom scope information.
// This can be done at any time, and will be passed through to the Java SDK as well.
SentrySdk.ConfigureScope(scope =>
{
scope.AddBreadcrumb("Custom Breadcrumb");
scope.SetExtra("Test", "Custom Extra Data");
scope.User = new User
{
Username = "SomeUser",
Email = "test@example.com",
Other =
{
["CustomInfo"] = "Custom User Info"
}
};
});

base.OnCreate(savedInstanceState);
Expand Down
101 changes: 101 additions & 0 deletions src/Sentry/Android/AndroidScopeObserver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using Sentry.Android.Extensions;
using Sentry.Extensibility;

namespace Sentry.Android;

internal sealed class AndroidScopeObserver : IScopeObserver
{
private readonly SentryOptions _options;
private readonly IScopeObserver? _innerObserver;

public AndroidScopeObserver(SentryOptions options)
{
_options = options;

// Chain any previous observer, but guard against circular reference.
var observer = options.ScopeObserver;
_innerObserver = observer is AndroidScopeObserver ? null : observer;
}

public void AddBreadcrumb(Breadcrumb breadcrumb)
{
try
{
var b = breadcrumb.ToJavaBreadcrumb();
Java.Sentry.AddBreadcrumb(b);
}
finally
{
_innerObserver?.AddBreadcrumb(breadcrumb);
}
}

public void SetExtra(string key, object? value)
{
try
{
if (value is null)
{
_options.LogDebug("Extra with key '{0}' was null.", key);
return;
}

if (value is string s)
{
Java.Sentry.SetExtra(key, s);
return;
}

try
{
var json = JsonSerializer.Serialize(value);
Java.Sentry.SetExtra(key, json);
}
catch (Exception ex)
{
_options.LogError("Extra with key '{0}' could not be serialized.", ex, key);
}
}
finally
{
_innerObserver?.SetExtra(key, value);
}
}

public void SetTag(string key, string value)
{
try
{
Java.Sentry.SetTag(key, value);
}
finally
{
_innerObserver?.SetTag(key, value);
}
}

public void UnsetTag(string key)
{
try
{
Java.Sentry.RemoveTag(key);
}
finally
{
_innerObserver?.UnsetTag(key);
}
}

public void SetUser(User? user)
{
try
{
var u = user?.ToJavaUser();
Java.Sentry.SetUser(u);
}
finally
{
_innerObserver?.SetUser(user);
}
}
}
29 changes: 29 additions & 0 deletions src/Sentry/Android/Extensions/UserExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.ObjectModel;

namespace Sentry.Android.Extensions;

internal static class UserExtensions
{
private static readonly IDictionary<string, string> EmptyDictionary =
new ReadOnlyDictionary<string, string>(new Dictionary<string, string>());

public static User ToUser(this Java.Protocol.User user) =>
new()
{
Email = user.Email,
Id = user.Id,
IpAddress = user.IpAddress,
Username = user.Username,
Other = user.Others ?? EmptyDictionary
};

public static Java.Protocol.User ToJavaUser(this User user) =>
new()
{
Email = user.Email,
Id = user.Id,
IpAddress = user.IpAddress,
Username = user.Username,
Others = user.Other.Count == 0 ? null : user.Other
};
}
2 changes: 2 additions & 0 deletions src/Sentry/Android/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ public static IDisposable Init(AndroidContext context, SentryOptions options)
options.IsGlobalModeEnabled = true;
options.AddEventProcessor(new AndroidEventProcessor(androidOptions!));
options.CrashedLastRun = () => Java.Sentry.IsCrashedLastRun()?.BooleanValue() is true;
options.EnableScopeSync = true;
options.ScopeObserver = new AndroidScopeObserver(options);
// TODO: Pause/Resume

// Init the managed SDK
Expand Down

0 comments on commit 610dee8

Please sign in to comment.