MAUI
Raygun4Maui will get you set up with Raygun Crash Reporting for your .NET MAUI application in no time.
Installation
Step 1 - Install Raygun4Maui
NuGet Package manager
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.
.NET Cli
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.0
Step 2 - Add Raygun4Maui to your MauiApp builder
Import the module by:
using Raygun4Maui;
To activate sending of unhandled exceptions and logs to Raygun, you must add Raygun4Maui to your MauiApp builder. To do so, 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
Configuration
Appsettings
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 a Lambda to change the 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 seperated 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"
},
"RaygunLoggerConfiguration": {
"SendDefaultTags": true,
"SendDefaultCustomData": true,
"MinLogLevel": "Debug",
"MaxLogLevel": "Critical"
},
"IgnoredViews": [
"LoginView",
"SettingsView"
],
"IgnoredUrls": [
"https://example.com/ignore"
],
"EnableRealUserMonitoring": true,
"RumFeatureFlags": "Network, Page, AppleNativeTimings"
}
}
Lambda Options
As mentioned previously, 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;
})
Raygun4MauiSettings overload
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 a RaygunSettings
from Raygun4Net.
Raygun4MauiSettings supports the following configurations:
- RaygunSettings
- Any configuration available in the Raygun4Net
RaygunSettings
, such asApiKey
.
- Any configuration available in the Raygun4Net
- RaygunLoggerConfiguration
SendDefaultTags
(defaulted totrue
) 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 totrue
) adds all available information in the uncaught exception as custom data on the crash report sent to Raygun.MinLogLevel
andMaxLogLevel
that specify the range of logging levels to be sent to Raygun.
IgnoredViews
a list of views to ignore when trackingIgnoredUrls
a list of URLs to ignore when trackingRumApiEndpoint
endpoint to where the Real User Monitoring data is sentEnableRealUserMonitoring
to enable Real User MonitoringRumFeatureFlags
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",
},
RaygunLoggerConfiguration = new RaygunLoggerConfiguration {
SendDefaultTags = true, // defaults to true
SendDefaultCustomData = true, // defaults to true
MinLogLevel = LogLevel.Debug, // defaults to Debug
MaxLogLevel = LogLevel.Critical // defaults to Critical
}
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 instantly.
Usage
Unhandled exceptions will be sent to Raygun automatically.
Raygun4Maui stores an instance of a RaygunMauiClient
object that is initialized by the Maui builder, this can be accessed through the following code:
RaygunMauiClient.Current
This client extends the Raygun4Net.NetCore RaygunClient
, as a result any features supported by the Raygun4Net.NetCore Client are supported here.
Manually sending exceptions
Raygun4Maui automatically sends unhandled exceptions. For manual sending, use Send
or SendInBackground
methods, as shown below:
try {
// Code that may fail
} catch (Exception e) {
RaygunMauiClient.Current.SendInBackground(e);
//or
RaygunMauiClient.Current.Send(e);
}
An exception needs to be thrown in order for its stack trace to be populated. If the exception is created manually no stack trace data is collected.
Other examples
For additional examples on how to use the RaygunMauiClient
object refer to the Raygun4Net.NetCore documentation
ILogger logging
Raygun4Maui will automatically send any logger logs to Raygun.
To make a log entry, obtain the reference to the ILogger services that your MAUI app maintains:
ILogger logger = Handler.MauiContext.Services.GetService<ILogger<MainPage>>();
You may now use the appropriate ILogger log method from the logger object. This uses the same RaygunMauiClient
object accessible from RaygunMauiClient.Current
logger.LogInformation("Raygun4Maui.SampleApp.TestLoggerErrorsSent: {MethodName} @ {Timestamp}", "TestLogInformation", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"));
logger.LogCritical("Raygun4Maui.SampleApp.TestLoggerErrorsSent: {MethodName} @ {Timestamp}", "TestLogCritical", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"));
This functionality also allows you to manually catch and log exceptions as shown below:
try {
// Code that throws exception
} catch (Exception e) {
// Example ILogger call. You can use the ILogger method and arguments of your choice.
logger.Log(LogLevel.Error, e, "Exception caught at {Timestamp}", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"));
}
Customers
User information enables the Raygun dashboard to track unique users impacted by each error or crash and for real user monitoring. While you can input any useful data, remember to respect your company's privacy policies. At minimum, input a unique GUID for user impact visibility per error. A database ID, if available, could help in resolving issues. Providing names and contact details allows for direct communication about issue resolution.
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>();
note:
The IRaygunUserProvider was introduced in Raygun4Net v10.0.0. The previous User
and UserInfo
properties are marked as obsolete and are not supported in the MAUI provider.
Here are all the available RaygunIdentifierMessage properties:
- Identifier (passed into the constructor) is the unique identifier from your system for this user.
- IsAnonymous is a flag indicating whether the user is logged in (or identifiable) or if they are anonymous. An anonymous user can still have a unique identifier.
- Email The user's email address. If you use email addresses to identify your users, feel free to set the identifier to their email and leave this blank. We will use the identifier as the email address if it looks like one, and if no email address is specified in this field.
- FullName The user's full name.
- FirstName The user's first (or preferred) name.
- UUID A device identifier. Could be used to identify users across devices, or machines that are breaking for many users.
note:
The string properties on a User
have a maximum length of 255 characters. Users that have fields that exceed this amount will not be processed.
Environment Variables
We support the inclusion of environment variables such as PATH
which will be displayed under the "Environment" tab of your crash report. In RaygunSettings
provide a list of strings that will match the keys you would like to record from the environment variables. These queries are case-insensitive, so if you query for PATH
we can still obtain Path
for you.
This works on Windows, MacCatalyst, iOS and Android. However, the range of environment variables on iOS and Android may vary depending on whether you are running on a simulated device or a real device.
For usage information see the .NET 6+ documentation.
Platform specific information
Raygun4Maui will automatically collect information specific to the environment the application is being run in. However, there are inconsistencies between certain values across platforms.
- On iOS, Raygun4Maui cannot obtain the device's name. This is a privacy restriction put in place by Apple. If you would like this information to be collected and sent with crash reports you will have to request for permission from apple.
- The
Total physical memory
andAvailable physical memory
properties mean different things across platforms. Below is a table explaining the differences for each platform.
Platform | Total physical memory | Available physical memory |
---|---|---|
Mac | Total installed ram | Total memory available for user-level processes |
iOS | Total installed ram | Total memory available for user-level processes |
Windows | Total installed ram | Total amount of private memory used by the process at the time of the measurement. For a number of reasons this might not be the actual total memory usage |
Android | Total amount of memory that the JVM has allocated for the application | Total amount of free memory that the JVM has available for the application to use |
The provider is open source and available at the Raygun4Maui repository.