Instrument mobile apps with Dynatrace .NET MAUI NuGet package
Dynatrace version 1.265+
The Dynatrace .NET MAUI NuGet package helps auto-instrument your .NET MAUI mobile application with OneAgent for Android and iOS as well as provides an API for manual instrumentation.
The Dynatrace .NET MAUI NuGet package is available for Android and iOS. You cannot use our package for macOS and Windows.
Supported features
Auto-instrumentation
- User actions
- Lifecycle events
- Web requests
- Crashes
Manual instrumentation
- Custom actions
- Web requests
- Values
- Events
- Errors
- Crashes
- User tagging
Requirements
- For Android: Android version 5.0+ (API 21+)
- For iOS: iOS version 11+
Set up the package
Perform the following steps to set up the Dynatrace .NET MAUI NuGet package for your mobile application.
Install the Dynatrace .NET MAUI NuGet package
Create an application and get the config file
Add the config file to your project
Add the OneAgent start method
Enable automatic web request instrumentation
Install the NuGet package
Add the Dynatrace .NET MAUI NuGet package to your application.
- In Visual Studio, right-click the solution of your mobile application and select Manage NuGet packages.
- Find Dynatrace.OneAgent.MAUI from nuget.org, and select Add Package.
- Select the checkboxes of all the projects to which you want to add the NuGet package.
- Select OK.
Create an application and get the config file
Create a new mobile application in the Dynatrace web UI, and download the configuration file.
- In the Dynatrace menu, go to Deploy Dynatrace.
- Scroll down to the Mobile app monitoring section and select Set up mobile monitoring.
- Enter a name for your application and select Create mobile app. The application settings page opens.
- From the mobile application settings, go to Instrumentation wizard, and select .NET MAUI.
- Under step 2, select Download dynatrace.config.json to get the configuration file.
Add the config file to your project
Add the dynatrace.config.json
file, which you downloaded in the previous step, to your project.
Add the dynatrace.config.json
file to the Platforms/Android/Assets
directory of your project.
If you cannot find the Assets
directory, create it inside the Platforms/Android
directory.
Add the dynatrace.config.json
file to the Platforms/iOS/Resources
directory of your project.
Before each build, our package automatically creates a new Dynatrace.plist
file based on the options set in your configuration file.
If you cannot find the Resources
directory, create it inside the Platforms/iOS
directory.
Add the OneAgent start method
The start method is required for OneAgent to start.
using Dynatrace.MAUI;
Agent.Instance.Start();
using Dynatrace.MAUI;
Agent.Instance.Start();
Enable automatic web request instrumentation optional
You can optionally use the following method to enable the auto-instrumentation of web requests. The HttpMessageHandler
used by HttpClient
takes care of the manual web request instrumentation.
using Dynatrace.MAUI;
var httpHandler = Agent.Instance.GetHttpMessageHandler();
var httpClient = new HttpClient(httpHandler);
Moreover, you can also have your own HTTP handler:
using Dynatrace.MAUI;
var defaultHttpHandler = new HttpClientHandler();
var httpHandler = Agent.Instance.GetHttpMessageHandler(defaultHttpHandler);
var httpClient = new HttpClient(httpHandler);
Manual instrumentation
The sections below describe how to start OneAgent manually, create custom actions, instrument web requests, and report values, events, and crashes.
Start OneAgent
You can use the manual startup with a configuration builder (Android) or a configuration dictionary (iOS).
-
Modify the
dynatrace.config.json
file to disable OneAgent autostart.{ "android": { "autoStart": { "enabled": false } } }
{ "ios": { "DTXAutoStart": false } }
Don't add additional properties to the configuration file. If you do that, the build fails with an exception.
-
Start OneAgent manually and pass the required properties.
using Dynatrace.MAUI; Agent.Instance.Start(new ConfigurationBuilder("<insertBeaconURL>","<insertApplicationID>") .BuildConfiguration());
using Dynatrace.MAUI; var configDict = new Dictionary<string, object>(); configDict.Add("DTXApplicationID", "<insertApplicationID>"); configDict.Add("DTXBeaconURL", "<insertBeaconURL"); Agent.Instance.Start(configDict);
Create custom actions
You can create custom actions and enhance them with additional information such as values, events, and errors.
Call EnterAction
to start a custom action and LeaveAction
to close a custom action. Timing is measured automatically.
using Dynatrace.MAUI;
IRootAction myAction = Agent.Instance.EnterAction("Tap on Confirm");
//Perform the action and whatever else is needed.
myAction.LeaveAction();
For a mobile custom action or a mobile autogenerated user action, the maximum name length is 250 characters.
Create child actions
Besides generating standalone custom actions, you can also create child actions.
Child actions are similar to parent custom actions. When a parent action is closed, all child actions of the parent action are automatically closed.
using Dynatrace.MAUI;
IRootAction myAction = Agent.Instance.EnterAction("Tap on Confirm");
IAction mySubAction = myAction.EnterAction("Tap on Confirm again");
//Perform the action and whatever else is needed.
mySubAction.LeaveAction();
myAction.LeaveAction();
For a mobile custom action or a mobile autogenerated user action, the maximum name length is 250 characters.
Cancel custom actions
If you need to cancel an already created but not yet closed custom action, call Cancel
. Canceling an action discards all data associated with it: all reported values, events, and errors are discarded; all child actions are canceled.
using Dynatrace.MAUI;
IRootAction myAction = Agent.Instance.EnterAction("Tap on Confirm");
// Action is canceled
myAction.Cancel();
You can't cancel a closed action, so calling Cancel
after LeaveAction
is impossible for the same action. The same goes for closing a canceled action: you can't call LeaveAction
after using Cancel
for the same action.
Instrument web requests
Use the following code snippet to instrument web requests:
using Dynatrace.MAUI;
// Create an action
IRootAction webAction = Agent.Instance.EnterAction(actionName: "WebRequest Action");
// Generate a new unique tag associated with the web request action
string requestTag = webAction.GetRequestTag(url);
string requestTagHeader = webAction.GetRequestTagHeader();
// Place the Dynatrace HTTP header on your web request
httpClient.DefaultRequestHeaders.Add(requestTagHeader, requestTag);
// Generate a WebRequestTiming object based on the unique tag
IWebRequestTiming timing = Agent.Instance.GetWebRequestTiming(requestTag, url);
// Start web request timing before the HTTP request is sent
timing.StartWebRequestTiming();
try
{
var response = await httpClient.GetAsync(url);
// Stop web request timing when the HTTP response is received and the response body is obtained
timing.StopWebRequestTiming(url, (int)response.StatusCode, response.ReasonPhrase);
}
catch (HttpRequestException exception)
{
// Stop web request timing when a connection exception occurs
timing.StopWebRequestTiming(url, -1, exception.ToString());
}
finally
{
// Leave an action
webAction.LeaveAction();
}
Report a value
The ReportValue
method allows you to report your own metrics. These metrics must be part of a user action. You can report int
, double
, and string
values.
ReportValue(valueName: string, value: int);
ReportValue(valueName: string, value: double);
ReportValue(valueName: string, value: string);
For instance, to report a string
value within the Tap on Confirm
action, use the following code:
using Dynatrace.MAUI;
IRootAction myAction = Agent.Instance.EnterAction("Tap on Confirm");
myAction.ReportValue("Customer type", "Gold");
myAction.LeaveAction();
Report an event
For any open action, you can report an event. Use the following API call:
ReportEvent(eventName: string);
If you want to report standalone events with lots of additional information, see Report a business event.
Report an error
To report an error, use the ReportError
method:
ReportError(errorName: string, errorCode: number);
Report an error stack trace
To report an error stack trace, use the following API call:
using Dynatrace.MAUI;
Agent.Instance.ReportErrorStacktrace("Error_Class", "Error_Value", "Error_Reason", "Error_Stacktrace");
Report a crash
To report a crash, use the following API call:
using Dynatrace.MAUI;
Agent.Instance.ReportCrash("CrashWithoutException", "Crash_Reason", "Crash_Stacktrace");
You can also use an exception object:
using Dynatrace.MAUI;
Agent.Instance.ReportCrashWithException("CrashWithExceptionObj", exception);
Reporting a crash forces a user session to be completed. Any subsequent actions are included in a new user session.
Android only When you use automated crash reporting, Visual Studio might catch the exception before OneAgent. If you notice that Dynatrace doesn't report crashes to your environment, make sure that you're not using the debug option in Visual Studio. Otherwise, the debugger catches the crash and nothing is reported to your Dynatrace environment.
Report a business event
With sendBizEvent
, you can report business events. These are standalone events, as Dynatrace sends them separately from user actions or user sessions.
For more information on business events, see Business Analytics in Dynatrace.
using Dynatrace.MAUI;
var attributes = new Dictionary<string, JsonValue>();
attributes.Add("event.name", "Confirmed Booking");
attributes.Add("screen", "booking-confirmation");
attributes.Add("product", "Danube Anna Hotel");
attributes.Add("amount", 358.35);
attributes.Add("currency", "USD");
attributes.Add("reviewScore", 4.8);
attributes.Add("arrivalDate", "2022-11-05");
attributes.Add("departureDate", "2022-11-15");
attributes.Add("journeyDuration", 10);
attributes.Add("adultTravelers", 2);
attributes.Add("childrenTravelers", 0);
Agent.Instance.SendBizEvent("com.easytravel.funnel.booking-finished", attributes);
Tag specific users
You can tag each user of your mobile application with a unique user name. This enables you to search and filter specific user sessions and analyze individual user behavior over time.
Make the following API call to tag the current session with a particular name:
using Dynatrace.MAUI;
Agent.Instance.IdentifyUser("John Smith");
OneAgent for Android version 237+ OneAgent for iOS version 235+ Sessions split due to idle or duration timeout are re-tagged automatically.
When OneAgent ends a tagged session because the session duration has reached its set limit or due to the user's inactivity, the subsequent session is re-tagged automatically. You don't need to provide the user identification information again.
However, note that OneAgent does not re-tag the subsequent session in the following cases:
- When you explicitly end a tagged user session via
endVisit
- When the user or the mobile operating system closes or force stops the app
- When OneAgent ends the current user session and generates a new session after the privacy settings have been changed
See User sessions > Session end to learn when OneAgent ends a mobile user session.
End a session
You can force a session to end via the API call. This also closes all open actions and starts a new session.
using Dynatrace.MAUI;
Agent.Instance.EndVisit();
Configure data privacy
With the user opt-in mode for mobile applications, you can dynamically adjust data privacy settings and build your applications in compliance with data protection laws and regulations.
Enable user opt-in mode
To activate the user opt-in mode, set the userOptIn
property (Android) or DTXUserOptIn
configuration key (iOS) to true
in the dynatrace.config.json
file. After enabling the user opt-in mode, you should also specify the privacy setting.
Retrieve data privacy settings
To get the current UserPrivacyOptions
configuration, use the following API call:
using Dynatrace.MAUI;
// Get the UserPrivacyOptions object
UserPrivacyOptions currentOptions = Agent.Instance.GetUserPrivacyOptions();
// Get the individual settings for DataCollectionLevel and crash reporting
bool crashOptedIn = Agent.Instance.GetUserPrivacyOptions().CrashReportingOptedIn;
DataCollectionLevel dataCollectionLevel = Agent.Instance.GetUserPrivacyOptions().DataCollectionLevel;
Change data privacy settings
To set new options on a UserPrivacyOptions
object, use the following code:
using Dynatrace.MAUI;
// Creating a new UserPrivacyOptions object requires setting the two parameters of DataCollectionLevel and crash reporting
UserPrivacyOptions options = new UserPrivacyOptions(DataCollectionLevel.Performance, false);
// Update the options with the setter
options.DataCollectionLevel = DataCollectionLevel.UserBehavior;
options.CrashReportingOptedIn = true;
// Get the values of the configuration with the getter
options.DataCollectionLevel;
options.CrashReportingOptedIn;
// Get the UserPrivacyOptions object
UserPrivacyOptions currentOptions = Agent.Instance.GetUserPrivacyOptions();
To apply the new UserPrivacyOptions
configuration, use this code:
using Dynatrace.MAUI;
UserPrivacyOptions options = new UserPrivacyOptions(DataCollectionLevel.UserBehavior, true);
Agent.Instance.ApplyUserPrivacyOptions(options);
Data collection levels
The table below describes the available data collection levels and shows whether user tags and custom user actions, events, values, and errors are reported for a particular level.
Level | Description | User tags, custom events, and custom values | Custom user actions and errors |
---|---|---|---|
Off Monitoring data is not sent | No personal data is sent; all identifiers are randomized on every launch.1 | ||
Performance Only performance, automatically captured data is sent | No personal data is sent; all identifiers are randomized on every launch. | ||
User behavior Performance data and user data is sent | Personal data is sent; OneAgent recognizes and reports users who revisit in the future.2 |
A single Loading <App>
event is sent to track the number of users that opted out.
If you haven't configured user tagging and custom event or value reporting, the User behavior level works similarly to the Performance level.
The possible values for the data collection levels are as follows:
Off
Performance
UserBehavior
Report GPS location
You can report the latitude and longitude.
SetGPSLocation(latitude: double, longitude: double);
Configuration file
The dynatrace.config.json
configuration file contains your application ID, beacon URL, and some other settings.
- You can download this file from the Dynatrace web UI or create it manually.
- If you don't add a configuration file with at least the beacon URL and the application ID properties, the build fails. Alternatively, use the manual startup with a configuration builder (Android) or a configuration dictionary (iOS).
- When you use a specific build configuration—for example,
Debug
,Release
, or a custom-defined configuration—our package searches theAssets
(Android) orResources
(iOS) directory for a configuration file nameddynatrace<Configuration>.config.json
. For example, if you're using theDebug
build configuration, our package looks for a file nameddynatraceDebug.config.json
. If the package can't find the configuration-specific file, it uses the defaultdynatrace.config.json
file.
The following is the dynatrace.config.json
file structure for Android and iOS.
{
"android": {
"autoStart": {
"applicationId": "<insertApplicationID>",
"beaconUrl": "<insertBeaconURL>"
},
"userOptIn": true,
"agentBehavior": {
"startupLoadBalancing": true
}
}
}
{
"ios": {
"DTXApplicationId": "<insertApplicationID>",
"DTXBeaconUrl": "<insertBeaconURL>",
"DTXUserOptIn": true,
"DTXStartupLoadBalancing": true
}
}
Never use dot notation for the configuration file. Always write in full bracket style.
Enable OneAgent debug logs
If the instrumentation runs through and your application starts, but you see no data in your Dynatrace environment, you probably need to dig deeper to find out why OneAgents aren't sending any data. Opening up a support ticket is a great idea but gathering logs first is even better.
Update your dynatrace.config.json
file to enable OneAgent debug logs.
{
"android": {
"autoStart": {
"applicationId": "<insertApplicationID>",
"beaconUrl": "<insertBeaconURL>"
},
"userOptIn": true,
"debug": {
"agentLogging": true
}
}
}
Add the following configuration snippet to the dynatrace.config.json
file:
{
"ios": {
"DTXApplicationId": "<insertApplicationID>",
"DTXBeaconUrl": "<insertBeaconURL>",
"DTXUserOptIn": true,
"DTXLogLevel": "ALL"
}
}
Enable build debug logs for Android
Android only
If the Android instrumentation fails, you most likely need to open a support ticket and provide build debug logs. To provide those logs, you need to set the DynatraceInstrumentationLogging
property and change the build log level to Diagnostic
.
-
Set the
DynatraceInstrumentationLogging
property. Choose one of the following options to do that:- Create
Directory.Build.props
in the Android project directory:
<Project> <PropertyGroup> <DynatraceInstrumentationLogging>true</DynatraceInstrumentationLogging> </PropertyGroup> </Project>
- Add the
DynatraceInstrumentationLogging
property to the.csproj
file of your project. Insert it into some existingPropertyGroup
, depending on the configuration that you're executing.
- Create
-
Change the build output verbosity to
Diagnostic
. For details, see the Microsoft documentation on how to change the amount of information included in the build log. -
Rebuild your project.
-
Attach the build logs to the support ticket so that we can further analyze your issue.
Enable instant crash reporting for iOS
iOS only
By default, our package captures the C# stack trace when a crash happens on the C# layer, or it captures the native iOS crash report when a crash happens on the native layer. The package sends out the C# stack trace or the native iOS crash report on the next app launch.
To change the default behavior and allow our package to send native formatted crash reports instantly, enable instant crash reporting using one of the following:
dynatrace.config.json
configuration file. See Configuration file for more details on this file.- Configuration builder
- Configuration dictionary
{
"ios": {
"DTXApplicationId": "<insertApplicationID>",
"DTXBeaconUrl": "<insertBeaconURL>",
"DTXCrashReportingEnabled": true,
"DTXInstantCrashReportingEnabled": true
}
}
using Dynatrace.MAUI;
Agent.Instance.Start(new ConfigurationBuilder("<insertBeaconURL>","<insertApplicationID>")
.WithCertificateValidation(true)
.WithCrashReporting(true)
.WithInstantCrashReporting(true)
.WithUserOptIn(true)
.BuildConfiguration());
using Dynatrace.MAUI;
var configDict = new Dictionary<string, object>();
configDict.Add("DTXApplicationID", "<insertApplicationID>");
configDict.Add("DTXBeaconURL", "<insertBeaconURL>");
configDict.Add("DTXCrashReportingEnabled", true);
configDict.Add("DTXInstantCrashReportingEnabled", true);
Agent.Instance.Start(configDict);
After you enable instant crash reporting, you get crash reports in the format of a native crash report, not a stack trace like you would for a standard unhandled exception triggered on the C# layer.
Troubleshooting
If you can't resolve a problem, please contact Dynatrace ONE via an in-product chat. Have the following details available:
- OneAgent debug logs
- Your
dynatrace.config.json
file
Failed build
If your build fails, make sure you've added the dynatrace.config.json
file to the Assets
(Android) or Resources
(iOS) directory and that the file includes at least the beacon URL and the application ID properties. For details, see Configuration file.
If you use the manual startup, don't include the beacon URL and the application ID properties in the configuration file. If you do that, you encounter an exception.
Turn off Visual Studio Debugger for Android
Android only
If you notice that Dynatrace doesn't report crashes for Android applications to your environment, make sure that you're not using the debug option in Visual Studio.
-
Right-click your Android project, and select Properties.
-
Go to Android Options, and clear Enable developer instrumentation (debugging and profiling).
Keep in mind that clearing Enable developer instrumentation disables debugging. Use this option only to verify that crashes are sent. Optionally, you can create a release build that is detached from Visual Studio.