Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions docs/instrument/mobile/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
14 changes: 6 additions & 8 deletions docs/instrument/mobile/hybrid.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
14 changes: 5 additions & 9 deletions docs/instrument/mobile/ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
25 changes: 11 additions & 14 deletions docs/instrument/mobile/kotlin-multiplatform.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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?**
Expand Down
Loading