Skip to content
Last9
Book demo

RUM Changelog

New instrumentation, config options, and fixes for Last9's Web, Android, iOS, React Native, and Flutter RUM SDKs, by version.

Release notes for all five RUM SDKs. See Distribution for CDN links and versioned URLs.

Current stable releases

PlatformStable channelVersion
Webstable/v22.9.0
Androidstable/v11.8.0
iOSstable/v11.8.0
React Nativestable/v11.8.0
Flutterstable/v11.8.0

Stable channels are major-version pinned. Web stable/v2 currently serves 2.9.0. Mobile stable/v1 currently serves 1.8.0, which is also the latest versioned mobile release. Pin versioned CDN URLs from Distribution for the iOS Swift Package Manager Git URL, reproducible lockfiles, or an exact artifact checksum.

Each platform section below is ordered newest first. Entries marked stable are served by the corresponding stable channel.

Web

v2.9.0 (2026-09-24) · stable

Add session.start_time to every span. Every span now carries session.start_time (epoch ms, integer) alongside session.id, read from the session store. The backend can read the real start time of a session from any span, also from a span outside the selected time range.

  • Fixed the Session Start span. The SDK created it before it stored the new session id, so it carried no session.id (first load) or the id of the old session (rollover). It now carries the session.id and session.start_time of the new session. session.previous_id is unchanged.
  • A Browser RUM instance that runs inside a native WebView and adopts the native session does not set session.start_time. The native-context bridge does not send a start time, and the SDK does not invent a value.

Backdate rollover Session End to last activity. When a session ends because of an inactivity timeout or a max-duration rollover, the Session End timestamp and session.time_spent now use the last recorded activity of the session, not the time the SDK detected the rollover. Idle and background time is no longer counted. exit ends are unchanged.

  • The rollover end stays between the session start and the current time. A system-clock change can no longer put Session End before Session Start or make session.time_spent negative. The native SDKs already apply the same limit.

v2.8.4 (2026-09-21)

Protect sensitive fields in all interaction handlers. Click, focus, keyboard, input, and touch interaction spans now skip sensitive input and textarea fields before they extract field metadata. Sensitive field names, labels, selectors, and other structural metadata are not exported.

v2.8.3 (2026-09-21)

Redact compound email field names in input interactions. Input interactions now treat text-entry fields whose name, id, or aria-label contains email as sensitive. This includes names such as useremail, emailfield, emailaddress, and primaryemail.

  • Email notification checkboxes and radio buttons stay trackable, so settings controls such as email_notifications_enabled are not redacted.

v2.8.2 (2026-09-21)

Fix attribute deletion in beforeSend. errors.beforeSend now honors attributes that the hook deletes. Before this fix, a key removed with delete event.attributes["exception.stacktrace"] came back from the original attributes and was still sent on the trace span event and on the OTel log record.

  • Redaction that removes sensitive attributes (stack traces, messages that contain PII or tokens) now works as documented. Added and changed attributes behave as before.

v2.8.1 (2026-09-21)

clientToken always wins over a colliding X-LAST9-API-TOKEN header. The exporter now writes the reserved X-LAST9-API-TOKEN header after the other entries in headers. Before this fix, an X-LAST9-API-TOKEN entry in config.headers silently replaced clientToken, which caused ingest auth failures and dropped exports.

v2.8.0 (2026-08-12)

Fold dynamic segments in network span names. Network span names now fold fully-numeric and UUID path segments to ? (e.g. GET /workspaces/1 → GET /workspaces/?), so per-endpoint metrics aggregate instead of exploding by id. Uses the same rule as view naming; version-like segments such as v2 are preserved.

  • Behavior change: the emitted span_name for fetch/XHR/resource spans changes. The full raw URL remains on http.url. GraphQL span names (operation-based) are unaffected.

v2.7.1 (2026-08-10)

Disable browser bundle source maps. Production ESM and UMD bundles no longer emit source map files.

v2.7.0 (2026-07-14)

Add GraphQL network observability

  • Automatically enriches GraphQL fetch/XHR spans from the request body. No GraphQL client dependency or setup required.
  • Descriptive span names, e.g. GraphQL: "GetUser" query (anonymous operations become GraphQL: query).
  • Sets graphql.operation.name and graphql.operation.type, and tags the span with l9.span.category=network.
  • Detects GraphQL errors[] on HTTP 200 responses (error.type=GraphQLError, graphql.error.count).
  • Detection is body-driven, so plain REST requests are never misclassified. Request bodies are scanned up to 256KB, response bodies up to 64KB.

v2.6.1 (2026-07-09)

recordCustomEvent no longer auto-creates a view span. If there’s no active view span when a custom event fires, no view span is fabricated to attach it to. The span event is dropped in that case, but the log is still emitted unconditionally (as an orphan, omitting trace.id/span.id/view.id). Aligns Web with the same orphan-log rule used by the mobile SDKs.

v2.6.0 (2026-07-07)

Add propagateTraceHeaders to disable trace context injection. network.backendCorrelation.propagateTraceHeaders (default true). Set to false to stop injecting traceparent, tracestate, and B3 headers on outgoing requests while keeping network span collection and baggage propagation.

L9RUM.init({
network: {
backendCorrelation: {
enabled: true,
propagateTraceHeaders: false,
},
},
});

v2.5.1 (2026-06-02)

Fix unknown browser RUM error types. Infers exception.type for non-Error throws and rejections (strings, primitives, plain objects), preserves explicit error names, and safely handles malformed error payloads in global error listeners.

v2.5.0 (2026-05-13)

Add native WebView session correlation. Browser RUM picks up a native-provided window.__LAST9_RUM_NATIVE_CONTEXT and uses the native session.id, so WebView spans correlate with the host mobile app’s spans. WebView spans are stamped with native.view.id and view.type=webview.

v2.4.0 (2026-05-04)

Add geoAttributesOverride. Set enduser.geo.* resource attributes explicitly; overrides win over auto-detected values including IP-based geolocation.

L9RUM.init({
geoAttributesOverride: {
country: "India",
country_code: "IN",
city: "Bangalore",
},
});

v2.3.0 (2026-04-27)

Comprehensive browser performance metrics. For parity with industry-standard RUM tooling:

  • Full Navigation Timing breakdown (document.dom_processing_time, dom_interactive_time, page_rendering_time, page_load_time, plus dns_time/tcp_time/ssl_time/request_time/response_time)
  • Long task tracking (longtask.blocking_time, longtask.total_blocking_time, attribution data)
  • Browser/device network context (network.effective_type, downlink, rtt, save_data)
  • Extended Core Web Vitals attribution for LCP, CLS, INP, FCP
  • Resource timing enhancements (resource.render_blocking, transfer/encoded/decoded body sizes)

v2.2.0 (2026-03-16)

Add isolateTracePerRequest. Each outgoing fetch/XHR request can propagate its own unique traceId instead of sharing the view’s root span traceId, so backends can correlate logs/traces to the exact request. session.id/view.id are added to baggage automatically so requests can still be grouped by session and view.

v2.1.0 (2026-02-06)

Add W3C Baggage propagation for custom attribute forwarding. Propagate whitelisted global span attributes to backend services via W3C Baggage headers, so a backend can read attributes like tenant.id or a caller-supplied session identifier off the baggage header. Includes percent-encoding, a configurable size limit (default 8192 bytes per the W3C recommendation), and URL pattern filtering via trackedUrls. Never whitelist sensitive data (tokens, passwords, PII).

v2.0.28 – v2.0.37 (2026-01 – 2026-02)

Earlier hardening and coexistence fixes, squashed:

  • forceOverwrite option so Last9 can take ownership of traceparent while preserving other vendors’ tracestate entries when multiple RUM/APM libraries run on the same page.
  • Backend-correlation header fixes when another RUM SDK on the page registers its own global propagator or patches fetch/XMLHttpRequest.
  • Sessions persisted to localStorage (shared across tabs) with a 30-minute inactivity timeout alongside the existing 4-hour max duration; sampling decisions persisted the same way.
  • view.name auto-generated from the URL path when not set explicitly, with dynamic segment normalization (/user/12345/profile → /user/?/profile).
  • geoIpEnabled added. Geolocation enrichment is off by default to avoid collecting location metadata without consent.
  • Removed deprecated unload listeners in favor of visibilitychange/pagehide/freeze/beforeunload.

Android

v1.8.0 (2026-09-24) · stable

Add session.start_time to every span. Every span now carries session.start_time (epoch ms) alongside session.id, read from the active session. The backend can read the real start time of a session from any span.

  • The Session Start span, the Session End span, and the process-death tombstone spans (Session End and View) carry the start time of the session they belong to. The tombstone carries the start time of the dead session, not of the new one.
  • No API change.

Backdate rollover Session End to last activity. When a session ends because of an inactivity timeout or a max-duration rollover, the Session End timestamp and session.time_spent now use the last recorded activity of the session, not the time the SDK detected the rollover. Idle and background time is no longer counted. exit, shutdown, and process_death ends are unchanged.

Keep session.previous_id across in-process rollovers. An in-process rollover no longer drops session.previous_id on the new session. The SDK now captures the id of the ending session before it clears the persisted session store. No API change.

v1.7.3 (2026-09-21)

Fix: Java span attributes tolerate null map entries. L9Rum.spanAttributes() now drops null keys and null values from Java maps instead of throwing a NullPointerException. Valid entries in the same map are still applied. No API change.

v1.7.2 (2026-09-21)

Fix: shutdown() keeps crash reporters installed after Last9. shutdown() no longer restores the uncaught-exception handler that was active before Last9 when another crash reporter installed itself after Last9. The third-party reporter stays installed. No API change.

v1.7.1 (2026-09-21)

Version parity. No functional Android changes; released in lockstep with the React Native fractional sampleRate bridge fix.

v1.7.0 (2026-09-16)

Per-view refresh rate and memory vitals. When resourceMonitoringEnabled is on (the default), each View span now carries per-view performance vitals. view.refresh_rate_average / view.refresh_rate_min are normalized to 0–60 Hz, so 60 Hz and 120 Hz devices compare directly. view.frame.slow counts frames whose inter-vsync interval exceeds 1.5× the display refresh period — a skipped vsync — and view.frame.frozen counts frames over 700 ms. view.memory_average / view.memory_max carry resident-set-size bytes, and process.cpu.usage is averaged over the view.

  • Frame timing comes from a Choreographer frame-rate tracker. Per-view memory is sampled (RSS) at each view start and end, so short screens still get coverage alongside the periodic resource.sample span. Frame tracking pauses while backgrounded, so a background gap is never counted as a frozen frame.
  • resource.sample spans now also carry process.memory.pss (proportional set size); the per-view view.memory_* rollup uses RSS.
  • No API change — gated by the existing resourceMonitoringEnabled flag.

v1.6.12 (2026-09-16)

Fix late-initialization cold-start durations. The SDK can initialize after the launch Activity is already resumed — for example React Native / Flutter initialize() running after native startup. A later background return no longer reports the entire prior process lifetime as a multi-minute cold start. An unbalanced onActivityStopped is now treated as proof of late init: the next foreground classifies as hot (or warm when the Activity was recreated), measured from foreground entry — not from process creation. Genuine early-initialization cold starts are unchanged.

v1.6.11 (2026-09-09)

Fix WebView-host container mislabeled view.type=webview. instrument(webView) no longer stamps view.type=webview / native.view.id on the active native view, so a persistent container that merely hosts a WebView (for example a tab-bar host) is no longer mislabeled. Views that genuinely display WebView content in place still carry view.type=webview.

v1.6.10 (2026-09-08)

Fix spurious session split near the inactivity boundary. The inactivity / max-duration rollover timer re-checks the session against both thresholds before it rolls over. A timer that fires just after fresh activity pushed the deadline out no longer splits an active session.

v1.6.9 (2026-08-31)

WebView view rotation, session-preserving flush(), and killed-view recovery.

  • flush() now exports pending views/spans/logs without ending or restarting the session — login and foreground handlers that call flush() no longer emit session.end_reason=flush or a new session.id. shutdown() still ends the session.
  • Session rollover (inactivity / max-duration) ends the in-flight View span before emitting Session End, so the open page exports on the ending session instead of leaking into the next.
  • The first committed WebView main-frame URL rotates to a dedicated view.type=webview page view; a resumed WebView folds its URL onto the Activity view instead of creating an extra WebViewActivity. A WebView URL that populates only after restoreState is picked up via a one-shot deferred re-check.
  • On SIGKILL / force-stop / jetsam the open view is snapshotted durably. The next cold start re-emits it as a backdated View span, so the dead session still shows its last page.

v1.6.8 (2026-08-31)

Fix hidden WebViews suppressing the visible URL. Hidden or transparent preloaded WebViews are excluded from shared-host URL ownership, so they no longer clear or overwrite the visible WebView’s URL-derived view.

v1.6.7 (2026-08-28)

Version parity release. No functional Android changes. Released in lockstep with the iOS streamed request-body fix.

v1.6.6 (2026-08-27)

Fix resumed WebViews losing their URL-derived view. A WebView that survives an Activity resume now resets URL dedup when it moves to a new native host. The new WebViewActivity span therefore keeps view.url, view.type, and its URL-derived name.

v1.6.5 (2026-08-26)

Version parity release. No functional Android changes. Released in lockstep with the iOS WebView lifecycle fix.

v1.6.4 (2026-08-26)

Fix minified (R8) release builds. Apps with minifyEnabled = true no longer fail R8 with Missing class io.opentelemetry.api.incubator.*. The AAR’s consumer-rules.pro now ships -dontwarn io.opentelemetry.api.incubator.**, so consumers need no app-side ProGuard change.

v1.6.3 (2026-08-25)

Version parity release. No functional Android changes; added batch-export regression coverage. Moves in lockstep with the iOS WebView lifecycle fix.

v1.6.2 (2026-08-24)

Each WebView page becomes its own view (per-navigation view rotation). Every committed WebView main-frame navigation now rotates the native view span. The current view ends and a fresh view.type=webview view starts, named by the URL and carrying view.url, the folded app.screen.name, its own native.view.id, and previous_url. Each page a WebView visits — including cross-origin pages the in-page Browser SDK cannot capture — becomes a first-class view. The first committed URL names the existing view; query-only changes and shared hosts (2+ WebViews) do not rotate.

  • Breaking: this replaces the webview_page_load span event — dashboards or alerts querying that event name should switch to the new view.type=webview view events.

v1.6.1 (2026-08-24)

Fix rapid repeated addEvent dropping span events past 128. The tracer now configures SpanLimits at 2048 events per span and 256 attributes per event, up from OpenTelemetry-Java’s default of 128. High-frequency custom events on a long-lived view span are no longer silently discarded from the exported span. The uncapped OTLP log remains the source of truth for extreme bursts.

v1.6.0 (2026-08-21)

Auto-name WebView-hosted views from the current URL. A WebView-hosted view (instrumented via instrument(webView) / getWebViewInjectedJavaScript(), tagged view.type=webview) is now auto-named from the current main-frame URL: app.screen.name is the folded pathname (e.g. https://www.example.com/health-record?webViewFrame=edgeToEdge → /health-record) instead of the host Activity class name. Numeric/UUID path segments fold to ? (e.g. /order/12345 → /order/?). The full URL (scheme, host, path, and query) is recorded on view.url.

  • Fires on both full loads (WebViewClient.onPageStarted) and in-WebView main-frame history changes (doUpdateVisitedHistory).
  • An explicit startView / setViewName still wins — the URL-derived name never overwrites an app-provided one. view.url is still recorded either way.
  • Scoped to WebView-hosted views. Normal native (class-named) view names are unchanged.

v1.5.2 (2026-08-21)

Fix: addEvent during a view’s teardown attaches to that view, not the next one. A custom event fired while screen A is being torn down now lands on A, not on the next screen B. Previously the Android sequence A.onPause (ends A’s view) → B.onResume (starts B) → A.onDestroy (addEvent) attached the event to B — or dropped it as an orphan log without view.id in the pause→resume gap.

  • On view end the just-ended view is kept for a 1000 ms grace window (span.end() is deferred but ended with its logical timestamp, so view.time_spent is unchanged). During the window addEvent attaches to the just-ended view even if the next view is already current; after it, and whenever there is no current view, the OTLP log still correlates to the last view for the rest of the session.
  • A manual startView(...) still ends the previous view immediately. Network and TTFD correlation still follow the current view only.
  • Prefer firing screen summaries in onPause (Activity) / onDestroyView or onPause (Fragment) rather than onDestroy.

v1.5.1 (2026-08-20)

Version parity release. No functional Android changes. Released in lockstep with the iOS SDK’s new Swift Package Manager distribution.

v1.5.0 (2026-08-20)

autoViewTrackingEnabled + no duplicate native views from startView. Added L9RumConfig.autoViewTrackingEnabled (default true). When false, Activity resume/pause no longer opens or closes view spans — the app owns view names entirely via startView / setViewName. Startup, session, and lifecycle spans are unaffected.

  • Mixing a manual startView/setViewName with Activity auto-tracking no longer creates a duplicate native view: a manual view is not overwritten by an auto view on the next resume, and pausing the host Activity no longer ends a manual view.
  • setViewName renames the current auto-tracked view in place (app.screen.name) with no extra span — the recommended way to name a WebView host Activity alongside instrument(webView).
  • Fixed a view.type=webview / native.view.id leak: WebView re-injection no longer re-marks the now-active view as a WebView host. Only the view live when instrument(webView) / getWebViewInjectedJavaScript() is called is tagged.

v1.4.1 (2026-08-19)

Keep the session alive on Home / background. Backgrounding the app — Home button, or leaving for a system file picker — no longer ends the RUM session. Returning within the 30-minute inactivity window resumes the same session, so later events keep their session.id. Rollover still happens on inactivity timeout, max duration, or shutdown().

Backfill Session End for killed sessions on next launch. A swipe-from-Recents, crash, or OS kill terminates the process with no guaranteed teardown, so no Session End is emitted at that moment. On the next cold start, if an orphaned persisted session is found, the SDK backfills that session’s Session End span — backdated to last activity, with session.end_reason=process_death — then starts a fresh session chained via session.previous_id. A same-process re-init (for example a React Native JS reload) still restores the in-window session.

v1.4.0 (2026-08-18)

Configurable batch export schedule delay. Added scheduleDelayMs to L9RumConfig — how long the batch span and log processors wait before flushing queued telemetry (previously the OTel Java default of 5s). When unset: 5000 ms in production, and 1000 ms when debugLogs is true, so a single addEvent becomes visible within ~1s during development. View span events still export only when the view span ends; the lower debug delay speeds up the dual-emitted custom-event logs.

v1.3.0 (2026-08-12)

Fold dynamic segments in network span names. Network span names fold fully-numeric and UUID path segments to ? (e.g. GET /workspaces/1 → GET /workspaces/?). Applies to OkHttp auto-instrumentation and bridged (startNetworkSpan) spans; version-like segments such as v2 are preserved. The raw URL remains on url.full. GraphQL span names are unaffected. A spanNameOverride or span hook still overrides the folded name.

v1.2.1 (2026-08-10)

Version parity release. No functional Android changes. Version bumped to 1.2.1 to keep all mobile SDKs at the same version; this release carries an iOS fix for a main-thread deadlock in WebView instrumentation (instrument(webView:)).

v1.2.0 (2026-07-30)

Version parity release. No functional Android changes. Version bumped to 1.2.0 to keep all mobile SDKs at the same version; this release carries the new React Native Expo config plugin.

v1.1.10 (2026-07-31)

Version parity release. Bumped to 1.1.10 to keep all mobile SDKs and bridge dependencies at parity for the React Native 1.1.10 release, which fixes a New Architecture Android clean-build failure (:app:configureCMakeDebug missing the generated codegen JNI directory).

v1.1.9 (2026-07-29)

getSessionId() no longer returns an empty string. On the sampled path, session start writes an internal placeholder entry before the session-start span produces the real id, so getSessionId() could return "" to a caller reading from another thread during that window. It now reports null for that state; the placeholder is never surfaced to callers.

  • addSessionIdObserver’s initial callback had the same gap — it read the session id directly instead of through getSessionId(). Both now go through one accessor.
  • Session start was already synchronous on Android, so the companion iOS fix (a session id missing right after initialize()) never affected Android.

v1.1.8 (2026-07-27)

Version parity release to keep all mobile SDKs and bridge dependencies at 1.1.8. No functional Android changes.

v1.1.7 (2026-07-27)

AGP / AndroidX consumer compatibility — OpenTelemetry Android agent removed. The SDK depended on io.opentelemetry.android:android-agent, which pulled 67 AndroidX modules into every consumer’s dependency graph — including androidx.core 1.17.0, whose AAR metadata requires AGP 8.9.1+ and compileSdk 36. Consumers on older toolchains failed at :app:checkReleaseAarMetadata (Dependency 'androidx.core:core:1.17.0' requires Android Gradle plugin 8.9.1 or higher) with no consumer-side fix short of a full toolchain upgrade.

  • The agent was never used — no io.opentelemetry.android class was referenced. Replaced with direct opentelemetry-api and opentelemetry-sdk (api, 1.59.0).
  • No instrumentation removed. The agent’s auto-instrumentation (activity, fragment, ANR, crash, slow rendering, startup) was never activated; the SDK builds its own tracer/logger pipeline.
  • The resolved runtime graph drops from 133 modules to 30 and contains no AndroidX, so androidx.core resolves to whatever the consumer app declares. Verified on AGP 8.3.2 / Kotlin 1.9.22 / Gradle 8.6 / compileSdk 36.
  • opentelemetry-exporter-otlp is now declared at 1.59.0 (matching what the removed agent BOM already promoted). kotlin-stdlib now resolves to 1.9.24 instead of being promoted to 2.0.20.
  • CI now fails the build if any AndroidX module reaches the runtime classpath, alongside the existing Kotlin-2.x-metadata okhttp/okio checks.

v1.1.6 (2026-07-22)

Version parity release with React Native 1.1.6 (TurboModule migration). No functional Android changes.

v1.1.5 (2026-07-20)

Version parity release to match the v1.1.5 React Native iOS bridge fix and Flutter iOS deployment-target fix. No functional Android changes.

v1.1.4 (2026-07-20)

Kotlin 1.9.x consumer compatibility — OkHttp/Okio transitive metadata. The OTLP sender pulled okhttp 5.x / okio 3.x transitively, both compiled with Kotlin 2.2 metadata, breaking apps pinned to Kotlin 1.9.x even after the earlier kotlin-stdlib fix. okhttp and okio are now excluded from the SDK’s published dependencies and the runtime pins okhttp 4.12.0, keeping the entire dependency graph Kotlin-1.9-readable.

v1.1.3 (2026-07-15)

Warm and hot app-start types now emitted. The AppStart span’s start.type could structurally only ever be cold: a one-shot latch never reset after first launch, so warm starts (Activity recreated) and hot starts (backgrounded → foregrounded) were never classified. Startup classification is now a state machine that re-opens on every background→foreground transition — cold on first launch, warm/hot on each subsequent return to the foreground. Warm/hot start duration now measures from foreground entry rather than process creation.

v1.1.2 (2026-07-15)

Kotlin 1.9.x consumer compatibility. Emits Kotlin metadata 1.9.0 so apps on Kotlin 1.9.x can compile against the AAR (fixes a consumer build failure caused by Kotlin metadata 2.1.0). Stops publishing kotlin-stdlib 2.x on the compile classpath. Minimum consumer toolchain: Kotlin ≥ 1.9.0, AGP ≥ 8.3.

v1.1.1 (2026-07-15)

Network interceptor no longer fails requests during attribute collection. The OkHttp interceptor read cellular attributes via TelephonyManager.getDataNetworkType(), which requires READ_PHONE_STATE and can throw SecurityException on some OEMs even when the permission is absent or granted. That exception could turn an already-successful HTTP response into a failed request. Attribute collection is now fully isolated from the request path, so a failure there can never fail the request, and cellular subtype/carrier reads are gated on a runtime permission check.

v1.1.0 (2026-07-13)

Add GraphQL Layer 1 + Layer 2 network observability

  • Parses GraphQL operation name/type from JSON request bodies and /graphql paths.
  • Descriptive network span names, e.g. GraphQL: "GetUserPreferences" query.
  • Sets graphql.operation.name, graphql.operation.type, l9.span.category=network.
  • Detects GraphQL errors[] on HTTP 200 responses (error.type=GraphQLError, graphql.error.count).
  • Optional networkSpanHook on L9RumConfig for cross-cutting span customization.

v1.0.0 (2026-07-09)

addEvent dual-emits an OTLP log. Alongside the span event on the active view span, addEvent(name, attributes) now also emits an OTLP log record carrying event.type=custom, event.name, and caller attributes. If there’s no active view span, the span event is dropped but the log still sends as an orphan (no trace.id/span.id/view.id). A custom event never silently vanishes.

v0.9.0 (2026-07-02)

Embedded per-flow lifecycle: shutdown() and safe re-initialization. New shutdown() flushes and fully tears down RUM so a later initialize() starts clean; new isActive() reports whether RUM is running. Intended for integrations scoped to a single flow (e.g. a checkout SDK embedded in a host app). Set per-flow attributes via spanAttributes() once known.

L9Rum.initialize(application, config)
L9Rum.spanAttributes(mapOf("tenant.id" to "acme", "feature.flag" to "beta"))
if (L9Rum.isActive()) {
L9Rum.shutdown() // flush + full teardown; a later initialize() re-arms RUM
}

v0.8.0 (2026-06-17)

Fix Client-ID per-install device identity. The Client-ID ingestion header now uses an SDK-generated, auto-persisted per-install UUID instead of serviceName. Previously every device of an app shared one Client-ID, collapsing them into a single ingestion rate-limit bucket. No migration path: existing installs generate a fresh ID once.

v0.7.1 (2026-06-04)

Fix unknown error types. Normalizes blank bridged error types using stack headers before falling back to Error.

v0.7.0 (2026-05-22)

Add network phase child spans. DNS, TCP connect, TLS handshake, and TTFB child spans under each OkHttp parent HTTP span. Added L9Rum.instrumentOkHttp(builder, context) to attach both the interceptor and event-listener factory in one call.

v0.6.1 (2026-05-21)

Patch release. Version sync across SDKs.

v0.6.0 (2026-05-20)

Add Time To Full Display. view.ttfd on View spans reports the maximum time from a completed network response to the next rendered frame.

v0.5.0 (2026-05-13)

Add WebView session correlation. L9Rum.getWebViewInjectedJavaScript() and L9Rum.instrument(webView) inject native session.id and native.view.id context so Browser RUM inside an Android WebView correlates with the host app’s session.

v0.4.0 (2026-05-12)

Add ignorePatterns for network tracking exclusions. Skip noisy requests (CDN assets, images, health checks) before span creation via fullUrl/pathname/hostname patterns, string or regex. Trace headers are still propagated by default unless propagationMode is set to STRIP.

v0.3.1 (2026-04-29)

Add per-request trace isolation and W3C Baggage propagation. isolateTracePerRequest gives each OkHttp request its own traceId; L9BaggageConfig supports whitelisted attributes, size limits, and URL filtering.

v0.3.0 (2026-04-22)

Add resource monitoring and ANR detection. Periodic memory/CPU sampling, Android ANR detection, and network connectivity attributes (connection type, cellular subtype, carrier) on HTTP spans.

v0.2.0 (2026-04-15)

Add sessions, views, errors, and network instrumentation. Session lifecycle tracking, Activity-backed view tracking, handled/unhandled error capture, OkHttp network instrumentation, user identification.

v0.1.0 (2026-04-08)

Initial Android SDK release. OpenTelemetry provider setup, OTLP export, resource attributes, batching configuration.

iOS

v1.8.0 (2026-09-24) · stable

Add session.start_time to every span. Every span now carries session.start_time (epoch ms) alongside session.id, read from the active session. The backend can read the real start time of a session from any span.

  • The Session Start span, the Session End span, and the process-death tombstone spans (Session End and View) carry the start time of the session they belong to. The tombstone carries the start time of the dead session, not of the new one.
  • No API change.

Backdate rollover Session End to last activity. When a session ends because of an inactivity timeout or a max-duration rollover, the Session End timestamp and session.time_spent now use the last recorded activity of the session, not the time the SDK detected the rollover. Idle and background time is no longer counted. exit, shutdown, and process_death ends are unchanged.

Keep session.previous_id across in-process rollovers. An in-process rollover no longer drops session.previous_id on the new session. The SDK now captures the id of the ending session before it clears the persisted session store.

Fix a session-attribute race. The session span processor now reads the active session one time and sets session.id, session.start_time, and session.previous_id from that one snapshot. Before this fix, a rollover between separate reads could put attributes from two different sessions on one span. This matches the fix already on Android. No API change.

v1.7.3 (2026-09-21)

Version parity. No functional iOS changes; released in lockstep with the Android Java null span-attribute fix.

v1.7.2 (2026-09-21)

Version parity. No functional iOS changes; released in lockstep with the Android crash-reporter shutdown() fix.

v1.7.1 (2026-09-21)

Version parity. No functional iOS changes; released in lockstep with the React Native fractional sampleRate bridge fix.

v1.7.0 (2026-09-16)

Per-view refresh rate and memory vitals. When resourceMonitoringEnabled is on (the default), each View span now carries view.refresh_rate_average / view.refresh_rate_min, normalized to 0–60 Hz. It also carries view.frame.slow (inter-tick interval > 1.5× the refresh period) / view.frame.frozen (> 700 ms), and view.memory_average / view.memory_max (resident memory bytes). process.cpu.usage is averaged onto the View from the periodic resource samples.

  • Frame timing comes from a CADisplayLink frame-rate tracker. Per-view memory is sampled (mach resident) at each view start and end, so short screens — including WebView page rotations — still get coverage. Frame tracking pauses while backgrounded.
  • On very short-lived views (shorter than the sampling interval) process.cpu.usage may be absent.
  • No API change — gated by the existing resourceMonitoringEnabled flag. instrumentationVersion reported on the OTel tracer updated to 1.7.0.

v1.6.12 (2026-09-16)

Version alignment. No functional iOS changes; keeps versions in lockstep with the Android 1.6.12 late-initialization cold-start fix (Android-only).

v1.6.11 (2026-09-09)

Fix WebView-host container mislabeled view.type=webview. instrument(webView:) no longer stamps view.type=webview / native.view.id on the active native view, so a persistent container that merely hosts a WebView is no longer mislabeled. In-place WebView content still carries view.type=webview.

v1.6.10 (2026-09-08)

Fix spurious session split near the inactivity boundary. The rollover timer handler re-checks the session against both thresholds before rolling over, so a timer event delivered after a cancel+reschedule no longer splits an active session.

v1.6.9 (2026-08-31)

WebView rotation robustness, session-preserving flush(), SPA history tracking, and killed-view recovery.

  • flush() exports pending telemetry without ending or restarting the session — it no longer emits session.end_reason=flush or a new session.id. shutdown() still ends the session.
  • Session rollover ends the in-flight View span before Session End.
  • View rotation runs on main-frame decidePolicyFor, so an early addEvent (for example WebView_shown) attaches to the destination page, not the previous view. The early rotation retries once when the WebView is transiently hidden mid-transition.
  • SPA history navigations are now tracked in WebViews: pushState, replaceState, hashchange, and popstate report their resulting URL to the native session. In-WebView route changes now get the same view naming as full navigations, which closes the Android-only gap noted at 1.6.0.
  • willTerminate ends the in-flight view; on SIGKILL / jetsam the open view is snapshotted and re-emitted as a backdated View span on the next cold start.

v1.6.8 (2026-08-31)

Fix hidden WebViews suppressing the active page URL. Hidden or transparent preloaded WebViews are excluded when deciding whether a host has multiple active WebViews, so they no longer force a stale URL onto the visible view.

v1.6.7 (2026-08-28)

Fix native network instrumentation replacing streamed POST bodies. URLSession instrumentation no longer opens or replaces httpBodyStream while inspecting requests for GraphQL metadata. Streamed form uploads and third-party SDK requests keep their original body bytes; stream-only requests keep their network spans but skip operation-level body enrichment.

v1.6.6 (2026-08-27)

Version parity release. No functional iOS changes. Released in lockstep with the Android WebView resume fix.

v1.6.5 (2026-08-26)

Fix native view tracking after leaving a WebView tab. WebView ownership now follows the child view controller that contains the WebView, not a persistent parent such as a tab controller. The next native screen is tracked automatically after leaving the WebView. A ghost WebView view cannot revive on a later native-to-native switch.

v1.6.4 (2026-08-26)

Version parity release. No functional iOS changes. Moves in lockstep with the Android R8 consumer-rules fix.

v1.6.3 (2026-08-25)

Fix WebView page identity through nested UIKit controllers. A URL-named WebView page stays the active native view while UIKit reports nested wrapper or Apple-framework controllers, so custom events keep the page’s trace.id and view.id. Native view tracking resumes when the real WebView host leaves.

v1.6.2 (2026-08-24)

Each WebView page becomes its own view (per-navigation view rotation). Same model as Android 1.6.2: every committed main-frame navigation rotates the native view span into a fresh view.type=webview view with view.url, folded app.screen.name, its own native.view.id, and previous_url. The first committed URL names the existing view; query-only changes and shared hosts do not rotate.

  • Breaking: replaces the webview_page_load span event — switch dashboards/alerts to the view.type=webview view events.

v1.6.1 (2026-08-24)

Fix rapid repeated addEvent dropping span events past 128. The tracer now configures SpanLimits at 2048 events per span and 256 attributes per event (up from OpenTelemetry-Swift’s default of 128). The uncapped OTLP log remains the source of truth for extreme bursts.

v1.6.0 (2026-08-21)

Auto-name WebView-hosted views from the current URL. A WebView-hosted view (instrumented via instrument(webView:) / getWebViewInjectedJavaScript(), tagged view.type=webview) is now auto-named from the committed main-frame URL: app.screen.name is the folded pathname (e.g. https://www.example.com/health-record?webViewFrame=edgeToEdge → /health-record) instead of the host view controller class name. Numeric/UUID path segments fold to ?. The full URL is recorded on view.url.

  • Fires on main-frame navigation commits (WKNavigationDelegate.webView(_:didCommit:)). Client-side SPA route changes (pushState / replaceState / hash) are not observable via WKNavigationDelegate, so an in-WebView route change without a full navigation does not re-name the view.
  • An explicit startView / setViewName still wins — the URL-derived name never overwrites an app-provided one. view.url is still recorded either way.
  • Scoped to WebView-hosted views. instrumentationVersion reported on the OTel tracer updated to 1.6.0.

v1.5.2 (2026-08-21)

Fix: addEvent during a view’s teardown attaches to that view, not the next one. A custom event fired while screen A is being torn down now lands on A, not on the next screen B. Previously, once B’s viewDidAppear made B active, an addEvent from A’s later teardown (or in the disappear→appear gap) attached to B or went out as an orphan log without view.id.

  • On view end the just-ended view is kept for a 1000 ms grace window (span.end() is deferred but ended with its logical timestamp). During the window addEvent attaches to the just-ended view even if the next view is already active; after it, and whenever there is no active view, the OTLP log still correlates to the last view for the rest of the session.
  • A manual startView(...) still ends the previous view immediately. Prefer firing screen summaries in viewWillDisappear rather than viewDidDisappear / deinit.
  • instrumentationVersion reported on the OTel tracer updated to 1.5.2.

v1.5.1 (2026-08-20)

Swift Package Manager distribution. Last9RUM can now be added in Xcode via Swift Package Manager from a git URL (https://github.com/last9/last9-rum-ios.git), alongside the existing versioned/stable CDN xcframework and CocoaPods. Pin an exact version tag (e.g. 1.5.1) or track the stable/v1 branch for the latest non-breaking release within a major. The package wraps the same binary xcframework, so there is no checksum to manage by hand. No runtime changes; instrumentationVersion reported on the OTel tracer updated to 1.5.1.

v1.5.0 (2026-08-20)

autoViewTrackingEnabled + no duplicate native views from startView. Added L9RumConfig.autoViewTrackingEnabled (default true). When false, swizzled viewDidAppear / viewWillDisappear no longer open or close view spans — the app owns view names entirely via startView / setViewName. Startup, session, and lifecycle spans are unaffected.

  • startView now ends whatever native view span is currently open (a prior manual view or an auto span still held by the current view controller) before opening a new one, so exactly one native view is ever active.
  • setViewName renames the active view span in place instead of guessing at the key-window root view controller — so it correctly renames auto-tracked child view controllers (e.g. React Native’s RNSScreen) too, with no extra span.
  • instrumentationVersion reported on the OTel tracer updated to 1.5.0.

v1.4.1 (2026-08-19)

Keep the session alive on Home / background. Backgrounding the app — Home button, didEnterBackground, or leaving for a system file picker — no longer ends the RUM session. Returning within the 30-minute inactivity window resumes the same session, so later events keep their session.id. Rollover still happens on inactivity timeout, max duration, or app termination (willTerminate).

Backfill Session End for killed sessions on next launch. A force-quit, crash, or OS memory-kill terminates the app with no runnable code, so iOS never emits a Session End at that moment. On the next cold start, if an orphaned persisted session is found, the SDK backfills that session’s Session End span — backdated to last activity, with session.end_reason=process_death — then starts a fresh session chained via session.previous_id. A same-process re-init still restores the in-window session.

v1.4.0 (2026-08-18)

Configurable batch export schedule delay. Added scheduleDelayMs to L9RumConfig — how long the batch span and log processors wait before flushing queued telemetry (previously hardcoded to 5s). When unset: 5000 ms in production, and 1000 ms when debugLogs is true. View span events still export only when the view span ends.

v1.3.0 (2026-08-12)

Fold dynamic segments in network span names. Network span names fold fully-numeric and UUID path segments to ? (e.g. GET /workspaces/1 → GET /workspaces/?). Applies to URLSession auto-instrumentation and bridged (startNetworkSpan) spans; version-like segments such as v2 are preserved. The raw URL remains on url.full. GraphQL span names are unaffected.

v1.2.1 (2026-08-10)

Fix WebView instrumentation main-thread deadlock. Fixed a reproducible main-thread hang when calling L9Rum.shared.instrument(webView:) right after creating a WKWebView. The view/session observers registered for the WebView re-entered the SDK’s non-recursive lock — both synchronously during registration and later from shutdown() (which ends the active view span/session while holding the lock) — deadlocking the calling thread and freezing the app.

  • sweepDeadWebViewInstrumentations() now acquires the lock non-blocking (try()) and skips when it is already held, removing the re-entrancy; dead entries are still reclaimed via instrument() and teardown.
  • instrumentationVersion reported on the OTel tracer updated to 1.2.1.

v1.2.0 (2026-07-30)

Version parity release. No functional iOS changes. Version bumped to 1.2.0 to keep all mobile SDKs at the same version; this release carries the new React Native Expo config plugin. instrumentationVersion reported on the OTel tracer updated to 1.2.0.

v1.1.10 (2026-07-31)

Version parity release. Bumped the pod and instrumentationVersion to 1.1.10 to keep all mobile SDKs at parity for the React Native 1.1.10 release, which fixes a New Architecture Android clean-build failure in the React Native SDK.

v1.1.9 (2026-07-29)

Session id is available as soon as initialize() returns. The session was previously started with a fire-and-forget dispatch onto an internal serial queue, so getSessionId() could return nil right after initialize(config:) returned even though isActive() already reported true. start() is now synchronous and does not return until the session exists, matching Android.

  • getSessionId() could also return an empty string on the sampled path, where session start writes an internal placeholder before the session-start span produces the real id. It now reports nil for that state; the placeholder is never surfaced.
  • addSessionIdObserver’s initial callback shared the same gap and now reads through the same accessor.
  • The same window existed after flush(), which ends and restarts the session, and is closed by the same change. flush() now blocks the calling thread until the session has restarted (bounded by creating and enqueuing one span) — prefer calling it off the main thread.
  • instrumentationVersion reported on the OTel tracer updated to 1.1.9.

v1.1.8 (2026-07-27)

Version parity release to keep all mobile SDKs and bridge dependencies at 1.1.8. No functional iOS changes. instrumentationVersion reported on the OTel tracer updated to 1.1.8.

v1.1.7 (2026-07-27)

Version parity release with Android 1.1.7 (OpenTelemetry Android agent removed on Android). No functional iOS changes. instrumentationVersion reported on the OTel tracer updated to 1.1.7.

v1.1.6 (2026-07-22)

Version parity release with React Native 1.1.6 (TurboModule migration). No functional iOS changes.

v1.1.5 (2026-07-20)

Modernized key-window lookup. View lifecycle tracking now resolves the key window via UIWindowScene.connectedScenes instead of the iOS 15-deprecated UIApplication.shared.windows. Behavior is unchanged; the SDK compiles cleanly under -warnings-as-errors, and iOS core builds (simulator + device) now run as a required CI gate on every release.

v1.1.4 (2026-07-20)

Version parity release to match Android’s v1.1.4 Kotlin 1.9.x compatibility fix. No functional iOS changes.

v1.1.3 (2026-07-15)

Version parity release to match Android’s v1.1.3 warm/hot app-start fix (that bug was Android-specific). No functional iOS changes.

v1.1.2 (2026-07-15)

Version parity release to match Android’s Kotlin 1.9.x compatibility fix. No functional iOS changes.

v1.1.1 (2026-07-15)

Version parity release to match Android’s network-interceptor fix. iOS was never affected: cellular attributes are read on a background NWPathMonitor callback (off the request path), and CoreTelephony returns optionals rather than throwing.

v1.1.0 (2026-07-13)

Add GraphQL Layer 1 + Layer 2 network observability. Parses GraphQL operation metadata from request bodies in L9URLProtocol, descriptive span names (GraphQL: "{name}" {type}), and detects errors[] on HTTP 200 responses.

v1.0.0 (2026-07-09)

addEvent dual-emits an OTLP log. Same behavior as Android above. The dual-emitted span event attaches to the active view span even when that view is an auto-tracked child view controller (e.g. React Native’s RNSScreen), not just the window’s root view controller.

v0.9.0 (2026-07-02)

Embedded per-flow lifecycle: shutdown() and safe re-initialization. Same model as Android.

L9Rum.shared.initialize(config: config)
L9Rum.shared.spanAttributes(["tenant.id": "acme", "feature.flag": "beta"])
if L9Rum.shared.isActive() {
L9Rum.shared.shutdown() // flush + full teardown; a later initialize() re-arms RUM
}

v0.8.0 (2026-06-17)

Fix Client-ID per-install device identity. Per-install UUID persisted in UserDefaults. Known limitation: UserDefaults is included in encrypted device backups, so a restored backup briefly shares a Client-ID with the original device until the value diverges. Move the ID to the Keychain or a backup-excluded file if strict per-device uniqueness across restores is required.

v0.7.1 (2026-06-04)

Fix unknown error types. Normalizes blank bridged error types before falling back to Error.

v0.7.0 (2026-05-22)

Add network phase child spans. DNS, TCP connect, TLS handshake, TTFB via URLSessionTaskMetrics.transactionMetrics. No config change required.

v0.6.1 (2026-05-21)

Patch release. Version sync across SDKs.

v0.6.0 (2026-05-20)

Add Time To Full Display. view.ttfd on View spans.

v0.5.0 (2026-05-13)

Add WKWebView session correlation. L9Rum.shared.instrument(webView:) injects native session/view context into WKWebView for correlation with Browser RUM.

v0.4.0 (2026-05-12)

Add ignorePatterns for network tracking exclusions. Same model as Android, applied to URLProtocol interception.

v0.3.1 (2026-04-29)

Add per-request trace isolation and W3C Baggage propagation. Via URLSession.

v0.3.0 (2026-04-22)

Add resource monitoring and network context. Memory/CPU sampling, network connectivity attributes, startup tracking.

v0.2.0 (2026-04-15)

Add sessions, views, errors, and network instrumentation. Full RUM instrumentation over the initial export setup.

v0.1.0 (2026-04-08)

Initial iOS SDK release.

React Native

v1.8.0 (2026-09-24) · stable

session.start_time on every span (via native). Carries the Android and iOS change that adds session.start_time (epoch ms) to every span alongside session.id. The Session Start, Session End, and process-death tombstone spans carry the start time of the session they belong to.

Rollover Session End backdating and session.previous_id fix (via native). A rollover’s Session End span and session.time_spent are dated at the last activity of the session, not at the time the rollover was detected. The new session keeps session.previous_id after an in-process rollover.

  • Native pins: Android io.last9:rum-android:1.8.0 and iOS Last9RUM 1.8.0. No wrapper API change.

v1.7.3 (2026-09-21)

Android Java null span-attribute fix (via native). Carries the Android fix that drops null keys and null values from Java L9Rum.spanAttributes() maps instead of throwing a NullPointerException. Native pins: Android 1.7.3 and iOS Last9RUM 1.7.3. No wrapper API change.

v1.7.2 (2026-09-21)

Android crash-reporter shutdown() fix (via native). Carries the Android fix that keeps a third-party crash reporter, installed after Last9, active during shutdown(). Native pins: Android 1.7.2 and iOS Last9RUM 1.7.2. No wrapper API change.

v1.7.1 (2026-09-21)

Fix: round fractional sampleRate values before the native bridge. The wrapper now rounds a fractional sampleRate to the nearest integer before it crosses the React Native bridge. iOS and Android now get the same sampling percentage. Before this fix, each platform converted the value to an integer in a different way. Native pins: Android 1.7.1 and iOS Last9RUM 1.7.1.

v1.7.0 (2026-09-16)

Per-view vitals — native refresh rate and memory plus JS-thread refresh rate.

  • Inherits the native per-view vitals (view.refresh_rate_average / view.refresh_rate_min, view.frame.slow / view.frame.frozen, view.memory_average / view.memory_max, process.cpu.usage) on View spans, gated by resourceMonitoringEnabled.
  • Additionally emits JS-thread refresh-rate vitals: view.js_refresh_rate.average / view.js_refresh_rate.min / view.js_refresh_rate.max. These are measured on the JS thread and flushed onto each View before startView and on shutdown. A busy JS thread therefore shows up even when native UI frames look healthy.
  • Native pins: Android io.last9:rum-android:1.7.0 and iOS Last9RUM 1.7.0. No wrapper API change.

v1.6.12 (2026-09-16)

Fix late-initialization cold-start durations (via native). React Native calls initialize() after the launch Activity is already resumed, so the native SDK never observes the cold launch. A background return of the resident Activity is now classified hot / warm, with a duration measured from foreground entry. It is no longer a cold start covering the entire prior process lifetime. Native pins: Android 1.6.12 and iOS Last9RUM 1.6.12.

v1.6.11 (2026-09-09)

Native WebView host-tagging fix (via native). A persistent native container merely hosting a WebView is no longer mislabeled view.type=webview; per-URL WebView page views are unaffected. Native pins: Android 1.6.11 and iOS Last9RUM 1.6.11.

v1.6.10 (2026-09-08)

Version parity release. Native 1.6.10 re-validates that a scheduled rollover is still due before firing, preventing a spurious session split near the inactivity boundary. Native pins: Android 1.6.10 and iOS Last9RUM 1.6.10.

v1.6.9 (2026-08-31)

Session-preserving flush() and WebView page association (via native). Carries the native fixes that keep flush() from rotating the RUM session and attach WebView navigation to dedicated page views. Native pins: Android 1.6.9 and iOS Last9RUM 1.6.9.

v1.6.8 (2026-08-31)

Version parity release. Carries the native fixes that prevent hidden or transparent preloaded WebViews from suppressing the visible WebView URL. Native pins: Android 1.6.8 and iOS Last9RUM 1.6.8.

v1.6.7 (2026-08-28)

Version parity release. Carries the iOS fix that preserves streamed POST bodies when native network instrumentation is enabled. Native pins: Android 1.6.7 and iOS Last9RUM 1.6.7.

v1.6.6 (2026-08-27)

Version parity release. Carries the Android fix that keeps a surviving WebView bound to its URL-derived view after Activity resume. Native pins: Android 1.6.6 and iOS Last9RUM 1.6.6.

v1.6.5 (2026-08-26)

Version parity release. Carries the iOS fix that resumes automatic native view tracking after leaving a WebView child inside a persistent container. Native pins: Android 1.6.5 and iOS Last9RUM 1.6.5.

v1.6.4 (2026-08-26)

Version parity release. Carries the Android fix so apps with minifyEnabled = true no longer fail R8 on missing io.opentelemetry.api.incubator.* classes — no app-side ProGuard change needed. Native pins: Android 1.6.4 and iOS Last9RUM 1.6.4.

v1.6.3 (2026-08-25)

Version parity release. Carries the iOS fix that keeps custom events correlated with the visible WebView page through nested UIKit controller callbacks. Native pins: Android 1.6.3 and iOS Last9RUM 1.6.3.

v1.6.2 (2026-08-24)

Each WebView page becomes its own view (per-navigation view rotation, via native). Both native SDKs rotate the native view span on each committed WebView main-frame navigation into a fresh view.type=webview view. React Native carries the change through the pinned native dependencies.

  • Breaking: replaces the webview_page_load span event — switch dashboards/alerts to the view.type=webview view events.
  • Native pins: Android 1.6.2 and iOS Last9RUM 1.6.2.

v1.6.1 (2026-08-24)

Fix rapid repeated addEvent dropping span events past 128 (via native). Both native tracers now configure SpanLimits at 2048 events per span and 256 attributes per event (up from the default of 128). Native pins: Android 1.6.1 and iOS Last9RUM 1.6.1.

v1.6.0 (2026-08-21)

Auto-name WebView-hosted views from the current URL (via native). A WebView instrumented with L9Rum.instrumentWebView(...) now has its host native view auto-named from the current main-frame URL: app.screen.name becomes the folded pathname (e.g. .../health-record?webViewFrame=edgeToEdge → /health-record) instead of the host Activity/ViewController class name. The full URL is recorded on view.url. An explicit L9Rum.startView / setViewName still wins. Android updates the name on full loads and in-WebView history changes; iOS updates on navigation commit (SPA route changes are not observable). Native pins: Android io.last9:rum-android:1.6.0 and iOS Last9RUM 1.6.0.

v1.5.2 (2026-08-21)

addEvent during a view’s teardown attaches to that view (via native). addEvent is a native pass-through, so it inherits the 1000 ms grace window: an event fired while a screen is being torn down attaches to that screen, not the next one, and the OTLP log still correlates to the last view when none is current. Prefer firing screen summaries before teardown (for example on blur / a screen’s unmount effect). A manual startView(...) ends the previous view immediately. Native pins: Android 1.5.2 and iOS Last9RUM 1.5.2.

v1.5.1 (2026-08-20)

Version parity release. No JS-side changes. Bumps the pinned native dependencies to Android io.last9:rum-android:1.5.1 and iOS Last9RUM 1.5.1.

v1.5.0 (2026-08-20)

autoViewTrackingEnabled config (via native). Added autoViewTrackingEnabled to the init config (default true), forwarded to the native SDKs. Set false when your app owns all view names (for example only via navigation instrumentation / manual startView) to suppress native Activity/ViewController auto views.

  • Carries the native fixes: startView never leaves a duplicate native view open, and setViewName renames the active view (including auto-tracked child view controllers) in place.
  • Bumps the pinned native dependencies to Android io.last9:rum-android:1.5.0 and iOS Last9RUM 1.5.0.

v1.4.1 (2026-08-19)

Keep the session alive on Home / background (via native). Backgrounding the app (Home button or a system file picker) no longer ends the RUM session — the same session continues when the app returns within the 30-minute inactivity window. A force-kill/crash now backfills the killed session’s Session End on the next cold start (session.end_reason=process_death) and starts a fresh session. Native pins: Android 1.4.1 and iOS Last9RUM 1.4.1.

v1.4.0 (2026-08-18)

Configurable batch export schedule delay (via native). Added scheduleDelayMs to the config — how long the native batch processors wait before flushing queued spans/logs. When omitted: 5000 ms in production, and 1000 ms when debugLogs is true.

v1.3.0 (2026-08-12)

Network span names fold dynamic segments (via native). Network span names fold fully-numeric and UUID path segments to ? (e.g. GET /workspaces/1 → GET /workspaces/?). RN forwards the raw URL to the native SDK, which does the folding. Native pins: Android 1.3.0 and iOS Last9RUM 1.3.0.

v1.2.1 (2026-08-10)

Fix robust instrumentWebView argument resolution. L9Rum.instrumentWebView(...) now resolves the native WebView tag from a WebView load event (event.nativeEvent.target), a numeric reactTag, a ref object, or a component instance — and never throws. Previously it passed the argument straight to findNodeHandle, which threw Argument appears to not be a ReactComponent for a react-native-webview >= 13 ref (its .current is a methods-only imperative handle, not a resolvable component). Older react-native-webview refs and other component instances keep working.

  • Recommended usage across all react-native-webview versions and both architectures: onLoadStart={(e) => L9Rum.instrumentWebView(e.nativeEvent.target)}.
  • Native pins updated to iOS Last9RUM 1.2.1 and Android io.last9:rum-android:1.2.1; the iOS pin carries a fix for a reproducible main-thread hang when instrumenting a WebView.

v1.2.0 (2026-07-30)

Expo config plugin for drop-in Continuous Native Generation (CNG). Add "@last9/rum-react-native" to the plugins array in app.json and the two native install steps are re-applied automatically on every prebuild: the Last9 CDN Maven repository on Android and the Last9RUM Podfile pod source on iOS. Previously these lived in the generated android/ and ios/ folders and were wiped on each prebuild, so CNG apps had to re-add them by hand.

{
"expo": {
"plugins": ["@last9/rum-react-native"]
}
}
  • The iOS podspec version is derived from the installed SDK version, so it never drifts. The plugin is idempotent across repeated prebuilds. It requires a development build (EAS Build or expo run:*) — it does not run in Expo Go, which cannot load native modules.
  • No changes to the JS API. The manual Android/iOS install steps remain supported for bare React Native apps.
  • Bumps the iOS pod to Last9RUM 1.2.0 and the native Android SDK to io.last9:rum-android:1.2.0.

v1.1.10 (2026-07-31)

Fix Android New Architecture clean-build failure (configureCMakeDebug). On the New Architecture, a clean or parallel Android build (and Android Studio’s Gradle sync) could fail at :app:configureCMakeDebug with add_subdirectory given source ".../@last9/rum-react-native/android/build/generated/source/codegen/jni/" which is not an existing directory. Introduced with the TurboModule/Codegen migration in 1.1.6.

  • Root cause: the consuming app’s autolinking add_subdirectory()s the library’s generated codegen/jni folder, which is produced at build time and is not in the npm package — and nothing ordered the app’s CMake configure after the library’s codegen under parallel execution.
  • Fix: the package now ships a committed android/src/main/jni/CMakeLists.txt and points autolinking at it via react-native.config.js, mirroring first-party libraries such as react-native-safe-area-context.
  • No JS-side or public API changes. Bumps the native Android SDK to io.last9:rum-android:1.1.10 and the iOS pod to Last9RUM 1.1.10 for version parity.

v1.1.9 (2026-07-29)

Fix initialize() resolving with an empty or missing sessionId on iOS. await L9Rum.initialize(config) resolves with { sessionId }, but on iOS that could come back as null or an empty string even on success: the native SDK started the session asynchronously and the bridge read it on the next line, racing session creation. Fixed in native Last9RUM 1.1.9 — session start is synchronous and the internal placeholder is never surfaced, so initialize() resolves with a real session id or rejects.

  • getSessionId() is fixed by the same change on both platforms and never returns an empty string.
  • No JS-side or public API changes; no action needed beyond upgrading.
  • Bumps the iOS pod to Last9RUM 1.1.9 and the native Android SDK to io.last9:rum-android:1.1.9 (Android carries the getSessionId() half; its session start was already synchronous).

v1.1.8 (2026-07-27)

Version parity release. Bumps the native Android SDK and iOS pod dependency to 1.1.8. There are no JS-side changes.

v1.1.7 (2026-07-27)

AGP / AndroidX consumer compatibility on Android. Bumps native Android SDK to io.last9:rum-android:1.1.7, which removes the OpenTelemetry Android agent and with it 67 transitive AndroidX modules — including androidx.core 1.17.0, whose AAR metadata requires AGP 8.9.1+. React Native Android apps on an older toolchain were failing the AAR metadata check with no fix short of a full toolchain upgrade. Picked up automatically; androidx.core now resolves to whatever the consumer app declares.

  • No instrumentation is lost — the removed agent’s auto-instrumentation was never activated by the SDK.
  • Bumps the iOS pod to Last9RUM 1.1.7 (version parity; no functional iOS changes).
  • Plugin version aligned to 1.1.7. There are no JS-side changes.

v1.1.6 (2026-07-22)

Fix initialize() hanging on the New Architecture (bridgeless). On bridgeless (default from RN 0.76+), await L9Rum.initialize(...) could hang forever: native called resolve(...), but the JS promise never settled because the module was reached through React Native’s interop layer (facebook/react-native#44555).

  • The module is now a real TurboModule (RNL9RumSpec Codegen spec). JS↔native calls dispatch over JSI directly.
  • iOS: getTurboModule: returns NativeL9RumSpecJSI; promise selectors renamed to resolve:/reject:.
  • Android: TurboModule marker + BaseReactPackage with isTurboModule = true.
  • Backwards compatible: public JS API unchanged; Old Architecture (Paper) still supported.
  • Bundles native Android/iOS RUM 1.1.6.
// Upgrade to 1.1.6+ (latest versioned: 1.6.0) and await initialize on bridgeless
const { sessionId } = await L9Rum.initialize(config);

v1.1.5 (2026-07-20)

Fix iOS build failure when bridging a nil session ID. After initialize() began resolving { sessionId }, the iOS bridge failed to compile (binary operator '??' cannot be applied to operands of type 'String?' and 'NSNull'). The bridge now resolves a non-nil session id to JavaScript as a string and nil as null. Also aligns the endNetworkSpan status-code bridge signature so HTTP status codes marshal correctly, and adds a real React Native iOS consumer build (autolinking + CocoaPods + Swift compile) as a required CI gate on every release. Bundles native Android/iOS RUM 1.1.5.

v1.1.4 (2026-07-20)

Bundles native Android RUM 1.1.4, which stops the OTLP okhttp/okio dependencies (Kotlin 2.2 metadata) from reaching a consumer’s compile classpath — fixing Android build failures for apps on Kotlin 1.9.x. No JS-side changes.

v1.1.3 (2026-07-15)

Bundles native Android RUM 1.1.3, which fixes AppStart start.type being stuck on cold — warm and hot starts are now classified for the whole process lifetime. No JS-side changes.

v1.1.2 (2026-07-15)

Initialize no longer fails silently. L9Rum.initialize() now returns Promise<{ sessionId }> and rejects when required config is missing or native init doesn’t become active. Use await L9Rum.initialize(...) and/or await L9Rum.isActive() to verify readiness. Don’t rely only on a null getSessionId() after a fire-and-forget call. Bundles native Android/iOS RUM 1.1.2.

try {
const { sessionId } = await L9Rum.initialize(config);
} catch (error) {
console.error("RUM failed to initialize", error);
}
const running = await L9Rum.isActive();

v1.1.1 (2026-07-15)

Bundles native Android RUM 1.1.1, fixing a SecurityException crash in the shared OkHttp interceptor for RN Android apps using nativeNetworkInterception. iOS pod bumped to 1.1.1 for parity.

v1.1.0 (2026-07-13)

Add GraphQL Layer 1 + Layer 2 network observability

  • Layer 1 (on by default): descriptive span name GraphQL: "{name}" {type} with graphql.operation.* attributes; errors[] on HTTP 200 flagged as error.type=GraphQLError.
  • Layer 2 (opt-in): l9GqlLink Apollo Link (requires the optional @apollo/client peer dependency) with opt-in captureVariables (redacted) and captureErrorMessages (truncated).
  • Bundles native Android/iOS RUM 1.1.0.

v1.0.0 (2026-07-09)

addEvent dual-emits an OTLP log (inherited from native). Bridge unchanged; behavior comes from the underlying Android/iOS SDKs.

v0.9.0 (2026-07-02)

Embedded per-flow lifecycle. L9Rum.shutdown() and L9Rum.isActive() bridged from native. shutdown() returns Promise<void>, so a caller can await L9Rum.shutdown() before re-initializing the next flow.

L9Rum.initialize(config);
L9Rum.spanAttributes({ "tenant.id": "acme", "feature.flag": "beta" });
if (await L9Rum.isActive()) {
await L9Rum.shutdown();
}

v0.8.0 (2026-06-17)

Fix Client-ID per-install device identity. Handled entirely by the native iOS/Android SDKs; no RN changes required.

v0.7.1 (2026-06-04)

Fix unknown error types. Infers exception.type for non-Error values (strings, primitives, plain objects).

v0.7.0 (2026-05-22)

Add network phase child spans. RN now defaults to native network interception for DNS/TCP/TLS/TTFB phase timing instead of JS-only fetch/XHR interception. JS fallback remains available when nativeNetworkInterception is explicitly disabled.

v0.6.1 (2026-05-21)

Patch release. Added typed serialized ignore-pattern shapes for the native bridge payload and applied ignorePatterns filtering to RN’s fetch/XMLHttpRequest instrumentation.

v0.6.0 (2026-05-20)

Add Time To Full Display. Native view.ttfd reporting for RN network requests.

v0.5.0 (2026-05-19)

WebView session correlation. L9Rum.instrumentWebView(event.nativeEvent.target) (recommended) or a numeric tag, ref, or component instance installs a forwarding delegate that re-injects session.id/native.view.id on every page commit; L9Rum.getWebViewInjectedJavaScript() remains available as a one-shot static script. webViewAutoLoadBrowserRum: true auto-loads Browser RUM into the WebView.

v0.4.0 (2026-05-12)

Add ignorePatterns for network tracking exclusions. Browser-style ignorePatterns on L9Rum.initialize().

v0.3.1 (2026-04-29)

Add per-request trace isolation and W3C Baggage propagation. Bridged to native Android/iOS.

v0.3.0 (2026-04-22)

Add React Navigation and runtime monitoring support. L9ReactNavigationInstrumentation, JS-level fetch/XHR interception, native resource monitoring and Android ANR detection exposed through RN config.

v0.2.0 (2026-04-15)

Add React Native bridge for mobile RUM APIs. Core RUM APIs bridged to Android/iOS: identify(), clearUser(), captureError(), addEvent(), startView(), setViewName().

v0.1.0 (2026-04-08)

Initial React Native SDK release.

Flutter

v1.8.0 (2026-09-24) · stable

session.start_time on every span (via native). Carries the Android and iOS change that adds session.start_time (epoch ms) to every span alongside session.id. The Session Start, Session End, and process-death tombstone spans carry the start time of the session they belong to.

Rollover Session End backdating and session.previous_id fix (via native). A rollover’s Session End span and session.time_spent are dated at the last activity of the session, not at the time the rollover was detected. The new session keeps session.previous_id after an in-process rollover.

  • Native pins: Android io.last9:rum-android:1.8.0 and iOS Last9RUM 1.8.0. No Dart API change.

v1.7.3 (2026-09-21)

Android Java null span-attribute fix (via native). Carries the Android fix that drops null keys and null values from Java L9Rum.spanAttributes() maps instead of throwing a NullPointerException. Native pins: Android 1.7.3 and iOS Last9RUM 1.7.3. No wrapper API change.

v1.7.2 (2026-09-21)

Android crash-reporter shutdown() fix (via native). Carries the Android fix that keeps a third-party crash reporter, installed after Last9, active during shutdown(). Native pins: Android 1.7.2 and iOS Last9RUM 1.7.2. No wrapper API change.

v1.7.1 (2026-09-21)

Version parity. No functional Flutter changes; released in lockstep with the React Native fractional sampleRate bridge fix. Native pins: Android 1.7.1 and iOS Last9RUM 1.7.1.

v1.7.0 (2026-09-16)

Version parity — per-view vitals via native. Native 1.7.0 adds per-view refresh rate and memory vitals (view.refresh_rate_average / view.refresh_rate_min, view.frame.slow / view.frame.frozen, view.memory_average / view.memory_max, process.cpu.usage) on View spans, gated by resourceMonitoringEnabled. Flutter inherits these with no Dart changes. Native pins: Android 1.7.0 and iOS Last9RUM 1.7.0.

v1.6.12 (2026-09-16)

Fix late-initialization cold-start durations (via native). Flutter calls initialize() after the launch Activity is already resumed. A background return of the resident Activity is now classified hot / warm, measured from foreground entry, instead of a cold start spanning the entire prior process lifetime. Native pins: Android 1.6.12 and iOS Last9RUM 1.6.12.

v1.6.11 (2026-09-09)

Version parity release. Native 1.6.11 stops a persistent container merely hosting a WebView from being mislabeled view.type=webview. As with the other WebView page-association fixes, this applies only when native instrument(webView) is used. Flutter has no instrumentWebView binding yet (ENG-1780), so the fix ships in the pinned dependencies but is not reachable from Dart. Native pins: Android 1.6.11 and iOS Last9RUM 1.6.11.

v1.6.10 (2026-09-08)

Version parity release. Native 1.6.10 re-validates that a scheduled rollover is still due before firing, preventing a spurious session split near the inactivity boundary. Native pins: Android 1.6.10 and iOS Last9RUM 1.6.10.

v1.6.9 (2026-08-31)

Session-preserving flush() (via native). Carries the native fix that keeps flush() from rotating the RUM session. The WebView page-association fixes apply only through native instrument(webView), which Flutter does not yet bind (ENG-1780), so they ship in the pinned dependencies but are not reachable from Dart. Native pins: Android 1.6.9 and iOS Last9RUM 1.6.9.

v1.6.8 (2026-08-31)

Version parity release. Carries the native fixes that prevent hidden or transparent preloaded WebViews from suppressing the visible WebView URL. Native pins: Android 1.6.8 and iOS Last9RUM 1.6.8.

v1.6.7 (2026-08-28)

Version parity release. Carries the iOS fix that preserves streamed POST bodies when native network instrumentation is enabled. Native pins: Android 1.6.7 and iOS Last9RUM 1.6.7.

v1.6.6 (2026-08-27)

Version parity release. Carries the Android fix that keeps a surviving WebView bound to its URL-derived view after Activity resume. Native pins: Android 1.6.6 and iOS Last9RUM 1.6.6.

v1.6.5 (2026-08-26)

Version parity release. Carries the iOS fix that resumes automatic native view tracking after leaving a WebView child inside a persistent container. Native pins: Android 1.6.5 and iOS Last9RUM 1.6.5.

v1.6.4 (2026-08-26)

Version parity release. Carries the Android fix so apps with minifyEnabled = true no longer fail R8 on missing io.opentelemetry.api.incubator.* classes. Native pins: Android 1.6.4 and iOS Last9RUM 1.6.4.

v1.6.3 (2026-08-25)

Version parity release. Carries the iOS fix that keeps custom events correlated with the visible WebView page through nested UIKit controller callbacks. Native pins: Android 1.6.3 and iOS Last9RUM 1.6.3.

v1.6.2 (2026-08-24)

Each WebView page becomes its own view (per-navigation view rotation, via native). Both native SDKs rotate the native view span on each committed WebView main-frame navigation into a fresh view.type=webview view. Flutter carries the change through the pinned native dependencies (reachable once a WebView is handed to native instrumentation).

  • Breaking: replaces the webview_page_load span event — switch dashboards/alerts to the view.type=webview view events.
  • Native pins: Android 1.6.2 and iOS Last9RUM 1.6.2.

v1.6.1 (2026-08-24)

Fix rapid repeated addEvent dropping span events past 128 (via native). Both native tracers now configure SpanLimits at 2048 events per span and 256 attributes per event (up from the default of 128). Native pins: Android 1.6.1 and iOS Last9RUM 1.6.1.

v1.6.0 (2026-08-21)

Version parity release. No Dart-side functional change. Bumped to 1.6.0 to keep all mobile SDKs at the same version; this release carries native WebView view auto-naming (host WebView views named from the folded URL path + a view.url attribute).

  • WebView auto-naming does not yet apply to Flutter. It fires only for WebViews handed to the native instrument(webView) entry point. Flutter has no instrumentWebView bridge — it uses getWebViewInjectedJavaScript(), which stamps view.type=webview but does not attach the native navigation delegate that drives URL-based naming. Name WebView host views with L9Rum.startView(...) in the meantime.
  • Bumps the pinned native dependencies to Android io.last9:rum-android:1.6.0 and iOS Last9RUM 1.6.0.

v1.5.2 (2026-08-21)

addEvent during a view’s teardown attaches to that view (via native). addEvent is a native pass-through, so it inherits the 1000 ms grace window with no Dart changes. Prefer firing screen summaries before teardown (for example in dispose() / a route’s pop callback). A manual startView(...) ends the previous view immediately. Native pins: Android 1.5.2 and iOS Last9RUM 1.5.2.

v1.5.1 (2026-08-20)

Version parity release. No Dart-side changes. Bumps the pinned native dependencies to Android io.last9:rum-android:1.5.1 and iOS Last9RUM 1.5.1.

v1.5.0 (2026-08-20)

autoViewTrackingEnabled config (via native). Added L9RumConfig.autoViewTrackingEnabled (default true), forwarded to the native SDKs. Set false when your app owns all view names to suppress native Activity/ViewController auto views.

  • Carries the native fixes: startView never leaves a duplicate native view open, and setViewName renames the active view in place.
  • Bumps the pinned native dependencies to Android io.last9:rum-android:1.5.0 and iOS Last9RUM 1.5.0.

v1.4.1 (2026-08-19)

Keep the session alive on Home / background (via native). Backgrounding the app no longer ends the RUM session — the same session continues when the app returns within the 30-minute inactivity window. A force-kill/crash now backfills the killed session’s Session End on the next cold start (session.end_reason=process_death). Native pins: Android 1.4.1 and iOS Last9RUM 1.4.1.

v1.4.0 (2026-08-18)

Configurable batch export schedule delay (via native). Added scheduleDelayMs to L9RumConfig. When omitted: 5000 ms in production, and 1000 ms when debugLogs is true.

v1.3.0 (2026-08-12)

Network span names fold dynamic segments (via native). Network span names fold fully-numeric and UUID path segments to ? (e.g. GET /workspaces/1 → GET /workspaces/?). Flutter forwards the raw URL to the native SDK, which does the folding. Native pins: Android 1.3.0 and iOS Last9RUM 1.3.0.

v1.2.1 (2026-08-10)

Version parity release. No Dart-side changes. Plugin version aligned to 1.2.1 across pubspec.yaml, the Android library, and the iOS podspec. Native pins bumped to iOS Last9RUM 1.2.1 and Android io.last9:rum-android:1.2.1; the iOS pin carries a fix for a reproducible main-thread hang when instrumenting a WebView.

v1.2.0 (2026-07-30)

Version parity release. No Dart-side changes. Plugin version aligned to 1.2.0 across pubspec.yaml, the Android library, and the iOS podspec to keep all mobile SDKs at the same version; this release carries the new React Native Expo config plugin. Native pins: iOS Last9RUM 1.2.0 and Android io.last9:rum-android:1.2.0.

v1.1.10 (2026-07-31)

Version parity release. Plugin version aligned to 1.1.10 across pubspec.yaml, the Android library, and the iOS podspec, with native pins bumped for parity. No Dart-side changes. Ships alongside the React Native 1.1.10 fix for a New Architecture Android clean-build failure.

v1.1.9 (2026-07-29)

getSessionId() no longer returns null or an empty string after init. Bumps the iOS pod to Last9RUM 1.1.9, which fixes a session id missing right after initialize(): iOS started the session asynchronously, so a getSessionId() call soon after initializing raced session creation and returned null, or returned an internal empty-string placeholder if it landed mid-creation. Session start is now synchronous and the placeholder is never surfaced.

  • Bumps the native Android SDK to io.last9:rum-android:1.1.9, which carries the same placeholder fix. Android’s session start was already synchronous, so it never returned a missing session id.
  • There are no Dart-side changes; Flutter apps pick this up automatically.

v1.1.8 (2026-07-27)

Version parity release. Bumps the native Android SDK and iOS pod dependency to 1.1.8. There are no Dart-side changes.

v1.1.7 (2026-07-27)

AGP / AndroidX consumer compatibility on Android. Bumps native Android SDK to io.last9:rum-android:1.1.7, which removes the OpenTelemetry Android agent and with it 67 transitive AndroidX modules — including androidx.core 1.17.0, whose AAR metadata requires AGP 8.9.1+. Flutter Android apps on an older toolchain were failing the AAR metadata check with no fix short of a full toolchain upgrade. Picked up automatically; androidx.core now resolves to whatever the consumer app declares.

  • No instrumentation is lost — the removed agent’s auto-instrumentation was never activated by the SDK.
  • Bumps the iOS pod to Last9RUM 1.1.7 (version parity; no functional iOS changes).
  • Plugin version aligned to 1.1.7 across pubspec.yaml, the Android library, and the iOS podspec. There are no Dart-side changes.

v1.1.6 (2026-07-22)

Version parity release. Bumps native Android/iOS SDK references to 1.1.6. No Dart-side changes.

v1.1.5 (2026-07-20)

Fix iOS pod install deployment-target mismatch. The plugin declared iOS 13.0 while depending on a core pod that requires 15.1, which could fail pod install for consumer apps; the plugin’s minimum deployment target is now 15.1. A full Flutter iOS consumer build now runs as a required CI gate on every release. Bundles native Android/iOS RUM 1.1.5. No Dart-side changes.

v1.1.4 (2026-07-20)

Bundles native Android RUM 1.1.4 (Kotlin 1.9.x consumer compatibility — okhttp/okio Kotlin 2.2 metadata no longer reaches the consumer compile classpath). No Dart-side changes.

v1.1.3 (2026-07-15)

Bundles native Android RUM 1.1.3 (warm/hot app-start classification fix). No Dart-side changes.

v1.1.2 (2026-07-15)

Version parity release. Bumps native Android/iOS SDK references to 1.1.2. No Dart-side changes.

v1.1.1 (2026-07-15)

Version parity release. Bumps native Android/iOS SDK references to 1.1.1. Flutter was never affected by the underlying Android interceptor crash: it doesn’t install the native OkHttp interceptor.

v1.1.0 (2026-07-13)

Add GraphQL Layer 1 + Layer 2 network observability. L9HttpClient captures request bodies for native span resolution; GraphQL spans named GraphQL: "{operationName}" {type}. Layer 2: L9DioInterceptor (Dio) and L9GqlLink (gql/graphql) with opt-in captureErrorMessages/captureVariables.

v1.0.0 (2026-07-09)

addEvent dual-emits an OTLP log (inherited from native). Flutter bridge unchanged. Bundles native Android/iOS RUM 1.0.0.

v0.9.0 (2026-07-02)

Embedded per-flow lifecycle. L9Rum.shutdown() and L9Rum.isActive() bridged from native. Requires native iOS/Android SDK 0.9.0.

await L9Rum.initialize(config);
await L9Rum.spanAttributes(<String, dynamic>{'tenant.id': 'acme', 'feature.flag': 'beta'});
if (await L9Rum.isActive()) {
await L9Rum.shutdown();
}

v0.8.0 (2026-06-17)

Fix Client-ID per-install device identity. Handled by the native iOS/Android SDKs; no Flutter changes required.

v0.7.1 (2026-06-04)

Fix unknown error types. Infers exception.type from Dart runtime types for primitive/non-Error payloads.

v0.7.0 (2026-05-22)

Add network phase child spans. Native interception enabled by default on Android/iOS bridges; Dart HttpClient fallback emits a best-effort ttfb phase when native isn’t available.

v0.6.1 (2026-05-21)

Patch release. Version sync across SDKs.

v0.6.0 (2026-05-20)

Add Time To Full Display. Native view.ttfd reporting for Flutter network requests.

v0.5.0 (2026-05-19)

WebView session correlation. L9Rum.getWebViewInjectedJavaScript() writes native session.id/native.view.id into the WebView; pair with the host plugin’s navigation callback (e.g. webview_flutter’s onPageStarted). webViewAutoLoadBrowserRum: true auto-loads Browser RUM into the WebView.

v0.4.0 (2026-05-12)

Add ignorePatterns for network tracking exclusions. Skips noisy dart:io HTTP requests before span creation.

v0.3.1 (2026-04-29)

Add per-request trace isolation and W3C Baggage propagation. Bridged to native Android/iOS.

v0.3.0 (2026-04-22)

Add Flutter navigation and runtime monitoring support. L9NavigationObserver, HttpOverrides instrumentation, native resource monitoring and Android ANR detection exposed through Flutter config.

v0.2.0 (2026-04-15)

Add Flutter plugin bridge for mobile RUM APIs. Core RUM APIs bridged to Android/iOS.

v0.1.0 (2026-04-08)

Initial Flutter SDK release.