Skip to content

Commit

Permalink
Add options for PII breadcrumbs from MAUI events (#1709)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjohnsonpint authored Jun 13, 2022
1 parent 7973bac commit d29ae07
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 62 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Initial MAUI support ([#1663](https://github.com/getsentry/sentry-dotnet/pull/1663))
- Continue with adding MAUI support ([#1670](https://github.com/getsentry/sentry-dotnet/pull/1670))
- MAUI events become extra context in Sentry events ([#1706](https://github.com/getsentry/sentry-dotnet/pull/1706))
- Add options for PII breadcrumbs from MAUI events ([#1709](https://github.com/getsentry/sentry-dotnet/pull/1709))
- Added a new `net6.0-android` target for the `Sentry` core library, which bundles the [Sentry Android SDK](https://docs.sentry.io/platforms/android/):
- Initial .NET 6 Android support ([#1288](https://github.com/getsentry/sentry-dotnet/pull/1288))
- Update Android Support ([#1669](https://github.com/getsentry/sentry-dotnet/pull/1669))
Expand Down
17 changes: 10 additions & 7 deletions src/Sentry.Maui/Internal/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ namespace Sentry.Maui.Internal;
internal static class Extensions
{
public static void AddBreadcrumbForEvent(this IHub hub,
SentryMauiOptions options,
object? sender,
string eventName,
string? type,
string? category,
Action<Dictionary<string, string>>? addExtraData)
=> hub.AddBreadcrumbForEvent(sender, eventName, type, category, default, addExtraData);
=> hub.AddBreadcrumbForEvent(options, sender, eventName, type, category, default, addExtraData);

public static void AddBreadcrumbForEvent(this IHub hub,
SentryMauiOptions options,
object? sender,
string eventName,
string? type = null,
Expand All @@ -21,7 +23,7 @@ public static void AddBreadcrumbForEvent(this IHub hub,
var data = new Dictionary<string, string>();
if (sender is Element element)
{
data.AddElementInfo(element, null);
data.AddElementInfo(options, element, null);
}

addExtraData?.Invoke(data);
Expand All @@ -30,7 +32,10 @@ public static void AddBreadcrumbForEvent(this IHub hub,
hub.AddBreadcrumb(message, category, type, data, level);
}

public static void AddElementInfo(this IDictionary<string, string> data, Element? element, string? property)
public static void AddElementInfo(this IDictionary<string, string> data,
SentryMauiOptions options,
Element? element,
string? property)
{
if (element is null)
{
Expand All @@ -55,15 +60,13 @@ public static void AddElementInfo(this IDictionary<string, string> data, Element
data.Add(prefix + "Name", element.StyleId);
}

if (element is ITitledElement { Title: { } } titledElement)
if (options.IncludeTitleInBreadcrumbs && element is ITitledElement { Title: { } } titledElement)
{
// TODO: Scrub PII ?
data.Add(prefix + nameof(titledElement.Title), titledElement.Title);
}

if (element is IText { Text: { } } textElement)
if (options.IncludeTextInBreadcrumbs && element is IText { Text: { } } textElement)
{
// TODO: Scrub PII ?
data.Add(prefix + nameof(textElement.Text), textElement.Text);
}
}
Expand Down
112 changes: 58 additions & 54 deletions src/Sentry.Maui/Internal/MauiEventsBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,28 +91,28 @@ private void BindApplicationEvents(Application application)

// Navigation events
application.ModalPopping += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.ModalPopping), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.ModalPopping), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
application.ModalPopped += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.ModalPopped), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.ModalPopped), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
application.ModalPushing += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.ModalPushing), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.ModalPushing), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
application.ModalPushed += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.ModalPushed), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.ModalPushed), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
application.PageAppearing += (sender, page) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.PageAppearing), NavigationType, NavigationCategory,
data => data.AddElementInfo(page, nameof(Page)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.PageAppearing), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, page, nameof(Page)));
application.PageDisappearing += (sender, page) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.PageDisappearing), NavigationType, NavigationCategory,
data => data.AddElementInfo(page, nameof(Page)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.PageDisappearing), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, page, nameof(Page)));

// Theme changed event
// https://docs.microsoft.com/dotnet/maui/user-interface/system-theme-changes#react-to-theme-changes
application.RequestedThemeChanged += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Application.RequestedThemeChanged), SystemType, RenderingCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Application.RequestedThemeChanged), SystemType, RenderingCategory,
data => data.Add(nameof(e.RequestedTheme), e.RequestedTheme.ToString()));
}

Expand All @@ -127,7 +127,7 @@ private void BindReflectedEvents(Element element)
{
Action<object, object> handler = (sender, _) =>
{
_hub.AddBreadcrumbForEvent(sender, eventInfo.Name);
_hub.AddBreadcrumbForEvent(_options, sender, eventInfo.Name);
};

try
Expand All @@ -151,31 +151,35 @@ private void BindWindowEvents(Window window)

// Lifecycle events caused by user action
window.Activated += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Activated), SystemType, LifecycleCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Activated), SystemType, LifecycleCategory);
window.Deactivated += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Deactivated), SystemType, LifecycleCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Deactivated), SystemType, LifecycleCategory);
window.Stopped += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Stopped), SystemType, LifecycleCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Stopped), SystemType, LifecycleCategory);
window.Resumed += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Resumed), SystemType, LifecycleCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Resumed), SystemType, LifecycleCategory);

// System generated lifecycle events
window.Created += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Created), SystemType, LifecycleCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Created), SystemType, LifecycleCategory);
window.Destroying += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Destroying), SystemType, LifecycleCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Destroying), SystemType, LifecycleCategory);
window.Backgrounding += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Destroying), SystemType, LifecycleCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.Backgrounding), SystemType, LifecycleCategory,
data =>
{
// TODO: Could this contain PII?
if (!_options.IncludeBackgroundingStateInBreadcrumbs)
{
return;
}

foreach (var item in e.State)
{
data.Add($"{nameof(e.State)}.{item.Key}", item.Value ?? "<null>");
}
});
window.DisplayDensityChanged += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.Destroying), SystemType, LifecycleCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.DisplayDensityChanged), SystemType, LifecycleCategory,
data =>
{
var displayDensity = e.DisplayDensity.ToString(CultureInfo.InvariantCulture);
Expand All @@ -184,51 +188,51 @@ private void BindWindowEvents(Window window)

// Navigation events
window.ModalPopping += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ModalPopping), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ModalPopping), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
window.ModalPopped += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ModalPopped), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ModalPopped), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
window.ModalPushing += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ModalPushing), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ModalPushing), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
window.ModalPushed += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ModalPushed), NavigationType, NavigationCategory,
data => data.AddElementInfo(e.Modal, nameof(e.Modal)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ModalPushed), NavigationType, NavigationCategory,
data => data.AddElementInfo(_options, e.Modal, nameof(e.Modal)));
window.PopCanceled += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.PopCanceled), NavigationType, NavigationCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.PopCanceled), NavigationType, NavigationCategory);
}

private void BindElementEvents(Element element)
{
// Element handler events
// https://docs.microsoft.com/dotnet/maui/user-interface/handlers/customize#handler-lifecycle
element.HandlerChanging += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.HandlerChanging), SystemType, HandlersCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.HandlerChanging), SystemType, HandlersCategory,
data =>
{
data.Add(nameof(e.OldHandler), e.OldHandler?.ToString() ?? "");
data.Add(nameof(e.NewHandler), e.NewHandler?.ToString() ?? "");
});
element.HandlerChanged += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.HandlerChanged), SystemType, HandlersCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.HandlerChanged), SystemType, HandlersCategory);

// Rendering events
element.ChildAdded += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ChildAdded), SystemType, RenderingCategory,
data => data.AddElementInfo(e.Element, nameof(e.Element)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ChildAdded), SystemType, RenderingCategory,
data => data.AddElementInfo(_options, e.Element, nameof(e.Element)));
element.ChildRemoved += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ChildRemoved), SystemType, RenderingCategory,
data => data.AddElementInfo(e.Element, nameof(e.Element)));
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ChildRemoved), SystemType, RenderingCategory,
data => data.AddElementInfo(_options, e.Element, nameof(e.Element)));
element.ParentChanging += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ParentChanging), SystemType, RenderingCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ParentChanging), SystemType, RenderingCategory,
data =>
{
data.AddElementInfo(e.OldParent, nameof(e.OldParent));
data.AddElementInfo(e.NewParent, nameof(e.NewParent));
data.AddElementInfo(_options, e.OldParent, nameof(e.OldParent));
data.AddElementInfo(_options, e.NewParent, nameof(e.NewParent));
});
element.ParentChanged += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Window.ParentChanged), SystemType, RenderingCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Window.ParentChanged), SystemType, RenderingCategory);

// These lead to lots of duplicate information, so probably best not to include them.
// element.DescendantAdded
Expand All @@ -241,7 +245,7 @@ private void BindElementEvents(Element element)
if (bo.BindingContext != null)
{
// Don't add breadcrumbs when this is null
_hub.AddBreadcrumbForEvent(element, nameof(bo.BindingContextChanged), SystemType, RenderingCategory,
_hub.AddBreadcrumbForEvent(_options, element, nameof(bo.BindingContextChanged), SystemType, RenderingCategory,
data => data.Add(nameof(bo.BindingContext), bo.BindingContext.GetType().Name));
}
};
Expand All @@ -256,15 +260,15 @@ private void BindShellEvents(Shell shell)
// Navigation events
// https://docs.microsoft.com/dotnet/maui/fundamentals/shell/navigation
shell.Navigating += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Shell.Navigating), NavigationType, NavigationCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Shell.Navigating), NavigationType, NavigationCategory,
data =>
{
data.Add("from", e.Current?.Location.ToString() ?? "");
data.Add("to", e.Target?.Location.ToString() ?? "");
data.Add(nameof(e.Source), e.Source.ToString());
});
shell.Navigated += (sender, e) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Shell.Navigated), NavigationType, NavigationCategory,
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Shell.Navigated), NavigationType, NavigationCategory,
data =>
{
data.Add("from", e.Previous?.Location.ToString() ?? "");
Expand All @@ -281,32 +285,32 @@ private void BindPageEvents(Page page)
// Lifecycle events
// https://docs.microsoft.com/dotnet/maui/fundamentals/shell/lifecycle
page.Appearing += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Page.Appearing), SystemType, RenderingCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.Appearing), SystemType, RenderingCategory);
page.Disappearing += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Page.Disappearing), SystemType, RenderingCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.Disappearing), SystemType, RenderingCategory);

// Navigation events
// https://github.com/dotnet/docs-maui/issues/583
page.NavigatingFrom += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Page.NavigatingFrom), NavigationType, NavigationCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.NavigatingFrom), NavigationType, NavigationCategory);
page.NavigatedFrom += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Page.NavigatedFrom), NavigationType, NavigationCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.NavigatedFrom), NavigationType, NavigationCategory);
page.NavigatedTo += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Page.NavigatedTo), NavigationType, NavigationCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.NavigatedTo), NavigationType, NavigationCategory);

// Layout changed event
// https://docs.microsoft.com/dotnet/api/xamarin.forms.ilayout.layoutchanged
page.LayoutChanged += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Page.LayoutChanged), SystemType, RenderingCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.LayoutChanged), SystemType, RenderingCategory);
}

private void BindButtonEvents(Button button)
{
button.Clicked += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Button.Clicked), UserType, UserActionCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Button.Clicked), UserType, UserActionCategory);
button.Pressed += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Button.Pressed), UserType,UserActionCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Button.Pressed), UserType,UserActionCategory);
button.Released += (sender, _) =>
_hub.AddBreadcrumbForEvent(sender, nameof(Button.Released), UserType,UserActionCategory);
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Button.Released), UserType,UserActionCategory);
}
}
Loading

0 comments on commit d29ae07

Please sign in to comment.