From bd30f42b0f0605e2b7a8c4a0fb70d561c5d2d267 Mon Sep 17 00:00:00 2001 From: nimishgj Date: Wed, 5 Aug 2026 09:44:43 +0530 Subject: [PATCH] update use of MetricKit in mobile instrumentation docs --- docs/instrument/mobile/android.md | 14 ++++------- docs/instrument/mobile/hybrid.md | 14 +++++------ docs/instrument/mobile/ios.md | 14 ++++------- .../instrument/mobile/kotlin-multiplatform.md | 25 ++++++++----------- 4 files changed, 27 insertions(+), 40 deletions(-) diff --git a/docs/instrument/mobile/android.md b/docs/instrument/mobile/android.md index bffcb8f..0fb6d28 100644 --- a/docs/instrument/mobile/android.md +++ b/docs/instrument/mobile/android.md @@ -285,15 +285,11 @@ at-most-once delivery). | Field | Type | Default | Description | |---|---|---|---| | `offlineBufferEnabled` | `Boolean` | `false` | Master toggle. Persist failed batches and replay them on next `initialize()` or connectivity change. | -| `offlineMaxTraceItems` | `Int` | `0` | Accepted, not yet enforced. | -| `offlineMaxMetricItems` | `Int` | `0` | Accepted, not yet enforced. | -| `offlineMaxLogItems` | `Int` | `0` | Accepted, not yet enforced. | -| `maxOfflineStorageMb` | `Int` | `5` | Accepted, not yet enforced. | - -The four cap fields are part of the config surface but nothing reads -them yet. When `offlineBufferEnabled` is on, the persisted queue is -bounded by `maxQueueSize` and `maxExportBatchSize` — the same limits the -in-memory path uses. Size the buffer with those. +| `maxOfflineStorageMb` | `Int` | `5` | Cap on the on-disk offline buffer. Once it is exceeded, the oldest persisted batches are pruned first (FIFO). Only active when `offlineBufferEnabled` is on. | + +When `offlineBufferEnabled` is on, the persisted queue is also bounded by +`maxQueueSize` and `maxExportBatchSize` — the same limits the in-memory +path uses. ### Diagnostics diff --git a/docs/instrument/mobile/hybrid.md b/docs/instrument/mobile/hybrid.md index 808d569..69217b0 100644 --- a/docs/instrument/mobile/hybrid.md +++ b/docs/instrument/mobile/hybrid.md @@ -37,7 +37,7 @@ detects the native SDK and delegates to it, and both layers report under one | Export pipeline | Native | Flutter forwards spans, logs, and metrics over the bridge. Same-process, one exporter for both layers; different-process, one per process | | Breadcrumbs, user and session attributes | Shared | Set on either side, visible to both | | Native Android telemetry | `scout-android` | Screens, taps, HTTP, JVM and NDK crashes, ANR, jank, vitals. See [Android](./android.md) | -| Native iOS telemetry | Bridge engine | Screens, KSCrash native crashes, app hangs, HTTP, jank, vitals. Taps, startup tracking, and MetricKit are off in bridge mode | +| Native iOS telemetry | Bridge engine | Screens, KSCrash native crashes, app hangs, MetricKit diagnostics, HTTP, jank, vitals. Taps and startup tracking are off in bridge mode | | Flutter telemetry | `scout_flutter` | Screens, taps, HTTP, errors, and jank from the Flutter layer, forwarded to the native side. See [Flutter](./flutter.md) | | Crash de-duplication | Native | In hybrid mode `scout_flutter` drains and discards its own crash files, so a crash is reported once | @@ -341,16 +341,14 @@ func presentFlutter() { :::note What bridge mode leaves out on iOS The engine `scout_flutter` starts for you covers sessions, screen views, -KSCrash native crashes, app hangs, HTTP, jank, and vitals on the native side. -Three things are off in bridge mode: +KSCrash native crashes, app hangs, MetricKit `MXCrashDiagnostic` / +`MXHangDiagnostic` diagnostics, HTTP, jank, and vitals on the native side. +Two things are off in bridge mode: - Tap tracking (`enableTapTracking` defaults to `false`). - Startup and cold-start tracking (`enableStartupTracking` defaults to `false`). -- MetricKit diagnostics. `Scout.startBridge` does not subscribe - `MetricKitSubscriber`, so `MXCrashDiagnostic` and `MXHangDiagnostic` reports - never arrive. KSCrash still captures native crashes in-process. -To get all three, call `Scout.start(...)` yourself in +To get both, call `Scout.start(...)` yourself in `application(_:didFinishLaunchingWithOptions:)` **before** `flutterEngine.run()`, using the same `serviceName` and `endpoint` as the Flutter config. The engine is a first-wins singleton: whichever of `Scout.start` and the plugin's @@ -385,7 +383,7 @@ Calling `Scout.start` after Flutter has started has no effect. See | **`main()` throws on startup** before any telemetry appears | `ScoutFlutter.initialize` reaches the native side over a platform channel, which needs the binding | Call `WidgetsFlutterBinding.ensureInitialized()` as the first line of `main()`. | | **Flutter data lands but under a different `session.id`** than native (not unified) | Different-process only: `role` was set to `ScoutRole.OWNER`, so the `:flutter` process skipped the cross-process lookup and minted its own session | Leave `role` at its `ScoutRole.AUTO` default. Same-process is unaffected. | | **Native screens/events don't appear on Android** | The native SDK was never initialized | Call `Scout.initialize` in `Application.onCreate`. | -| **No native taps, cold-start spans, or MetricKit reports on iOS** | Bridge mode leaves tap tracking, startup tracking, and the MetricKit subscriber off | Call `Scout.start(...)` in `application(_:didFinishLaunchingWithOptions:)` before `flutterEngine.run()`. Screens, KSCrash crashes, and hangs are already covered without it. | +| **No native taps or cold-start spans on iOS** | Bridge mode leaves tap tracking and startup tracking off | Call `Scout.start(...)` in `application(_:didFinishLaunchingWithOptions:)` before `flutterEngine.run()`. Screens, KSCrash crashes, hangs, and MetricKit diagnostics are already covered without it. | ## FAQ diff --git a/docs/instrument/mobile/ios.md b/docs/instrument/mobile/ios.md index 258ed2f..bbdf70b 100644 --- a/docs/instrument/mobile/ios.md +++ b/docs/instrument/mobile/ios.md @@ -285,15 +285,11 @@ at-most-once delivery). | Parameter | Type | Default | Description | |---|---|---|---| | `offlineBufferEnabled` | `Bool` | `false` | Master toggle. Persist failed batches and replay them on the next launch. | -| `offlineMaxTraceItems` | `Int` | `0` | Accepted, not yet enforced. | -| `offlineMaxMetricItems` | `Int` | `0` | Accepted, not yet enforced. | -| `offlineMaxLogItems` | `Int` | `0` | Accepted, not yet enforced. | -| `maxOfflineStorageMb` | `Int` | `5` | Accepted, not yet enforced. | - -The four cap parameters are part of the config surface but nothing reads -them yet. When `offlineBufferEnabled` is on, the persisted queue is -bounded by `maxQueueSize` and `maxExportBatchSize` — the same limits the -in-memory path uses. Size the buffer with those. +| `maxOfflineStorageMb` | `Int` | `5` | Cap on the on-disk offline buffer. Once it is exceeded, the oldest persisted batches are pruned first (FIFO). Only active when `offlineBufferEnabled` is on. | + +When `offlineBufferEnabled` is on, the persisted queue is also bounded by +`maxQueueSize` and `maxExportBatchSize` — the same limits the in-memory +path uses. ### Diagnostics diff --git a/docs/instrument/mobile/kotlin-multiplatform.md b/docs/instrument/mobile/kotlin-multiplatform.md index 94f82ee..0d33569 100644 --- a/docs/instrument/mobile/kotlin-multiplatform.md +++ b/docs/instrument/mobile/kotlin-multiplatform.md @@ -52,9 +52,8 @@ capabilities** documented for each platform, driven from common code: set: Activity/Compose screens, taps, JVM + NDK crashes, `ApplicationExitInfo`, ANR, jank, startup, lifecycle, HTTP. - **iOS** — the [scout-ios](/instrument/mobile/ios) set: screens, taps, - KSCrash native crashes, app hangs, jank, startup, lifecycle, HTTP. One - exception: MetricKit is not subscribed on the KMP path (see the - [FAQ](#faq)). + KSCrash native crashes, app hangs, jank, startup, lifecycle, HTTP, and + MetricKit `MXCrashDiagnostic` / `MXHangDiagnostic` diagnostics. Every signal flows through the shared `scout-core` engine — the same sessions, sampling, batching, and OTLP export on both platforms. Each @@ -271,11 +270,11 @@ instrumentation defaults to **on**; metric collection defaults to ### Offline buffer Disabled by default (strict at-most-once). `offlineBufferEnabled` -(`false`) is the master toggle. The cap fields `offlineMaxTraceItems` / -`offlineMaxMetricItems` / `offlineMaxLogItems` (`0`) and -`maxOfflineStorageMb` (`5`) are part of the config surface but nothing -reads them yet — when the buffer is on, the persisted queue is bounded -by `maxQueueSize` and `maxExportBatchSize` instead. +(`false`) is the master toggle. When the buffer is on, +`maxOfflineStorageMb` (`5`) caps the on-disk buffer — once the cap is +exceeded the oldest persisted batches are pruned first (FIFO) — and the +persisted queue is additionally bounded by `maxQueueSize` and +`maxExportBatchSize`. ### Diagnostics @@ -371,7 +370,6 @@ status to the platform console. | Crashes not appearing | They drain on the *next* launch on both platforms. Relaunch, then check the collector. | | Telemetry hard to distinguish from native SDK data | KMP exports carry a `scout.kmp.version` resource attribute — filter on it. | | No telemetry at all | Set `debugLogging = true` to print export attempts and their HTTP status, then confirm the endpoint is reachable from the device. Remember the default `sessionSampleRate` is **1%**. | -| No MetricKit diagnostics on iOS | Expected. The KMP path does not install the MetricKit subscriber — see the FAQ below. | ## Performance considerations @@ -409,11 +407,10 @@ transitively at the versions listed under No. `scout-kmp` calls the Kotlin engine (`ScoutEngine`) directly rather than the Swift `Scout.start(...)` entry point. KSCrash still installs, -and ANR detection still runs — but from the Kotlin watchdog, gated by -`enableAnrTracking`, instead of the Swift `AppHangWatchdog`. The -practical difference is that **MetricKit is not subscribed on the KMP -path**, so Apple's asynchronous `MXCrashDiagnostic` / `MXHangDiagnostic` -payloads are not collected. Everything else in the +ANR detection still runs — from the Kotlin watchdog, gated by +`enableAnrTracking`, instead of the Swift `AppHangWatchdog` — and the +engine subscribes to MetricKit, so Apple's asynchronous +`MXCrashDiagnostic` / `MXHangDiagnostic` payloads are collected. The full [iOS](/instrument/mobile/ios) capability table applies. **How do I track screens in a Compose Multiplatform app?**