MAUI

Installation

The best way to install Raygun is to use the NuGet package manager. Right-click on your project and select "Manage NuGet Packages....". Navigate to the Browse tab, then use the search box to find Raygun4Maui and install it.

To install the latest version:

dotnet add package Raygun4Maui

Alternatively, you can specify a version tag to install a specific version of the package. See Raygun4Maui NuGet Gallery page for information on available versions.

dotnet add package Raygun4Maui --version 2.0.1

Import the module by:

using Raygun4Maui;

To add the ability to send crash reports to Raygun, you need to initialize the client during the builder stage. Open your main MauiProgram class (MauiProgram.cs) and change the CreateMauiApp method by adding the AddRaygun extension method:

var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    ...
    .AddRaygun();

The default method uses the configuration service to pull in your configuration and create the Raygun client.

We provide three ways to set up Raygun4Maui. We recommend using Lambda options for their simplicity and flexibility, but we also offer configuration via appsettings.json and a Raygun4MauiSettings overload. Choose the method that best fits your application's setup process.

We provide Lambda options that you can use to make in-code changes to the configuration, e.g.

.AddRaygun(options => {
    options.RaygunSettings.ApiKey = "paste_your_api_key_here";
    options.EnableRealUserMonitoring = true;
    options.RumFeatureFlags = RumFeatures.Page | RumFeatures.Network | RumFeatures.AppleNativeTimings;
})

For enabling Real User Monitoring, set EnableRealUserMonitoring to true and list the RumFeatureFlags you would like to be enabled.

Configuration settings can be added via an appsettings.json file. To add appsettings.json to the bundled app, you should add it as an embedded resource (consult IDE specific instructions). If you do not provide one, we create a default Raygun4MauiSettings object which you can change using the previously mentioned lambda options. This must be added to the configuration before you call the .AddRaygun() method.

 var a = Assembly.GetExecutingAssembly();
 using var stream = a.GetManifestResourceStream("Raygun4Maui.SampleApp.appsettings.json");
        
 builder.Configuration.AddJsonStream(stream!);

Below is an example appsettings.json file. You need to use Raygun4MauiSettings for the root as the configuration will not pull it in otherwise. Additionally, the RumFeatureFlags are comma-separated so that they can be loaded in correctly as a bitwise feature flag.

{
  "Raygun4MauiSettings": {
    "RaygunSettings": {
      "ApiKey": "paste_your_api_key_here",
      "ApplicationVersion": "1.0.0"
    },
    "IgnoredViews": [
      "LoginView",
      "SettingsView"
    ],
    "IgnoredUrls": [
      "https://example.com/ignore"
    ],
    "EnableRealUserMonitoring": true,
    "RumFeatureFlags": "Network, Page, AppleNativeTimings"
  }
}

The AddRaygun extension method contains an overloaded method that takes a Raygun4MauiSettings options object which can be used instead of the configuration service. This contains RaygunSettings from Raygun4Net.

Raygun4MauiSettings supports the following configurations:

  • RaygunSettings
    • Any configuration available in the Raygun4Net RaygunSettings, such as ApiKey.
  • RaygunLoggerConfiguration
    • SendDefaultTags (defaulted to true) adds the Log Level (e.g., Severe, Warning, etc.) and the Build Platform (e.g., Windows, Android, iOS, etc.) to reports and logs sent to Raygun.
    • SendDefaultCustomData (defaulted to true) adds all available information in the uncaught exception as custom data on the crash report sent to Raygun.
    • MinLogLevel and MaxLogLevel specify the range of logging levels to be sent to Raygun.
  • IgnoredViews a list of views to ignore when tracking.
  • IgnoredUrls a list of URLs to ignore when tracking.
  • RumApiEndpoint endpoint to where the RUM data is sent.
  • EnableRealUserMonitoring to enable RUM.
  • RumFeatureFlags an enum flag to enable specific Real User Monitoring features, (e.g. RumFeatures.Page | RumFeatures.Network).

To use these additional configurations, create and initialize a new Raygun4MauiSettings object as follows:

Raygun4MauiSettings raygunMauiSettings = new Raygun4MauiSettings {
    RaygunSettings = new RaygunSettings() {
        ApiKey = "paste_your_api_key_here"
    },
    EnableRealUserMonitoring = true, // defaults to false
    RumFeatureFlags = RumFeatures.Page | RumFeatures.Network | RumFeatures.AppleNativeTimings // Enables Page, Network, and Native Apple Timings
};

The Raygun4MauiSettings are added to the service provider so that any DI dependent service can pull in the Raygun4MauiSettings and make changes. For example, the application version may be obtained from an endpoint, so this can be assigned later rather than at app startup.


We have an interface of IRaygunUserProvider. This offers a GetUser function that our Crash Reporting product can use to get the current user. Only having GetUser makes sense for the .NET provider, but since MAUI supports Real User Monitoring we need a way of notifying the Real User Monitoring implementation that a user has changed.

We therefore, provide an IRaygunMauiUserProvider interface which adds a SetUser method. With this we can notify the Real User Monitoring module. There is a default implementation of this class for this provider which takes in a user with SetUser and provides this user through GetUser.

You can obtain an instance of this provider through dependency injection using IRaygunMauiUserProvider, then you can set the user by calling SetUser.

public MainPage(IRaygunMauiUserProvider userProvider) {
    userProivder.SetUser(new RaygunIdentifierMessage("anonymous");    
}

You can implement your own custom user provider if the default does not fit your needs. This can be done by implementing the IRaygunMauiUserProvider, specifically GetUser and SetUser.

Please note, if you create a custom implementation you must send a user changed event to the RaygunAppEventPublisher for our Real User Monitoring module to be notified.

RaygunAppEventPublisher.Publish(new RaygunUserChanged
{
    User = _user
});

As mentioned, we obtain this user provider by using dependency injection, so to add your custom instance of the user provider to the DI container we provide an extension on the app builder.

builder.AddRaygunUserProvider<CustomRaygunMauiUserProvider>();

You can enable page timings by supplying the RumFeatureFlags.Page in the Raygun4MauiSettings object when you start your application.

We also offer Apple native view timings which report timings based on the events of what the UIViewController sees.

note: Apple native view timings can be out of order and multiple views can be loading at the same time. This may result in a session that is not easily interpreted.

You can add pages to be ignored from these page timings by adding them to the IgnoredViews list in the Raygun4MauiSettings object. This will ignore any page timing that contains any of the supplied pages in the ignore list.

Normal page timings are calculated through the time between OnDissapearing and OnAppearing hooks. If your navigation does not trigger these, you can manually send these timings. The time supplied for the view timings is in milliseconds.

RaygunRum.SendTimingEvent(RaygunRumEventTimingType.ViewLoaded, "View Name", 200);

You can enable page timings by supplying the RumFeatureFlags.Network in the Raygun4MauiSettings object when you start your application.

This feature calculates the time taken for every outgoing network request. There are some platform-specific limitations mainly regarding Android and the Xamarin.Android implementation of the HttpClient.

You can add pages to be ignored from these page timings by adding them to the IgnoredUrls list in the Raygun4MauiSettings object. This will ignore any network timing that contains any of the supplied URLs in the ignore list.

You can send manual network timings in the same way as view timings. Again, the time is in milliseconds. You should put the type of request e.g. GET, POST, PUT in front of the URL.

RaygunRum.SendTimingEvent(RaygunRumEventTimingType.Network, "GET https://raygun.com/", 153);

Custom timings is also available. You can either provide the RaygunRumEventTimingType.CustomTiming or the previously mentioned Network or Page timings.

RaygunRum.SendCustomTimingEvent(RaygunRumEventTimingType.CustomTiming, "Custom", 200);

In Real User Monitoring, there is platform-specific information. Similar to the Crash Reporting feature. This concerns the support for automatic network timings.

Platform Networking support Conditions
Mac Yes HttpClient, NSURLSession, and NSURLConnection
iOS Yes HttpClient, NSURLSession, and NSURLConnection
Windows Yes HttpClient
Android Yes HttpURLConnection (see SampleApp)

.NET MAUI Blazor Hybrid Apps are special in the sense that they contain a combination of both the .NET runtime and the JavaScript runtime. This creates difficulties with integrating Real User Monitoring due to multiple runtimes, though our provider should still function as expected as plain MAUI apps in this regard.

If you notice any irregularities, you could also try to use our Raygun4Js provider to get Real User Monitoring information by following the JavaScript setup in our Blazor documentation


The provider is open source and available at the Raygun4Maui repository.