Instana

Instana

The community for performance and observability professionals to learn, to share ideas, and to connect with others.

 View Only

Monitoring WebView-Based Hybrid Mobile Applications in Instana: A Comprehensive Guide

By Joby Korah George posted 04/29/26 02:52 AM

  

 

Modern mobile apps often embed web content using WebView components (Android WebView, iOS WKWebView). This creates a monitoring challenge: how do you correlate native mobile sessions with web sessions when they’re tracked by different Instana agents?


Clarification: This guide covers native apps with embedded WebViews, NOT cross-platform frameworks like Flutter or React Native.

This integration approach bridges Instana’s Mobile SDK and Website Monitoring to provide:
- Complete end-to-end user journey tracking
- Unified session correlation for faster troubleshooting
- Direct navigation from mobile traces to web session data

The Challenge:

When a WebView loads web content in mobile, you have two separate monitoring contexts:

  • Mobile SDK: Tracks native app events, crashes, and network calls
  • Website Monitoring (JavaScript agent): Tracks page loads, JS errors, and AJAX calls

Without integration, you can’t:
- See the complete user journey from native to web
- Correlate mobile crashes with web errors
- Quickly navigate between mobile and web session data

Solution Architecture

The integration uses three components:

1. Session ID Injection: Pass mobile session ID to web context via JavaScript
2. Custom Event/Metadata: Store correlation URL in mobile session
3. HTTP Marker: Create clickable link in mobile trace (optional)

image

Prerequisites

Before implementing, ensure:

1. Instana Mobile SDK is integrated in your app
2. Website Monitoring script is installed on web pages loaded in WebView:

<script>
  (function(s,t,a,n){s[t]||(s[t]=a,n=s[a]=function(){n.q.push(arguments)},
  n.q=[],n.v=2,n.l=1*new Date)})(window,"InstanaEumObject","ineum");
  ineum('reportingUrl', 'https://<eum-your-region>.instana.io');
  ineum('key', 'your-website-monitoring-key');
  ineum('trackSessions');
</script>
<script async src="https://eum-your-region.instana.io/eum.min.js"></script>

The `ineum` object must be available globally for session correlation to work.

Implementation

Complete Android implementation

class WebViewActivity : AppCompatActivity() {

    private lateinit var webView: WebView
    
    /**
     * Retrieves the current Instana mobile session ID
     * This ID will be used to correlate mobile and web sessions
     * Returns "unknown" if session ID is not available
     */
    private fun getInstanaSessionId(): String {
        return Instana.sessionId ?: "unknown"
    }
    
    /**
     * Generates JavaScript code to inject the mobile session ID into the web context
     * This script:
     * 1. Checks if the Instana EUM agent (ineum) is loaded on the web page
     * 2. If available, sets the mobile session ID as metadata using ineum('meta', ...)
     * 3. This metadata will be attached to all web beacons sent from the WebView
     * 4. Logs a warning if the EUM agent is not found
     */
    private fun getInjectedScript(): String {
        val sessionId = getInstanaSessionId()
        return """
            (function() {
                if (typeof ineum !== 'undefined') {
                    ineum('meta', 'mobile_sessionId', '$sessionId');
                } else {
                    console.warn('Instana EUM agent (ineum) not found');
                }
            })();
        """
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_webview)
        webView = findViewById(R.id.webView)
        
        /**
         * Build the Instana dashboard URL that filters web beacons by mobile session ID
         * This URL structure:
         * - Points to the Website Monitoring beacon analysis page
         * - Filters for pageLoad beacons
         * - Uses tagFilterExpression to match beacons where beacon.meta[mobile_sessionId] equals our mobile session ID
         * - When opened, shows all web activity correlated to this mobile session
         */
        val domain = "https://<your-instana-instance>.instana.io"
        val instanaUrl = "$domain/#/websiteMonitoring/analyzeBeacons;" +
            "beaconType=pageLoad;" +
            "groupBy=()~;" +
            "tagFilterExpression=!(type~TAG*_FILTER~name~beacon.meta~operator~EQUALS~key~mobile_sessionId~value~*${Instana.sessionId}"
        
        /**
         * Report a custom event to make this session searchable
         * Benefits:
         * - Appears in the mobile session timeline
         * - Searchable by event name "WebUrl"
         * - Metadata contains the correlation URL for easy access
         * - Helps identify which mobile sessions have WebView activity
         */
        val myEvent = CustomEvent("WebUrl").apply {
            meta = mapOf("WebUrlEvent" to instanaUrl)
        }
        Instana.reportEvent(myEvent)

        // Configure WebView settings and behavior
        setupWebView()
        
        /**
         * Create an HTTP marker for one-click navigation
         * This creates a fake HTTP call in the mobile trace that:
         * - Shows up as a GET request in the mobile session
         * - URL is the Instana dashboard correlation link
         * - Clicking it navigates directly to the correlated web session
         * - Provides the fastest way to jump from mobile to web data
         */
        val marker = Instana.startCapture(instanaUrl)
        val httpMarkerData = HTTPMarkerData(
            requestMethod = "GET",
            responseStatusCode = 200  // Simulate successful request
        )
        marker?.finish(httpMarkerData)
        
        // Load the actual web content into the WebView
        webView.loadUrl("https://your-web-content.com")
    }

    /**
     * Configures WebView settings and sets up the WebViewClient
     * Key configurations:
     * - Enables JavaScript (required for Instana EUM agent and session injection)
     * - Enables DOM storage (required for web monitoring)
     * - Sets up page lifecycle callbacks for session ID injection
     */
    @SuppressLint("SetJavaScriptEnabled")
    private fun setupWebView() {
        webView.settings.apply {
            javaScriptEnabled = true      // Required for Instana monitoring and injection
            domStorageEnabled = true      // Required for web session tracking
        }

        webView.webViewClient = object : WebViewClient() {
            /**
             * Called when a page starts loading
             * This is the critical timing point - we inject the session ID here to ensure:
             * 1. The injection happens before the page fully loads
             * 2. The session ID is available when the EUM agent initializes
             * 3. All beacons sent from this page will include the mobile session ID
             */
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
                // Inject the mobile session ID into the web context
                injectJavaScript(getInjectedScript())
            }
        }
    }

    /**
     * Executes JavaScript code in the WebView context
     * Uses evaluateJavascript for modern Android versions (API 19+)
     * The result callback can be used to verify injection success
     */
    private fun injectJavaScript(script: String) {
        webView.evaluateJavascript(script) { result ->
            // Optional: Log or handle the result of the injection
            // Result will be "undefined" for successful meta setting
        }
    }

    /**
     * Clean up WebView resources when activity is destroyed
     * Important to prevent memory leaks
     */
    override fun onDestroy() {
        webView.destroy()
        super.onDestroy()
    }
}

Key Implementation Points

  1. Session ID Injection
    ineum('meta', 'mobile_sessionId', '$sessionId');
    This adds the mobile session ID as metadata to all web beacons, enabling correlation.

  2. Dashboard URL Construction
    val instanaUrl = "$domain/#/websiteMonitoring/analyzeBeacons;" +
    "beaconType=pageLoad;" +
    "tagFilterExpression=!(type~TAG*_FILTER~name~beacon.meta~operator~EQUALS~key~mobile_sessionId~value~*${Instana.sessionId}"
    This URL filters Website Monitoring beacons by the mobile session ID.

  3. Timing

    Inject in `onPageStarted()` to ensure the session ID is set before beacons are sent.

    Session Correlation


    Dashboard URL Parameters

    https://your-instana-instance.instana.io/#/websiteMonitoring/analyzeBeacons;beaconType=pageLoad;tagFilterExpression=!(type~TAG*_FILTER~name~beacon.meta~operator~EQUALS~key~mobile_sessionId~value~*YOUR_SESSION_ID

    Add 7-Day Timeline

    Append the following string to the end of the dashboard URL to view beacon correlation for the past 7 days

    ?timeline.ws=604800000&timeline.to&timeline.fm&timeline.ar=false

    Parameters:

    - `timeline.ws=604800000`: Window size (7 days in milliseconds)
    - `timeline.to`: Current time (empty = now)
    - `timeline.ar=false`: Disable auto-refresh

    Common window sizes:

    - 1 hour: `3600000`
    - 24 hours: `86400000`
    - 7 days: `604800000`

    Accessing Correlated Data

    Method 1: From Custom Event

    1. Open mobile session
    2. Find `WebUrl` event in timeline
    3. Copy URL from event metadata

    You will have to copy paste this URL to a new tab

    Method 2: From HTTP Marker (One-Click)

    1. Open mobile session
    2. Find GET request to dashboard URL
    3. Click to navigate directly

    As you added a fake http call you can go to website details in a single click (opens a new tab)

    Filtering Strategies

    Find All WebView Sessions (In Mobile Monitoring:)
    Filter: Event Name = “WebUrl”
    Filter: HTTP URL contains “your-instana-instance.instana.io”

    Grouping or filtering will bring in the origin related to the WebView in mobile app

    This will give the custom event based grouping, giving the single view for web in mobile

    Find Specific Correlated Session (In Website Monitoring:)

    Filter: beacon.meta.mobile_sessionId = YOUR_MOBILE_SESSION_ID

    All web sessions started from mobile grouped

    iOS Implementation Key Differences:

    - Use `WKWebView` instead of Android’s `WebView`
    - Use `evaluateJavaScript(_:completionHandler:)` for script injection
    - Use `WKNavigationDelegate` for page lifecycle events

    Known Limitations

    iFrames and Nested WebViews: Session ID injection only works for top-level WebView content. iFrames run in separate JavaScript contexts and won’t automatically receive the session ID. Use `postMessage` API or inject the EUM script separately in each iFrame if correlation is needed.

    Unified Dashboard: Mobile and web metrics exist in separate data streams and cannot be displayed together in a single dashboard without custom configuration. You’ll need to create custom dashboards using meta values (`beacon.meta`) to merge mobile and web data, or navigate between views using the HTTP marker links.

    Conclusion

    This integration approach bridges Instana’s Mobile SDK and Website Monitoring to provide:

    ✅ Complete end-to-end visibility across native and web layers
    ✅ Unified session correlation for faster troubleshooting
    ✅ Multiple access methods (metadata, events, HTTP markers)
    ✅ Flexible filtering and navigation options


    Explore More:
    - Monitoring Mobile Application With Instana 
    - Monitoring Website Application With Instana
    - Read in Medium




#EUM
#Ideas
#Mobile
#CaseStudy
#Demo

0 comments
13 views

Permalink