Mobile App Monitoring FAQ

TABLE OF CONTENTS

Data collection and reporting

Which app data is collected?

Along with the Instana monitoring, the mobile agent automatically collects the following app-specific information:

  • Bundle/App identifier.
  • App and build version.
  • Current app language.
  • iOS/Android version, device model, hardware, device, and manufacturer.
  • Whether a device is jailbroken/rooted.
  • Screen size and resolution.
  • Carrier name and connection type (2G, 3G, 4G...).

How is beacon reporting handled?

We collect all incoming beacons in a queue, which are flushed one second (ten seconds if the battery is low) after the last beacon has arrived. All beacons are transmitted in one HTTP request and there is a limit of 100 beacons per request. When the queue exceeds the limit of 100 items, any beacons that arrive are discarded. A compact format is used to save data traffic for data transmission. Until the beacons are reported to Instana, the queue uses a protected persistence layer to store all beacons which ensures that no beacon is lost if the app crashes or suddenly closes. To avoid blocking the main thread (UI), reporting and queue handling is performed in a background thread.

What happens for users with bad internet/network connections?

Data transmission requests from your mobile app users to our servers might not be working. In these cases, we attempt to deliver the beacons as part of the next monitoring data transmission, e.g., on the following mobile app start.

What happens if reporting fails?

Due to network problems, beacon reporting may fail. The beacons are retained in the queue for the next transmission attempt.

Is data collected while offline?

Yes, however, consider the limit of 100 beacons described above. If the queue is full and cannot be flushed (due to network issues) all upcoming beacons are discarded.

Is it possible to proxy the HTTP endpoints (for SaaS)?

We recommend not to attempt the proxying of the HTTP endpoints. Instana does not provide any support for any proxy setups nor for any issues that may arise due to the usage of a proxy. Should you still want (or have) to do this, you may find these pointers helpful:

  • Set proper Host HTTP headers.
  • Respect the difference between the eum.instana.io and eum-{region}.instana.io servers.
  • Make sure that our servers are aware of the end-users IPs. Send an X-FORWARDED-FOR header to our servers with the end-user's IP. Alternatively send a X-REALER-IP HTTP header (yes, deliberately not X-REAL-IP) to the Instana servers which contains the end-user's IP.
  • Pass through all the HTTP headers that the Instana servers include in the response body.
  • Don't do any caching in the proxy.

Sessions

The information captured by mobile Instana Agents is organized in sessions.

Each session maps to an instance of the app; starts when the app is instantiated and ends when the app is terminated.

Session lifecycle

  1. A session automatically starts every time the app is launched, when the agent is set up
  2. A sessionID is automatically generated for the session
  3. The sessionID remains unchanged while the app is alive (either in the foreground of the background)
  4. All beacons sent by the Instana Android/iOS Agent will contain the same sessionID
  5. The sessionID will be discarded when the app is terminated; when the process itself is terminated
  6. Next time the app is launched, a new sessionID will be automatically generated

HTTP Monitoring

What HTTP information is monitored?

  • The duration of the request.
  • HTTP method (POST, GET....).
  • Full URL and path.
  • Status code (e.g. 200).
  • Response sizes (header, body, decoded body).
  • Any underlying error.
  • Backend tracing ID for backend correlation.

What is the difference between auto and manual HTTP monitoring?

iOS

The iOS agent offers automatic and manual monitoring of HTTP sessions.

Automatic

To monitor HTTP requests and reponses going through the URLSession, the automatic HTTP monitoring uses the Foundation's URLProtocol. All captured requests and responses are reported to Instana. While the default URLSession can be intercepted implicitly by URLProtocol, all custom sessions require an explicit URLProtocol registration for monitoring. Because many applications have a custom URLSession, the registration process for those sessions is not the ideal solution for the Instana iOS agent. To simplify the registration process, all sessions are registered implicitly by swizzling the initializer of all URLSessions. With the swizzling approach, no registration of the URLProtocol is required and it simplifies automatic HTTP monitoring. Automatic monitoring of the WKWebView is not available since it's not reliable. The app and the WebView's WebKit run in different processes. There is an IPC between the app and WebKit process but some data (e.g. POST body) are not transmitted to the app process. This would lead to an unexpected behaviour.

Manual

By capturing the HTTP request & response manually, the client can opt-out from automatic monitoring and swizzling. No URLProtocol is installed to the URLSessions. Manual monitoring means that when capturing HTTP requests and responses, it requires more effort to use the monitoring by the client.

Android

The Android agent offers automatic and manual monitoring of HTTP sessions.

Automatic

The Android plugin will weave some additional tracking code in your app, at compile time.

We currently support automatic tracking of these network clients:

  • OkHttp3
  • HttpURLConnection
  • Retrofit

Please register your interest for support of additional network clients in the Android Agent's issue tracker.

Manual

By capturing the HTTP request & response manually, the client can opt-out from automatic monitoring and take complete control over which network requests are tracked and which are not.

Please refer to the Android API in order to learn more about this.

React Native

The React Native agent currently offers automatic of HTTP sessions.

Automatic

Please refer to the documentation specific to each platform for more details about automatic monitoring of HTTP sessions.

iOS: Can I use my own URLProtocol with automatic monitoring enabled?

Yes, you can create your own URLProtocol to proxy your requests and responses through a custom URLSession. Instana HTTP monitoring automatically ignores any URLSession that has an URLProtocol as delegate. But you can also explicitly ignore any custom URLSession from being monitored via Instana.ignore(yourURLSession). If you are using an URLSession inside your own URLProtocol without a delegate, you should ignore this session in the Instana iOS agent. Otherwise, the request and response is doubled monitored.

iOS: Isn't swizzling dangerous?

Not always. Swizzling in the runtime is mostly done by adding a new method:

func swizzled_touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  // looks weird, but it calls the original implementation
   swizzled_touchesBegan(touches, with: event)
   print("do some custom magic here")
 }

And then the new and old methods will be exchanged via:

if let originalMethod = class_getInstanceMethod(UIResponder.self, #selector(touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?))),
   let swizzledMethod = class_getInstanceMethod(UIResponder.self, #selector(swizzled_touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?))) {
        method_exchangeImplementations(originalMethod, swizzledMethod)
}

However, this could lead to unexpected behavior when the runtime makes a forward invocation like in UIResponder. Sometimes the runtime sometimes performs message forwarding. This swizzling technique could cause a crash if a message (e.g. the new swizzled_touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)) is forwarded to another receiver on which the new method does not exist. In the Instana iOS agent, we don't add a second method to the class. We set our new implementation directly (via a block) to the original selector and therefore override the original implementation. The original implementation, temporarly stored, is then called inside the new function; so our swizzling leaves no traces.

iOS: Is monitoring for background sessions available?

No, because custom URLProtocol subclasses are not available to background sessions. (see URLSession doc.)

How does backend correlation work with HTTP requests?

All HTTP requests include automatic backend correlation, to backends that are monitored by Instana's host agent. There is no need to track or set anything client-side.

Which HTTP headers are being used?

To achieve backend correlation, the agent makes use of the following HTTP headers:

  • Response Headers:

    • Server-Timing

Requirements

iOS

Which iOS versions are supported?

iOS: Instana iOS agent is compatible from iOS 11.

Which Swift versions are supported?

Swift 5 (since Xcode 10.2) or higher

How do I install the iOS agent?

iOS: Use the Swift Package Manager inside Xcode. Alternatively, you can use CocoaPods. To setup the Instana iOS agent, call one method in application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:.

Android

Which Android versions are supported?

Minimum supported API level: Android API 16 (Android 4.1 "Jelly Bean"). Android Gradle Plugin: 3.5.x, 3.6.x and 4.0.x AndroidX: AndroidX is supported and required.

Which Languages are supported?

Languages: Both Java and Kotlin are supported.

Java compatibility target: Java 1.8 or higher

What does the Duplicate class com.google.common.util.concurrent.ListenableFuture compilation error mean?

If your app has a dependency on guava, you might get the following compilation error after adding Instana Android Agent

Duplicate class com.google.common.util.concurrent.ListenableFuture found in modules guava-25.0-android.jar (com.google.guava:guava:25.0-android) and listenablefuture-1.0.jar (com.google.guava:listenablefuture:1.0)

To solve this, please add the following dependency to your app:

implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'

What does the NoSuchMethodError: No virtual method log(Ljava/lang/String;)V in class Lokhttp3/internal/Platform; runtime error mean?

This links to a well-know issue which might occur when your app's resolved OkHttp and OkHttp-logging-interceptor versions differ. This situation is described in more length in: https://github.com/square/okhttp/issues/2839

Instana Android Agent uses OkHttp v4, which might be newer than the OkHttp version your app was using.

To solve this, please upgrade your app's OkHttp and OkHttp-logging-interceptor to the latest available versions.

What does the android.os.StrictMode$StrictModeDiskReadViolation StrictMmode error mean?

Instana Android Agent makes use of Java's UUIDs.

A well-know false positive is raised by StrictMode in Android API 18 and lower: https://issuetracker.google.com/issues/36969031

As a work around, please disable penaltyDeath or detectDiskReads for API 18 and lower.

What does the java.lang.NoSuchMethodError: No virtual method setInitialDelay compilation error mean?

The whole error reads: java.lang.NoSuchMethodError: No virtual method setInitialDelay(JLjava/util/concurrent/TimeUnit;)Landroidx/work/OneTimeWorkRequest$Builder; in class Landroidx/work/OneTimeWorkRequest$Builder; or its super classes (declaration of 'androidx.work.OneTimeWorkRequest$Builder'

WorkManager 2.1.0 changed the method signature for setInitialDelay. Before WorkManager 2.1.0, it read as follows:

abstract class WorkRequest {
    abstract static class Builder<B extends Builder, W extends WorkRequest> {
    }
}

class OneTimeWorkRequest extends WorkRequest {
   static class Builder extends WorkRequest.Builder<Builder, OneTimeWorkRequest> {
       public @NonNull Builder setInitialDelay(long duration, @NonNull TimeUnit timeUnit) {
          ....
       }
  }
}

After WorkManager 2.1.0, it reads:

abstract class WorkRequest {
    abstract static class Builder<B extends Builder, W extends WorkRequest> {
         public @NonNull B setInitialDelay(long duration, @NonNull TimeUnit timeUnit) {
              ...
         }
    }
}

class OneTimeWorkRequest extends WorkRequest {
   static class Builder extends WorkRequest.Builder<Builder, OneTimeWorkRequest> {
  }
}

In effect, this means every dependency in a project needs to exclusively use WorkManager 2.1.0+ or previous versions.

Instana Android Agent uses WorkManager 2.4.0+.

If you get this error, the most probably issue is that another dependency is using an older version of WorkManager. Please make sure to update it.

What does the Required: PROJECT. Found: EXTERNAL_LIBRARIES, PROJECT, SUB_PROJECTS compilation error mean?

This error has been known to pop up when a gradle plugin which requires an Android Gradle Plugin older than 3.6.1 is compiled using Android Gradle Plugin 3.6.1 or higher.

For instance, we have found that using Realm Database Plugin 7.0.1 with Android Gradle Plugin 4.0.1 and Instana Android Agent 3.4.0 can give way to this compilation error. The resulting error log will contain a reference to Realm's transformer task's failure first, and then maybe to some other plugin (not relevant):

[...]
Task :app:transformClassesWithRealmTransformerForDevevelopDebug FAILED
[...]

In order to solve this issue, please try to upgrade the offending plugin.

Alternativelly, please either:

  1. Make sure that Instana Android Agent plugin is invoked after the offending plugin. For example:
apply plugin: 'com.android.application'
apply plugin: 'realm-android'
apply plugin: 'com.instana.android-agent-plugin'
  1. Downgrade your app's Android Gradle Plugin to the one that the offending pluging requires

What does the Problem processing attributes... compilation error in ajc-transform mean?

As of today, it seems like one of the bytecode transformations applied by the Firebase Performance Plugin has the adverse effect of preventing Instana Android Agent from doing it's job.

In order to prevent this issue, please make sure that Instana's Android Agent is run before Firebase Performance Plugin.

You can achieve this by simply changing the order in which you add each plugin into your project:

apply plugin: 'com.instana.android-agent-plugin' // Instana Agent will be applied before Firebase Performance
apply plugin: 'com.google.firebase.firebase-perf'

What does the Unable to find method... compilation error mean?

Each major Instana Android Agent version is compatible with a specific Android Gradle Plugin branch.

This error is most likely to show up when the Android Gradle Plugin being used isn't supported by the Instana Android Agent.

Please refer to the Android Gradle Plugin and Gradle version section of the documentation to check the compatibility matrix and learn where to find your app's current Android Gradle Plugin version.

What does the Failed resolution of: Landroidx/work/impl/utils/futures/AbstractFuture runtime error mean?

The whole error reads: Fatal Exception: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/work/impl/utils/futures/AbstractFuture;

This could happen if your app dependencies at some point required a dependency on 9999.0-empty-to-avoid-conflict-with-guava but it no longer requires it.

If your app's contains the following dependency, please try removing it:

implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'

What does the Execution failed for task ':app:transformClassesWithDexBuilderFor...' compilation error mean?

The whole error reads (for the DevDebug flavor, for instance):

FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformClassesWithDexBuilderForDevDebug'.
> There were multiple failures while executing work items
   > A failure occurred while executing com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform$DexConversionWorkAction
      > Failed to process /Users/developer/Projects/mobile-app/android/app/build/intermediates/javac/devDebug/classes
[...]

This error highlights a mismatch between the Instana Agent version and the Android Gradle plugin versions. Please refer to the platform-specific installation instructions to find out about the supported combinations.

React Native

Please refer to the documentation specific to each platform for more details.

Sensitive data

Are you collecting data which can uniquely identify users?

By default, the Instana Agent, does not include data which can unique identify users. Additionally, the agent also does not apply techniques such as device fingerprinting.

User specific data can be made available to Instana via the iOS user API or the Android user API.

What are you doing with the user data transmitted to Instana?

The Instana Agent can be configured by customers to transmit user-identifying information to Instana. This information is only used to provide the features visible to you within Instana. Instana does not interpret this data in any other way, nor is it correlated across customers.

Is it possible to delete user data after it has been transmitted to Instana?

Infrequent deletion requests, e.g. to comply with GDPR, are supported. If you expect frequent or periodic deletion requests, please instead transmit anonymized data to Instana (e.g. hashed user IDs).

Are you anonymizing IPs?

Yes, IPs are anonymized. Specifically, the last octet of IPv4 addresses, and the last 80 bits of IPv6 addresses are set to zeros.