AppDynamics Xamarin SDK
2021.8.0
Real user monitoring for your Xamarin app.
|
The AppDynamics Xamarin SDK is a package that allows you to monitor the performance and activities of a Xamarin.Android, Xamarin.iOS and/or a Xamarin.Forms app.
The SDK includes APIs to instrument specific methods in your own code, to measure durations of operations in your application (like application start up, for example), or to report an arbitrary metric.
NOTE: The SDK only targets Android and iOS deployments. All other targets will build and run. However, at runtime, the SDK calls are "stubbed" out and will actually do no work.
Follow the steps below to manually instrument your Xamarin iOS, Android, and Forms apps.
Complete the Getting Started Wizard to get an EUM App Key. You will need this key when you modify the source code. In some cases, multiple mobile applications can share the same key.
Because there is no Xamarin platform option, you will need to choose either Android or iOS. For Android, you will need to select Manual.
Xamarin.Android
project, add the following to MainActivity.cs
under OnCreate
:To initialize the Xamarin Agent, all you have to do is:
Note: See the AppDynamics.Agent.AgentConfiguration
object for more configuration options
Where to best place this code snippet depends on the desgin of the application. It is usually best to place it as early as possible in the runtime lifecycle.
It's recommended to add the initialization code in the App.xaml.cs
file:
It's recommended to add the initialization code in the MainActivity.cs
file under the OnCreate
method:
It's recommended to add the initialization code in the AppDelegate.cs
file under the FinishedLaunching
method:
Although these are usually on by default, it is important to make sure that the following permissions are enabled in the Properties/AndroidManifest.xml
file:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Run and build your application from Visual Studio. From the Getting Started Wizard, you should see that the application has connected and the instrumentation has been verified.
For iOS projects with Xamarin Agent versions prior to 2021.5.0, you must add the additional MtouchExtraArgs
argument --gcc_flags "-ObjC -lz"
for each build configuration. If the iOS project file is edited directly, the build configuration should contain the MtouchExtraArgs element:
To use an on-premises EUM Server, you pass the URL to the on-premises EUM Server when you initialize the instrumentation with the EUM App Key from Get Your Application Key:
You can instrument methods to see how often the instrumented a method is invoked and how long it takes to run. To do this, add a call at the beginning and end of the method you'd like to instrument.
In the example below, the code executed in the constructor for the class ShoppingCart will be tracked and reported. In your own code, start tracking calls by specifying the class and method in BeginCall and then complete the tracking and report the data by calling ReportCallEnded.
Sometimes you want to time an event in your application that spans multiple methods. You can do this by calling StartTimerWithName when the event starts, and then StopTimerWithName when it ends. For example, to track the time a user spends viewing a screen, the instrumentation might look something like the following:
To report other types of data, you can use a metric. The metric name should only contain alphanumeric characters and spaces. Illegal characters are replaced by their ASCII hex value. The metric value must be a long integer.
The snippet below shows how you might report a metric.
The HttpRequestTrackerHandler
handles all the tracking and error handling. It can also include other inner handlers if you are already using a custom HttpMessageHandler
for other purposes, such as for logging.
To add http tracking, instantiate an HttpClient
and pass the HttpRequestTrackerHandler
:
Then, all the requests sent using the client will be already instrumented:
If you already have HttpMessageHandler
passed to the HttpClient (for example, adding a logging handler), you must instantiate HttpRequestTrackerHandler
and pass the existing handler to the constructor:
You can manually report a network request using the AppDynamics.Agent.HTTPRequestTracker
.
The example below uses HTTPRequestTracker
with the System.Net.Http.HttpClient
class. The tracker object synchronously captures and reports the network request as well as any network errors.
You can leave breadcrumbs to mark interesting events. For example, if your application crashes, the breadcrumbs you left with be displayed in the crash report and could provide context. You can also configure the breadcrumb to appear in sessions.
The following is the method signature for leaving breadcrumbs:
You use the mode to set the visibility of the breadcrumb. The visibility defines where you will see the breadcrumb in the Controller UI. The value of mode can be one of the following:
BreadcrumbVisibility.CrashesOnly
– The breadcrumb will only appear in crash snapshots.BreadcrumbVisibility.CrashesAndSessions
– The breadcrumb will appear in crash snapshots and sessions.Thus, you would use the method below to set breadcrumbs that are only reported in crash reports:
If you would like to see the breadcrumb in crash reports and sessions:
You can disable the agent to stop sending all data to the collector while the agent is initialized and running. For example, you can disable the agent if your app has an option for users to opt-out of monitoring for privacy reasons.
The shutdownAgent call stops outgoing data to the collector, and does not persist data on the device.
To re-enable the agent and reverse shutdownAgent, use restartAgent.
You can report exceptions using the method reportError
from the Instrumentation
class. Reported exceptions will appear in session details.
You can also set one of the severity levels below for an issue. With the severity level, you can filter errors in the Code Issues Dashboard or Code Issues Analyze.
ErrorSeverityLevel.INFO
ErrorSeverityLevel.WARNING
ErrorSeverityLevel.CRITICAL
The example below uses the API to report possible exceptions and sets the severity level to ErrorSeverityLevel.CRITICAL
(critical) when writing to a file
You can configure the Xamarin Agent to report aggregate exceptions (handled and unhandled) as crashes by setting the boolean property EnableAggregateExceptionHandling to true. When the property is set to false, only unhandled exceptions are reported. The default value is false.
The following code example configures the Xamarin Agent to report aggregate exceptions (handled and unhandled) as crashes.
Crash reporting is enabled by default, but you can manually disable crash reporting through the instrumentation configuration. If you are using other crash reporting tools, you might disable crash reporting to minimize conflicts and optimize the crash report results.
You can disable crash reporting by configuring the instrumentation with the crashReportingEnabled
property as shown in the following code snippet:
By default, a mobile session ends after a period of user inactivity. For example, when a user opens your application, the session begins and only ends after the user stops using the app for a set period of time. When the user begins to use the application again, a new session begins.
Instead of having a period of inactivity to define the duration of a session, however, you can use the following API to programmatically control when sessions begin and end:
When you call the method StartNextSession
, the current session ends and a new session begins. The API enables you to define and frame your sessions so that they align more closely with business goals and expected user flows. For example, you could use the API to define a session that tracks a purchase of a product or registers a new user.
Excessive use of this API will cause sessions to be throttled (excessive use is > 10 calls per minute per Xamarin Agent, but is subject to change). When not using the API, sessions will fall back to the default of ending after a period of user inactivity.
In the example below, the current session ends and a new one begins when an item is bought.
You can use the Session Frame API to create session frames that will appear in the session activity. Session frames provide context for what the user is doing during a session. With the API, you can improve the names of user screens and chronicle user flows within a business context.
The following are common use cases for the ISessionFrame API:
The table below lists the two methods and one property you can use with session frames. In short, you start a session frame with StartSessionFrame
and then use the returned ISessionFrame object to rename and end the session frame.
Class | Method / Property | Description |
---|---|---|
Instrument | Method: static ISessionFrame StartSessionFrame(string sessionFrameName) | Use this to start and name your session frame. Naming session frames enables you to easily identify and track the frames in the Sessions Details dialog. |
ISessionFrame | Property: string Name | Rename the session frame name. You assign the updated session frame name with this property from the ISessionFrame object returned from StartSessionFrame . |
ISessionFrame | Method: static void End() | End the session frame. You call this method from the ISessionFrame object returned from StartSessionFrame . |
In the following example, the ISessionFrame API is used to track user activity during the checkout process.
You can set a key/value pair of strings to record important events or information. Below is the method signature for setting user data:
For example, you might want to log the user ID when the method for logging in the user is called:
This information is available in Network Request Analyze and is added to any crash snapshots that may be taken. Keys and values are limited to 2048 characters each.
You can also set user data with values of other types (long, boolean, double, DateTime) using the following methods:
To remove user data, use the following methods:
You can set the logging level with the configuration LoggingLevel
as part of the class AgentConfiguration
.
You can set LoggingLevel to one of the levels listed in the table below:
Level | Description |
---|---|
Off | Agent will emit no messages at all. |
Error | Default Value. Only show errors and initial banner. |
Warn | Warning level messages and above. |
Info | Information level messages and above. May be useful to the developer. |
Debug | Debug level messages and above. Useful for support personnel and developers. |
Verbose | Verbose level messages and above. Use verbose logging only for troubleshooting. Be sure to disable for production. |
All | All messages. |
For example:
The callback that modifies or ignore specific URLs should be assigned to the Func delegate below.
To transform URLs, the OnNetworkRequest
method should:
IHttpRequestTracker
object.IHttpRequestTracker
object will be ignored.For example:
You may want to identify and transform URLs that contain sensitive information.
For example:
If the onNetworkRequest
method returns false, the beacon is dropped. Generally, the process for ignoring beacons is:
false
.To ignore specific URLs, you would identify network requests that you didn't want to monitor and return false
to ignore the network request.
For example:
To ignore all network requests, implement the following:
To register a network request callback:
AgentConfiguration
initialization phase:Mobile screenshots are enabled by default, but you can configure the Controller UI to automatically take screenshots or use the Xamarin SDK to manually take a screenshot:
Note: The takeScreenshot() function limits screenshots to a maximum of 1 screenshot per 10 seconds.
You can disable screenshots from the Controller UI or with the Xamarin SDK. To disable screenshots with the Xamarin SDK, set the property ScreenshotsEnabled of the IAgentConfiguration object to false:
You can also use the Xamarin SDK to block screenshots from being taken during the execution of a code block. This just temporarily blocks screenshots from being taken until you unblock screenshots. This enables you to stop taking screenshots in situations where users are entering personal data, such as on login and account screens.
The Instrumentation class provides the methods blockScreenshots()
and unblockScreenshots()
to block and unblock screenshots.
Note: If screenshots are disabled through the property ScreenshotsEnabled
of the IAgentConfiguration
object or through the Controller UI, these methods have no effect. You can also check the Instrumentation.ScreenshotsBlocked
property to check if screenshots are being blocked.
You may want to make crash report information (that the Xamarin Agent collects) available to other parts of your code, for example, to Google Analytics. To enable passing on summary crash information, you can set up a crash report runtime callback. To get a callback when the Xamarin Agent detects and then reports a crash, subscribe to the following event, that's part of the IAgentConfiguration interface.
The Xamarin Agent sends a collection of crash report summaries instead of an individual callback in the event that there is more than one crash, producing multiple crash report summaries.
The OnCrash
event is raised during the next initialization of the Xamarin Agent after a crash has occurred.
This event is raised on your app's UI thread, so any work should be done on a separate work thread.
Each CrashReportSummary has the following properties:
If you are sending the information to another analytics tool, such as Google Analytics, we recommend to include all three properties: ExceptionName
and ExceptionReason
are useful for quick identification of the crash, and ExceptionId
is useful to look up the crash in the Controller UI.
For example, to print the crash information to the console, you could subscribe to the OnCrash
event like this:
You can now instrument Xamarin.Forms elements using AppDynamics.Agent.Forms. Make sure you included the right nuget package before proceeding.
Track page usage and see the how the user interacts with the application in the session timeline.
In order to track pages, all you need to do is call TrackPage from the constructor on every page you want to monitor: