Instrument mobile app with Dynatrace Xamarin NuGet Package

Dynatrace 1.214+

The Dynatrace Xamarin NuGet Package helps auto-instrument your Xamarin app with Dynatrace OneAgent for Android and iOS and also provides an API to add manual instrumentation. It is compatible with Xamarin.iOS, Xamarin.Android and Xamarin Forms projects.

Supported features

Auto-instrumentation using OneAgent for Android and iOS

  • User actions for application start and controls
  • Lifecycle events
  • Web requests
  • Crashes

Manual instrumentation

  • Custom User Actions
  • User Tagging
  • Report Errors
  • Report Crashes
  • Report Events
  • Report Values (String, Int, Double)
  • Web Requests

Requirements

  • .NET Standard 1.1 and later
  • Gradle >= 5.0
  • For Android users: Minimum SDK version 15
  • For iOS users: Minimum iOS 6

Quick setup

  1. Install NuGet package
  2. Setup configuration in WebUI
  3. Add config file to your project
  4. Add the Start method

1. Install the NuGet Package

  1. In Visual Studio, right-click the main project of your app and select Manage NuGet packages.
  2. Search for Dynatrace.OneAgent.Xamarin from nuget.org and select Add Package.
  3. Select the checkboxes of all the projects that you want to add the NuGet package to, then select OK.

2. Set up configuration in WebUI

The new Dynatrace Xamarin NuGet package may be available at nuget.org before your environment is updated to version 1.214. If that is the case, you won't be able to access the Xamarin wizard. As a workaround, create the dynatrace.config.json file using information from Android or iOS instrumentation wizards.

  1. Create a custom mobile app as explained below.
  2. Instead of downloading the dynatrace.config.json file, create the file manually by copying the values from the Android or iOS wizard.
  3. Save the file as dynatrace.config.json.
  4. Add the dynatrace.config.json file you just created to your project. See Add config file to your project.

In Dynatrace, define a new mobile app.

  1. From the navigation menu, select Deploy Dynatrace.
  2. Select Set up mobile monitoring and type the name of your mobile app.
  3. Select Create mobile app. Mobile app settings page appears.
  4. Select Instrumentation wizard and then select Xamarin tile.
  5. Download the dynatrace.config.json file.

3. Add config file to your project

Add the downloaded dynatrace.config.json file into the Assets directory of your Android project.

For more information, see Advanced topics.

4. Add the Start method

The start method is required for the OneAgent for mobile to start.

using Dynatrace.Xamarin;

Agent.Instance.Start();

Note: To allow for auto-instrumentation of web requests, see the Setup HTTP client section.

Advanced topics

How can you use different build configurations?

When using a specific build configuration, i.e. Debug, Release, or a custom defined configuration, our package will search the Assets (Android) or Resources (iOS) folder for a config file named dynatrace<Configuration>.config.json. For example, if you are using the Debug build configuration, our package will look for a file name of dynatraceDebug.config.json. If the configuration specific file is not found, the default dynatrace.config.json file will be used.

Note:
If you do not add a config file to the Assets (Android) or Resources (iOS) folder with the minimum properties of DTXBeaconUrl and DTXApplicationId, the build will fail. Alternatively, you can use DTXAutoStart and set it to false if you want to use the Start method with a configuration dictionary (iOS) or configuration builder (Android). For more information, see Start the OneAgent manually.

Xamarin Forms

Register the interface at the startup in the native part of your Xamarin Forms application, and paste the following code right after Forms.Init() - Following example is from an Android Forms application:

using Dynatrace.Xamarin;

Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Xamarin.Forms.DependencyService.RegisterSingleton<IDynatrace>(Agent.Instance);

LoadApplication(new App());

The following piece of code in your forms application allows you to access the agent:

using Dynatrace.Xamarin;

IDynatrace dynatrace = DependencyService.Get<IDynatrace>();

Make sure that in case of auto instrumentation, you also need to apply the package to the native parts.

Manual instrumentation

Start the OneAgent manually

Using manual startup with configuration builder:

using Dynatrace.Xamarin;

Agent.Instance.Start(new ConfigurationBuilder("<insertBeaconURL>","<insertApplicationID>")
                .WithDebugLogging(true)
                .WithCertificateValidation(true)
                .WithCrashReporting(true)
                .WithUserOptIn(true)
                .BuildConfiguration());

Create manual actions

To create a manual action named "MyButton tapped", use the following code. The leaveAction closes the action again. To report values for this action before closing, see Report Values.

using Dynatrace.Xamarin;

var myAction = Agent.Instance.EnterAction("MyButton tapped");
//Perform the action and whatever else is needed.
myAction.LeaveAction();

Create manual sub actions

You can create a single manual action as well as sub actions. The MyButton Sub Action is automatically put under the MyButton tapped. As long as MyButton tapped is open, it gathers all the web requests.

using Dynatrace.Xamarin;

var myAction = Agent.Instance.EnterAction("MyButton tapped");
var mySubAction = myAction.EnterAction("MyButton SubAction");
//Perform the action and whatever else is needed.
mySubAction.LeaveAction();
myAction.LeaveAction();

Setup Http Client

To enable the auto-instrumentation of web requests, you will need to use the following method:

using Dynatrace.Xamarin;

HttpClient httpClient = new HttpClient();
Agent.Instance.SetupHttpClient(httpClient);

Every HttpClient passed to this function gets an additional handler which will take care of the manual web request instrumentation. All other available functions behave the same as their native counterparts.

Manually instrument web requests

using Dynatrace.Xamarin;

// Create action
var webAction = Agent.Instance.EnterAction(actionName: "WebRequest Action");
// Generate a new unique tag associated with the web request action
string requestTag = webAction.GetRequestTag();
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
WebRequestTiming timing = (WebRequestTiming)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 was 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 Action
  webAction.LeaveAction();
}

Report values

For any open action you can report certain values. The following API is available for action:

ReportValue(valueName: string, value: int);
ReportValue(valueName: string, value: double);
ReportValue(valueName: string, value: string);
ReportError(errorName: string, errorCode: number);
ReportEvent(eventName: string);

To report a string value, use the following:

using Dynatrace.Xamarin;

var myAction = Agent.Instance.EnterAction("MyButton tapped");
myAction.ReportValue("ValueName", "ImportantValue");
myAction.LeaveAction();

Report an error stacktrace

To manually report an error stacktrace, use the following API call:

using Dynatrace.Xamarin;

Agent.Instance.ReportErrorStacktrace("Error_Class", "Error_Value", "Error_Reason", "Error_Stacktrace");

Report a crash manually

Android only: When using automated crash reporting, be aware that Visual Studio might catch the exception in front of OneAgent. If you notice that crashes on Android devices are not reported to your environment, make sure you are not using the debug option in Visual Studio or the debugger will catch the crash and nothing will be reported. See Turn off the Visual Studio Debugger for Android projects.

To manually report a crash, use the following API call:

using Dynatrace.Xamarin;

Agent.Instance.ReportCrash("CrashWithoutException", "Crash_Reason", "Crash_Stacktrace");

Using an exception object:

using Dynatrace.Xamarin;

Agent.Instance.ReportCrashWithException("CrashWithExceptionObj", exception);

Note: When you use the API calls ReportCrash and ReportCrashWithException to report a crash manually, it will force the session to be completed. Any new actions that are captured afterward will be added into a new session.

Identify a user

You can identify a user and tag the current session with a name by making the following call:

using Dynatrace.Xamarin;

Agent.Instance.IdentifyUser("User XY");

End a session

You can force a session to end via the API. This will also close all open actions.

using Dynatrace.Xamarin;

Agent.Instance.EndVisit();

Data collection and UserPrivacyOptions

The privacy API methods allow you to dynamically change the data-collection level based on the individual preferences of your end users. Each end user can select from three data-privacy levels:

enum DataCollectionLevel {
    Off, Performance, UserBehavior
}
  1. Off: Native OneAgent doesn't capture any monitoring data.
  2. Performance: Native OneAgent captures only anonymous performance data. Monitoring data that can be used to identify individual users, such as user tags and custom values, aren't captured.
  3. UserBehavior: Native OneAgent captures both performance and user data. In this mode, Native OneAgent recognizes and reports users who re-visit in future sessions.

The API to get and set the current level looks like this:

To get current UserPrivacyOptions configuration:

using Dynatrace.Xamarin;

// Get the UserPrivacyOptions object:
UserPrivacyOptions currentOptions = Agent.Instance.GetUserPrivacyOptions();

// Get the individual settings for DataCollectionLevel and or crash reporting:
bool crashOptedIn = Agent.Instance.GetUserPrivacyOptions().CrashReportingOptedIn;
DataCollectionLevel dataCollectionLevel = Agent.Instance.GetUserPrivacyOptions().DataCollectionLevel;

Setting new options on a UserPrivacyOptions object:

using Dynatrace.Xamarin;

// Creating a new UserPrivacyOptions object requires setting the two parameters of DataCollectionLevel and crash reporting:
UserPrivacyOptions options = new UserPrivacyOptions(DataCollectionLevel.Performance, false);

// You can update the options with the setter:
options.DataCollectionLevel = DataCollectionLevel.UserBehavior;
options.CrashReportingOptedIn = true;

// You can get the values of the configuration with the getter:
options.DataCollectionLevel;
options.CrashReportingOptedIn;

// You can get the UserPrivacyOptions object with the following:
UserPrivacyOptions currentOptions = Agent.Instance.GetUserPrivacyOptions();

Apply new UserPrivacyOptions configuration:

using Dynatrace.Xamarin;

UserPrivacyOptions options = new UserPrivacyOptions(DataCollectionLevel.UserBehavior, true);
Agent.Instance.ApplyUserPrivacyOptions(options);

Report GPS Location

You can report latitude and longitude and specify an optional platform.

SetGPSLocation(latitude: double, longitude: double);

Structure of the dynatrace.config.json file

The configuration is structured in the following way:

{
    "android": {
        "autoStart": {
            "applicationId": "<insertApplicationID>",
			      "beaconUrl": "<insertBeaconURL>"
        }
        "userOptIn": true
    }
}

User opt-in mode

Specifies if the user has to opt-in before they are monitored. When enabled, you must specify the privacy setting. For more information, see the API section and the configuration above.

Native OneAgent debug logs

If the instrumentation runs through and your application starts but you see no data, you probably need to dig deeper to find out why the OneAgents aren't sending any data. Opening up a support ticket is a great idea, but gathering logs first is even better.

Add the following configuration snippet to your other configuration in dynatrace.config.json right under the autoStart block (the whole structure is visible, so you know where the config belongs):

{
    "android": {
        "autoStart": {
            "applicationId": "<insertApplicationID>",
			      "beaconUrl": "<insertBeaconURL>"
        }
        "userOptIn": true,
        "debug": {
            "agentLogging": true
        }
    }
}

Build debug logs

If, for instance, 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 property DynatraceInstrumentationLogging and change the build log level to Diagnostic.

  • Enable the property DynatraceInstrumentationLogging:

Setting the property DynatraceInstrumentationLogging is possible in several ways. One is to create Directory.Build.props in the Android project directory:

<Project>
	<PropertyGroup>
		<DynatraceInstrumentationLogging>true</DynatraceInstrumentationLogging>
	</PropertyGroup>
</Project>

Another option is to add the property in the .csproj file of your project. Insert it into some existing PropertyGroup, depending on the configuration that you are executing (such as Debug or Release).

  • Set build output verbosity

To learn how to change the output verbosity to Diagnostic, see the Microsoft documentation: To change the amount of information included in the build log.

  • After setting the property and changing the build output verbosity, rebuild your project and attach the build logs to the support ticket so we can further analyze your problems.

How does Dynatrace determine the user action name?

For more information on the user action name, see User action naming

Further reading

Troubleshooting

Failed build

If you receive a failed build while the NuGet package is added for iOS, make sure you add the dynatrace.config.json file to your Resources folder and that you include the following:

  • Minimal Auto-instrumentation properties
    • DTXApplicationId
    • DTXBeaconUrl

Note: If you forget to add either DTXApplicationId or DTXBeaconUrl, you will see a failed build with an exception. You need both properties added to the dynatrace.config.json as they both are required properties. You will also encounter an exception if DTXAutoStart => false while including either the DTXApplicationId or DTXBeaconUrl properties. For a manual startup, see below.

Using manual startup

Add DTXAutoStart and set the value to false

Note: Only use this property as no other properties will be considered when manually starting OneAgent for iOS and you will encounter a failed build with an exception if additional properties are added other than DTXAutoStart => false.

Dynatrace.Xamarin.Build.iOS

The following error can happen on older Xamarin iOS projects:

dotnet "/tools/netcoreapp2.1/Dynatrace.Xamarin.Build.iOS.dll" "Debug"

Could not execute because the specified command or file was not found.

The Dynatrace Xamarin package MSBuild command can't resolve the package directory because the .csproj file references Dynatrace Xamarin package dependencies individually, not as a package. To resolve the problem

  1. Open your iOS .csproj file and remove all Dynatrace Xamarin package .dll references. For example

    <Reference Include="Dynatrace.Xamarin.Abstraction">
      <HintPath>..\packages\Dynatrace.OneAgent.Xamarin.8.x.x.x\lib\xamarinios10\Dynatrace.Xamarin.Abstraction.dll</HintPath>
    </Reference>
    <Reference Include="Dynatrace.Xamarin.Binding.iOS">
      <HintPath>..\packages\Dynatrace.OneAgent.Xamarin.8.x.x.x\lib\xamarinios10\Dynatrace.Xamarin.Binding.iOS.dll</HintPath>
    </Reference>
    <Reference Include="Dynatrace.Xamarin.iOS">
      <HintPath>..\packages\Dynatrace.OneAgent.Xamarin.8.x.x.x\lib\xamarinios10\Dynatrace.Xamarin.iOS.dll</HintPath>
    </Reference>
    
  2. Add the Dynatrace Xamarin package reference to the .csproj file. Add the actual package version as the value of <Version>.

    <ItemGroup>
      <PackageReference Include="Dynatrace.OneAgent.Xamarin">
        <Version>8.x.x.x</Version>
      </PackageReference>
    </ItemGroup>
    
  3. Rebuild your project.

Turn off the Visual Studio Debugger for Android projects

The following options were tested with the latest Visual Studio. If you are using an older version, the options below might look slightly different.

Use a right-click on your Android project and select properties. This will show your project-related settings. Then select Android Options and clear Enable developer instrumentation. Keep in mind this will disable debugging. Use this option only to verify that crashes are sent. Optionally, you can create a release build that is detached from Visual Studio.

Disable developer instrumentation

Contact Dynatrace ONE

If you're unable to resolve a problem, please contact a Dynatrace ONE product specialist via in-product chat. Have the following details available:

  • Logs from the OneAgent
  • Your dynatrace.config.json file