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 12+

Set up the package

Perform the following steps to set up the Dynatrace .NET MAUI NuGet package for your mobile application.

Step 1 Install the NuGet package

Add the Dynatrace .NET MAUI NuGet package to your application.

  1. In Visual Studio, right-click the solution of your mobile application and select Manage NuGet packages.
  2. Find Dynatrace.OneAgent.MAUI from nuget.org and select Add Package.
  3. Select the checkboxes of all the projects to which you want to add the NuGet package. Make sure you're adding the package to your native projects, as the target files within our package interact with the build.
  4. Select OK.

Step 2 Create an application and get the config file

Create a new mobile application in Dynatrace and download the configuration file.

  1. In Dynatrace, go to Mobile.
  2. Select Create mobile app.
  3. Enter a name for your application and select Create mobile app. The application settings page opens.
  4. From the application settings, select Instrumentation wizard > .NET MAUI.
  5. Under step 2, select Download dynatrace.config.json to get the configuration file.

Step 3 Add the config file to your project

Add the dynatrace.config.json file, which you downloaded in the previous step, to your project.

Step 4 Add the OneAgent start method

The start method is required for OneAgent to start.

Step 5 optional 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).

  1. Modify the dynatrace.config.json file to disable OneAgent autostart.

    Don't add additional properties to the configuration file. If you do that, the build fails with an exception.

  2. Start OneAgent manually and pass the required properties.

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.

Check the following links for information on user action naming: Android and iOS.

When the user opt-in mode is enabled for your application, it might affect user tagging and reporting of custom events, user actions, values, and errors. The exact data types not reported to Dynatrace depend on the data collection level set by a particular user. For details, refer to Data collection levels.

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.

There's no limit on the number of child actions attached to a custom action. However, note that you can have only one level of child actions—you can't create a child action for another child action (child actions can't have their own child actions). Also, refer to User session structure for individual user.

Child actions are not displayed on the user session details page, but you can view them on the waterfall analysis page for a custom action to which these child actions are attached.

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 key-value pairs of metadata that you can later view in the Dynatrace web UI and convert into user action and user session properties. The reported values must be part of a user action.

You can report values of the following data types:

  • int
  • double
  • string
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();

To view the reported values in the Dynatrace web UI, go to the details of the user action that should contain that metadata and scroll down to the Reported values section.

User action details page with SDK-reported values

To add action and session properties based on the reported values and then use these properties to create powerful queries, segmentations, and aggregations, see Define user action and user session properties for mobile applications.

When the user opt-in mode is enabled for your application, it might affect user tagging and reporting of custom events, user actions, values, and errors. The exact data types not reported to Dynatrace depend on the data collection level set by a particular user. For details, refer to Data collection levels.

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.

When the user opt-in mode is enabled for your application, it might affect user tagging and reporting of custom events, user actions, values, and errors. The exact data types not reported to Dynatrace depend on the data collection level set by a particular user. For details, refer to Data collection levels.

Report an error

To report an error, use the ReportError method.

ReportError(errorName: string, errorCode: number);

When the user opt-in mode is enabled for your application, it might affect user tagging and reporting of custom events, user actions, values, and errors. The exact data types not reported to Dynatrace depend on the data collection level set by a particular user. For details, refer to Data collection levels.

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);

The time when the crash details are sent to Dynatrace depends on your mobile application operating system.

  • Android

    In general, the crash details are sent immediately after the crash, so the user doesn’t have to relaunch the application. However, in some cases, the application should be reopened within 10 minutes so that the crash report is sent. Note that Dynatrace doesn't send crash reports that are older than 10 minutes (as such reports can no longer be correlated on the Dynatrace Cluster).

  • iOS

    The crash details are sent only when the user reopens the mobile application (so on the next application launch). However, if the user doesn't open the application within 10 minutes, the crash report is deleted. This is because Dynatrace doesn't send crash reports that are older than 10 minutes (as such reports can no longer be correlated on the Dynatrace Cluster).

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.

Business events are only captured for monitored sessions. When OneAgent is disabled either through a special flag or due to cost and traffic control, business events are not reported for such sessions. Note that this behavior might be subject to change in the future, potentially allowing business events to be sent to Dynatrace regardless of session monitoring.

For additional details on business events, refer to Business Analytics.

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. For more details, see User tagging.

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.

When the user opt-in mode is enabled for your application, it might affect user tagging and reporting of custom events, user actions, values, and errors. The exact data types not reported to Dynatrace depend on the data collection level set by a particular user. For details, refer to Data collection levels.

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 (opt-in mode)

With user opt-in mode, each user of your application can set their data privacy preferences and decide whether they want or don't want to share their information. When the opt-in mode is enabled, you need to ask each user for permission to capture their data; then, you store their data privacy preferences. For details, see User opt-in mode.

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.

Retrieve user's data privacy preferences

You can retrieve the data privacy preferences of a particular user.

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 user's data privacy preferences

You can adjust the data privacy preferences based on the decision of a particular user.

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
// Set a data collection level (user allowed you to capture performance and personal data)
options.DataCollectionLevel = DataCollectionLevel.UserBehavior;
// Allow crash reporting (user allowed you to collect information on crashes)
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);

The possible values for the data collection level are as follows:

  • Off
  • Performance
  • UserBehavior

Report GPS location

You can report the latitude and longitude.

SetGPSLocation(latitude: double, longitude: double);

Instrumentation Overhead

When using auto-instrumentation through our plugin, here are some examples of the size differences before and after instrumentation for release builds.

Operating System
App template
Version
Size Before
Size After
Difference
Android
Default new app
net8.0-android
31.8 MB
32.4 MB
0.6 MB
iOS
Default new app
net8.0-ios
421 MB
426.2 MB
5.2 MB

Configuration file

The dynatrace.config.json configuration file contains your application ID, beacon URL, and some other settings.

  • You can download this file from Dynatrace 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 the Assets (Android) or Resources (iOS) directory for a configuration file named dynatrace<Configuration>.config.json. For example, if you're using the Debug build configuration, our package looks for a file named dynatraceDebug.config.json.

  • If you want to specify a custom path for your configuration, set it via the DynatraceConfigurationFile property.

    Create Directory.Build.props in the Android/iOS (or general) project directory:

    <Project>
    <PropertyGroup>
    <DynatraceConfigurationFile>CUSTOM_PATH/dynatrace.config.json</DynatraceConfigurationFile>
    </PropertyGroup>
    </Project>

In summary, this results in the following order in which the configuration will be used:

  1. Custom configuration path through DynatraceConfigurationFile property
  2. Configuration-specific file like dynatrace<Configuration>.config.json
  3. Default name dynatrace.config.json

The following is the dynatrace.config.json file structure for Android and iOS.

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.

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.

  1. 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 existing PropertyGroup, depending on the configuration that you're executing.
  2. 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.

  3. Rebuild your project.

  4. Attach the build logs to the support ticket so that we can further analyze your issue.

Troubleshooting

If you can't resolve a problem, check Mobile applications: Issues with Dynatrace .NET MAUI NuGet package in the Dynatrace Community.