Mobile app monitoring
Concepts
End-User Monitoring (EUM) or Real-User Monitoring (RUM), is a vital tool to understand digital user experience.
Instana supports mobile app monitoring by analyzing actual URL request times, which provides detailed insights into the app experience of users, and deep visibility into application call paths. The Instana app monitoring solution works that uses an iOS/Android agent, which is installed as a dependency on mobile apps.
Installation
iOS
To install the iOS agent, use Swift Package Manager (through Xcode) or CocoaPods.
Requirements
- iOS 11 or later
- swift 5.1 or later
Swift Package Manager
- Open Xcode.
- Select File -> Swift Packages -> Add Package Dependency -> Your Xcode project.
- Enter the https://github.com/instana/iOSAgent repository.
CocoaPods
-
Within your
Podfile
specification, add the commands:pod 'InstanaAgent'
-
To download the dependencies, run
pod install
.
Setup
For more information on the setup process, see the iOS agent API.
Android
The Android agent is composed by a Gradle plugin and an SDK library. Apply the plugin to your application module and add the SDK as a dependency.
Requirements
- Android 4.1+ (API level 16+)
- Java 8+
- Gradle 7.3.3+
- AndroidX
- targetSdk 33+
Note: If you have to use Gradle version lower than 7.3.3 in your project, you must use an android-agent
version lower than 6.0.0.
Instana Android plugin
In your project-level build.gradle
file:
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.instana:android-agent-plugin:6.0.0"
}
}
In your module (app-level) Gradle file (usually app/build.gradle
) after you apply the com.android.application
plugin:
apply plugin: 'com.android.application'
apply plugin: 'com.instana.android-agent-plugin'
Instana Android SDK
In your project-level build.gradle
file,
allprojects {
repositories {
google()
mavenCentral()
}
}
In your module (app-level) Gradle file (usually app/build.gradle
),
dependencies {
implementation 'com.instana:android-agent-runtime:6.0.0'
}
Java 1.8 compatibility
Note: this step is not needed if your minSdkVersion
is 24 or higher
In your module (app-level) Gradle file (usually app/build.gradle
),
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Request READ_PHONE_STATE permission (optional)
When a user accesses the internet through a cellular network, Instana Agent can report the specific type of cellular network.
To enable the reporting of the cellular network type, your app needs to request the READ_PHONE_STATE
permission. Refer to the Request App Permissions
section in the official Android documentation.
If your app doesn't request the permission or if the user declines it, Instana Agent does not report the cellular network type.
Basic initialization
In your class, which extends Application
, replace YOUR_REPORTING_URL
and YOUR_APP_KEY
with the configuration values you find in your Instana Dashboard:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Instana.setup(
this,
InstanaConfig(
key = "YOUR_APP_KEY",
reportingURL = "YOUR_REPORTING_URL"
)
)
}
}
Advanced usage
For a complete list of initialization options, view tracking, manual request-tracking, and see the Android agent API.
React Native
The React Native agent brings support for both Android and iOS platforms.
Requirements
Add the dependency
Run the following command in your project's root:
npm install @instana/react-native-agent --save
Basic initialization
In your class App.js
file, replace YOUR_INSTANA_APP_KEY
and YOUR_INSTANA_REPORTING_URL
with the configuration values you find in your Instana Dashboard:
export default class App extends Component {
componentDidMount() {
Instana.setup(YOUR_INSTANA_APP_KEY, YOUR_INSTANA_REPORTING_URL, null);
}
}
Recommendation
We recommend adding http://localhost:8081
to the ignored URLs list to prevent the Agent from tracing communication with the Metro bundler:
Instana.setIgnoreURLsByRegex(["http:\/\/localhost:8081.*"]);
iOS
Your project should contain at least one Swift file (it can be empty).
If you don't have any, open your Xcode Project in <YourReactNativeProject>/ios
and add an empty Swift file. Let Xcode create the Bridging Header for you.
Android
Use the Instana Android plugin version appropriate for your React Native version:
- React Native 0.63.3 or earlier: Use Instana Android plug in 1.5.3
- React Native 0.63.4 or later: Use Instana Android plugin 5.2.2
Follow these steps to enable automatic HTTP monitoring:
-
In your
/android/build.gradle
file:buildscript { dependencies { classpath "com.instana:android-agent-plugin:$INSTANA_ANDROID_PLUGIN_VERSION" } }
-
In your
/android/app/build.gradle
file:apply plugin: 'com.android.application' apply plugin: 'com.instana.android-agent-plugin'
Known issues
fetch(url)
If your app uses fetch
to complete network requests, you might find your app crashing on runtime whenever fetch
is used: No virtual method toString(Z)Ljava/lang/String;
If you encounter this issue, and until the upstream issue is solved (here and here), apply the following workaround.
In your Android module-level gradle file (usually app/gradle.build
):
dependencies {
implementation "com.squareup.okhttp3:okhttp:4.3.1"
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.3.1"
}
Execution failed for task ':app:transformClassesWithDexBuilderForDevDebug'
If you upgraded to React Native 0.63.4 from a previous version, check that you are using,
- Instana Android plug in 4.5.3
- Gradle 6.5:
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
inandroid/gradle/wrapper/gradle-wrapper.properties
- Android Gradle plugin 5.2.2:
classpath("com.android.tools.build:gradle:4.1.0")
inandroid/build.gradle
Advanced usage
For a complete list of initialization options, view tracking, and so on, see the React Native agent API.
Flutter
The Flutter agent brings support for both Android and iOS platforms.
Note that the Flutter agent does not provide automatic http tracing. Http tracing must be manually set up by the developer (an example is provided in this documentation)
Requirements
- Flutter version 1.20.0 or later
- Dart version between 2.12.0 and 3.0.0
Adding the package to your app
The Instana agent Flutter package is available via pub.dev.
You can add it to your app the same way as usual:
- Open the
pubspec.yaml
file located inside the app folder, and addinstana_agent:
underdependencies
. - Install it.
From the terminal, Run flutter pub get
Or * From Android Studio/IntelliJ: Click Packages get in the action ribbon at pubspec.yaml
. * From VS Code: Click Get Packages that are located in right side of the action
ribbon atpubspec.yaml
.
Initialization
Import package in your dart files:
import 'package:instana_agent/instana_agent.dart';
Stop and restart the app, if necessary
Setup Instana once as soon as possible. For example, in initState()
@override
void initState() {
super.initState();
InstanaAgent.setup(key: 'YOUR-INSTANA-KEY', reportingUrl: 'YOUR-REPORTING_URL');
}
If you intend to build for iOS, set up a minimum platform version in ${appFolder}/ios/Podspec
with a minimum value of 11.0
.
Tracing View changes
At any point after initializing Instana agent:
import 'package:instana_agent/instana_agent.dart';
[...]
InstanaAgent.setView('Home');
Tracing Http requests
At any point after initializing Instana agent:
import 'package:instana_agent/instana_agent.dart';
[...]
InstanaAgent.startCapture(url: 'https://example.com/success', method: 'GET').then((marker) => marker
..responseStatusCode = 200
..responseSizeBody = 1000
..responseSizeBodyDecoded = 2400
..finish());
We recommend creating your own InstrumentedHttpClient
extending http.BaseClient
as shown in this snippet, for example:
class _InstrumentedHttpClient extends BaseClient {
_InstrumentedHttpClient(this._inner);
final Client _inner;
@override
Future<StreamedResponse> send(BaseRequest request) async {
final Marker marker = await InstanaAgent.startCapture(url: request.url.toString(), method: request.method);
StreamedResponse response;
try {
response = await _inner.send(request);
marker
..responseStatusCode = response.statusCode
..responseSizeBody = response.contentLength
..backendTracingID = BackendTracingIDParser.fromHeadersMap(response.headers);
} finally {
await marker.finish();
}
return response;
}
}
class _MyAppState extends State<MyApp> {
[...]
Future<void> httpRequest() async {
final _InstrumentedHttpClient httpClient = _InstrumentedHttpClient(Client());
final Request request = Request("GET", Uri.parse("https://www.instana.com"));
httpClient.send(request);
}
[...]
}
Dashboards
Summary
The main dashboard summarizes all the important data at a glance.
HTTP Requests
Learn which of your HTTP requests are slow or problematic. Selecting a specific origin provides an insight into throughput and latency, and error rates and latency breakdown.
Views
Often it's important to isolate specific views and analyze their performance, which is also a great way to find the view with the most traffic. Select a specific view to display all of the metrics that relates to it.
Analytics
Similar to analytics capabilities for traces and calls, the analytics view for mobile app monitoring data can be used to answer specific questions that aren't covered by any preconfigured dashboards. A single piece of app monitoring data is called a beacon. A few beacon types exist, that is, session start and HTTP requests. For convenience purposes, each beacon type has its main navigation item within the analytics view.
Beacon data can be used to filter and group. The default grouping depends on the selected beacon type. Grouping can be removed to inspect the individual beacon that match filters.
Geographic Data
Instana maps end-user IP addresses to geographic details based on GeoLite2 database, which is provided by MaxMind. The IP addresses are collected by using the reverse proxy server. For self-hosted installation, make sure that you configure the URL of the end-user monitoring endpoint as the agent reporting URL. Otherwise, the IP addresses are not collected, and the related geographic details information is not available.