Skip to content

Commit 610dee8

Browse files
Android Scope Sync (#1737)
* Add AndroidScopeObserver * Update CHANGELOG.md
1 parent 36ccacf commit 610dee8

File tree

5 files changed

+156
-1
lines changed

5 files changed

+156
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Android Scope Sync ([#1737](https://github.com/getsentry/sentry-dotnet/pull/1737))
8+
39
## Sentry.Maui 3.18.0-preview.1
410

511
### Features

samples/Sentry.Samples.Android/MainActivity.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,25 @@ protected override void OnCreate(Bundle? savedInstanceState)
99
{
1010
SentrySdk.Init(this, o =>
1111
{
12-
o.Debug = true;
1312
o.Dsn = "https://eb18e953812b41c3aeb042e666fd3b5c@o447951.ingest.sentry.io/5428537";
13+
o.SendDefaultPii = true; // adds the user's IP address automatically
14+
});
15+
16+
// Here's an example of adding custom scope information.
17+
// This can be done at any time, and will be passed through to the Java SDK as well.
18+
SentrySdk.ConfigureScope(scope =>
19+
{
20+
scope.AddBreadcrumb("Custom Breadcrumb");
21+
scope.SetExtra("Test", "Custom Extra Data");
22+
scope.User = new User
23+
{
24+
Username = "SomeUser",
25+
Email = "test@example.com",
26+
Other =
27+
{
28+
["CustomInfo"] = "Custom User Info"
29+
}
30+
};
1431
});
1532

1633
base.OnCreate(savedInstanceState);
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using Sentry.Android.Extensions;
2+
using Sentry.Extensibility;
3+
4+
namespace Sentry.Android;
5+
6+
internal sealed class AndroidScopeObserver : IScopeObserver
7+
{
8+
private readonly SentryOptions _options;
9+
private readonly IScopeObserver? _innerObserver;
10+
11+
public AndroidScopeObserver(SentryOptions options)
12+
{
13+
_options = options;
14+
15+
// Chain any previous observer, but guard against circular reference.
16+
var observer = options.ScopeObserver;
17+
_innerObserver = observer is AndroidScopeObserver ? null : observer;
18+
}
19+
20+
public void AddBreadcrumb(Breadcrumb breadcrumb)
21+
{
22+
try
23+
{
24+
var b = breadcrumb.ToJavaBreadcrumb();
25+
Java.Sentry.AddBreadcrumb(b);
26+
}
27+
finally
28+
{
29+
_innerObserver?.AddBreadcrumb(breadcrumb);
30+
}
31+
}
32+
33+
public void SetExtra(string key, object? value)
34+
{
35+
try
36+
{
37+
if (value is null)
38+
{
39+
_options.LogDebug("Extra with key '{0}' was null.", key);
40+
return;
41+
}
42+
43+
if (value is string s)
44+
{
45+
Java.Sentry.SetExtra(key, s);
46+
return;
47+
}
48+
49+
try
50+
{
51+
var json = JsonSerializer.Serialize(value);
52+
Java.Sentry.SetExtra(key, json);
53+
}
54+
catch (Exception ex)
55+
{
56+
_options.LogError("Extra with key '{0}' could not be serialized.", ex, key);
57+
}
58+
}
59+
finally
60+
{
61+
_innerObserver?.SetExtra(key, value);
62+
}
63+
}
64+
65+
public void SetTag(string key, string value)
66+
{
67+
try
68+
{
69+
Java.Sentry.SetTag(key, value);
70+
}
71+
finally
72+
{
73+
_innerObserver?.SetTag(key, value);
74+
}
75+
}
76+
77+
public void UnsetTag(string key)
78+
{
79+
try
80+
{
81+
Java.Sentry.RemoveTag(key);
82+
}
83+
finally
84+
{
85+
_innerObserver?.UnsetTag(key);
86+
}
87+
}
88+
89+
public void SetUser(User? user)
90+
{
91+
try
92+
{
93+
var u = user?.ToJavaUser();
94+
Java.Sentry.SetUser(u);
95+
}
96+
finally
97+
{
98+
_innerObserver?.SetUser(user);
99+
}
100+
}
101+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.Collections.ObjectModel;
2+
3+
namespace Sentry.Android.Extensions;
4+
5+
internal static class UserExtensions
6+
{
7+
private static readonly IDictionary<string, string> EmptyDictionary =
8+
new ReadOnlyDictionary<string, string>(new Dictionary<string, string>());
9+
10+
public static User ToUser(this Java.Protocol.User user) =>
11+
new()
12+
{
13+
Email = user.Email,
14+
Id = user.Id,
15+
IpAddress = user.IpAddress,
16+
Username = user.Username,
17+
Other = user.Others ?? EmptyDictionary
18+
};
19+
20+
public static Java.Protocol.User ToJavaUser(this User user) =>
21+
new()
22+
{
23+
Email = user.Email,
24+
Id = user.Id,
25+
IpAddress = user.IpAddress,
26+
Username = user.Username,
27+
Others = user.Other.Count == 0 ? null : user.Other
28+
};
29+
}

src/Sentry/Android/SentrySdk.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ public static IDisposable Init(AndroidContext context, SentryOptions options)
160160
options.IsGlobalModeEnabled = true;
161161
options.AddEventProcessor(new AndroidEventProcessor(androidOptions!));
162162
options.CrashedLastRun = () => Java.Sentry.IsCrashedLastRun()?.BooleanValue() is true;
163+
options.EnableScopeSync = true;
164+
options.ScopeObserver = new AndroidScopeObserver(options);
163165
// TODO: Pause/Resume
164166

165167
// Init the managed SDK

0 commit comments

Comments
 (0)