diff --git a/docs/instrument/mobile/rum-opentelemetry.md b/docs/instrument/mobile/rum-opentelemetry.md new file mode 100644 index 00000000..e1744992 --- /dev/null +++ b/docs/instrument/mobile/rum-opentelemetry.md @@ -0,0 +1,453 @@ +--- +title: Sending RUM Data to base14 - OpenTelemetry Integration Guide +sidebar_label: Sending RUM Data (OTel) +sidebar_position: 30 +description: + Data-model reference for sending mobile RUM telemetry to base14 Scout over + OTLP. Documents every span name, its resource and span attributes, units, + and the RUM views each one powers. +keywords: + [ + rum opentelemetry, + otlp mobile, + rum data model, + rum span attributes, + mobile crash reporting, + native crash otlp, + anr instrumentation, + session timeline, + base14, + scout, + ] +--- + +# Sending RUM Data to base14 + +This is a data-model reference for sending mobile +[RUM](../../operate/rum/getting-started.md) telemetry to base14 Scout. Use it +when you build your own instrumentation +(rather than using a prebuilt SDK like +[scout_flutter](./flutter.md)) and need to know exactly which spans and +attributes each RUM view expects. + +RUM data is plain OpenTelemetry: every value is a standard resource or span +attribute, so it lines up with any traces and logs you already send to Scout. +Each RUM feature is powered by a span with a specific `span.name` and a +specific set of attributes - get the names and attribute placement right and +the corresponding view populates automatically. + +--- + +## Transport + +| Setting | Value | +| ------- | ----- | +| **Protocol** | OTLP - traces sent to `…/v1/traces` | +| **Endpoint** | The OTLP URL base14 provides for your account, e.g. `https://rum..base14.io//otlp` | +| **Auth** | `Authorization: Bearer ` header (base14 provisions the token) | + +--- + +## Identity and Attribute Placement + +Read this section before wiring up any spans - most integration problems come +from putting an attribute on the wrong scope, or letting an identity value +drift between builds. + +### `service.name` is fixed + +`service.name` is a **resource** attribute and is your app's identity in +base14. Agree the value with base14 and keep it **constant** across builds and +environments. Use `service.version` for build axes and `environment` for +deployment axes - never encode those into `service.name`, or your data +fragments into many "apps". + +### `[R]` resource vs `[S]` span + +Throughout this guide: + +- **`[R]`** marks a **resource** attribute - set once per export on the + OpenTelemetry `Resource`. +- **`[S]`** marks a **span** attribute - set per span. + +Putting a span key on the resource (or vice versa) is the most common reason a +view comes up empty. + +### Duration units are not uniform + +Most durations are in **seconds**, but app startup is in **milliseconds**. + +| Attribute | Unit | +| --------- | ---- | +| `screen.load_time` | seconds | +| `view.time_spent` | seconds | +| `long_task.duration` | seconds | +| `anr.duration` | seconds | +| `app_startup.duration` | **milliseconds** | + +:::warning +`app_startup.duration` is the one exception - it is in milliseconds. Sending it +in seconds makes every startup look ~1000x too fast. +::: + +--- + +## Shared Attribute Sets + +To avoid repeating the same lists on every span, this guide refers to two +shared sets. + +### Standard resource set `[R]` + +Unless a span says otherwise, it carries these resource attributes: + +```text +service.name, service.version, environment, +os.name, os.version, +device.manufacturer, device.model.name, +network.connection.type +``` + +Crash-related spans (`error`, `native_crash`, `app_crash`) add: + +```text +host.arch, app.version, app.build, app.bundle_id +``` + +### Standard session identity `[S]` + +Unless a span says otherwise, it carries this identity block: + +```text +session.id, session.start_time, session.sampled, +session.sample_rate, session.type, +user.id, user.anonymous_id, +screen.name +``` + +- `session.start_time` - ISO-8601; constant for the session's whole life. +- `user.id` / `user.anonymous_id` - send at least one. The crash **Affected + Users** panel is populated from these, so set them on crash spans too. + +--- + +## Spans + +Each span is recognized by its **exact** `span.name`. All RUM spans use +`SpanKind = Internal`. + +### `screen_view` + +A screen or route was shown. + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `view.id` | Unique id for this view instance | +| `view.loading_type` | `initial_load` or `route_change` | +| `view.is_active` | Whether the view is currently active | +| `view.referrer` | The previous screen/route | + +**Powers:** screen list and per-screen stats, session screen counts, active +users. + +### `screen_load` + +Time to display a screen. + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `screen.load_time` | Load time in **seconds** (float) | + +**Powers:** average and p95 screen-load time per screen. + +### `view_session` + +Time spent on a screen. Emit when leaving it. + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `view.time_spent` | Time on screen in **seconds** (float) | + +**Powers:** average time-spent per screen. + +### `long_task` + +A main-thread block / jank event. + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `long_task.duration` | Block duration in **seconds** | +| `long_task.threshold` | Threshold that classified it, in **seconds** | +| `display.scroll.max_depth` | Max scroll depth reached | +| `display.scroll.max_depth_scroll_top` | Scroll-top at max depth | +| `display.scroll.max_scroll_height` | Max scrollable height | +| `display.scroll.max_scroll_height_time_ms` | Time to reach max height (ms) | + +**Powers:** long-task counts per screen; session timeline. + +### `http.request` + +A network request. + +:::warning Span name and dual keys +The span name must be exactly `http.request` (not `http`), or no network data +is recorded. Send **both** keys in each pair below with the **same value** - +different views read different names. Request latency is taken from the span's +own start/end time, so set those correctly. +::: + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute(s) | Description | +| ------------ | ----------- | +| `url.full` **and** `http.url` | Full URL (same value in both) | +| `http.request.method` **and** `http.method` | Method (same value in both) | +| `http.response.status_code` **and** `http.status_code` | Status (same value in both) | +| `http.duration_ms` | Latency in ms | +| `http.response.body.size` | Response body size | +| `http.error` | Error flag/message, if the request failed | + +**Powers:** network dashboard (top endpoints, error rate, latency +p50/p95/p99); session timeline. + +### `app_startup` + +A cold or warm start. + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `app_startup.type` | `cold` or `warm` | +| `app_startup.duration` | Startup time in **milliseconds** (not seconds) | + +**Powers:** average cold/warm start, cold/warm counts. + +### `error` + +A handled or unhandled error (JS / Dart / app-level). `app_crash` is treated as +the same `javascript` kind as `error` and shares this attribute set (grouped by +`error.message`). + +- **Resource:** standard set **+ crash additions** +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `error.message` | Title and grouping key - keep it **stable** (no timestamps/ids) | +| `error.type` | Error type/class | +| `error.stack_trace` | Full stack trace | +| `error.handled` | Whether the error was caught | +| `error.library` | Library/framework that raised it | +| `breadcrumbs` | JSON array of `{time, type, message}` | +| `dart.build_id` | Dart build id (for symbol resolution) | + +**Powers:** crash list, crash detail, crash-free rate, per-user error counts. + +### `native_crash` + +A native crash (signal / Mach / exit-info / JVM). Grouped and addressed by +`(crash.type, crash.reason)`. + +- **Resource:** standard set **+ crash additions** +- **Span:** standard identity, plus the crash keys and detail below. + +**Crash keys (grouping):** + +| Attribute | Description | +| --------- | ----------- | +| `crash.type` | Grouping key | +| `crash.reason` | Grouping key / title | +| `crash.stack_trace` | Native stack trace | + +**Crash detail** (send what the platform provides): + +| Group | Attributes | +| ----- | ---------- | +| Report / identity | `crash.timestamp`, `crash.report_id`, `crash.last_screen`, `crash.previous_session_id`, `crash.started_at`, `crash.status`, `crash.error_type`, `crash.subreason` | +| Signal / Mach (Apple) | `crash.signal`, `crash.signal_code`, `crash.signal_address`, `crash.mach_exception`, `crash.mach_code`, `crash.mach_subcode`, `crash.nsexception_name`, `crash.exception_type`, `crash.exception_code`, `crash.cpp_exception_name`, `crash.fault_address_register`, `crash.exception_syndrome_register`, `crash.os_reason_code`, `crash.os_reason_name` | +| Thread / process | `crash.thread`, `crash.thread_name`, `crash.process_name`, `crash.queue`, `crash.pid`, `crash.tid`, `crash.uid`, `crash.ppid`, `crash.process_uptime_secs`, `crash.importance` | +| Memory | `crash.pss_kb`, `crash.rss_kb`, `crash.hang_duration_ms` | +| Device / OS / build | `crash.cpu_arch`, `crash.machine`, `crash.os_name`, `crash.os_version`, `crash.kernel_version`, `crash.kernel`, `crash.device_model`, `crash.abi`, `crash.build_fingerprint`, `crash.build_type`, `crash.region_format` | +| App version | `crash.app_version`, `crash.application_version`, `crash.application_build_version`, `crash.bundle_id` | +| Android exit-info | `crash.exit_status`, `crash.death_timestamp_ms` | +| Heavy blobs (raw JSON / text) | `crash.tombstone`, `crash.binary_images_json`, `crash.registers_json`, `crash.callstack_tree_json`, `crash.memory_map`, `crash.registers` | +| Breadcrumbs | `breadcrumbs` - JSON array of `{time, type, message}` | + +**Powers:** native crash list and detail, crash-free rate, affected +devices/users, frequency over time, top crashing screens, post-crash recovery +flag. + +### `app_crash` + +An app-level crash. Handled together with `error` (the `javascript` crash +kind), grouped by `error.message`. + +- **Resource:** standard set **+ crash additions** +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `error.message` | Title and grouping key - keep it **stable** | +| `crash.type` | Crash type | +| `crash.last_screen` | Screen active when the crash occurred | + +### `anr` + +Application Not Responding (Android). Grouped and scoped by `screen.name`. + +- **Resource:** standard set +- **Span:** standard identity, plus: + +| Attribute | Description | +| --------- | ----------- | +| `anr.duration` | ANR duration in **seconds** | +| `anr.threshold` | Threshold that classified it, in **seconds** | +| `anr.main_thread_stack` | Main-thread stack at the freeze | +| `anr.thread_count` | Number of threads captured | +| `anr.threads_json` | All-threads dump (JSON) | + +**Powers:** ANR list/detail, ANR duration by app-version/OS/device. + +### `user_interaction` + +A tap/click, for the session timeline. + +- **Resource:** `service.name`, `environment`, `os.name`, `device.model.name` +- **Span:** `session.id`, `session.start_time`, `user.id`, + `user.anonymous_id`, `screen.name`, plus: + +| Attribute | Description | +| --------- | ----------- | +| `user_interaction.target` | Tapped element's label (mobile) | +| `user_interaction.target.type` | Element type | +| `target_element` | Tapped element (web) | +| `target_xpath` | Element xpath (web) | +| `user_interaction.type` | e.g. `tap` | +| `user_interaction.target.name_source` | Source of the target's name | +| `user_interaction.target.permanent_id` | Stable element id | +| `user_interaction.target.x` / `.y` | Tap coordinates | +| `user_interaction.id` | Unique id for the interaction | + +**Powers:** session timeline (tap events). + +### `app_vital` + +FBC / interaction-to-next-view vitals, for the session timeline. + +- **Resource:** `service.name`, `environment`, `os.name` +- **Span:** `session.id`, `session.start_time`, `user.id`, + `user.anonymous_id`, `screen.name`, plus: + +| Attribute | Description | +| --------- | ----------- | +| `vital.name` | e.g. `fbc`, `inv` | +| `vital.type` | `startup` or `navigation` | +| `vital.duration_ms` | Duration in ms | +| `vital.from_screen` | Source screen | +| `vital.to_screen` | Destination screen | + +**Powers:** session timeline (vitals). + +### `frozen_frame` + +A frozen frame, for the session timeline. + +- **Span:** `session.id`, `session.start_time`, `user.id`, + `user.anonymous_id`, `screen.name`, plus: + +| Attribute | Description | +| --------- | ----------- | +| `frozen_frame.duration` | Frozen-frame duration | + +**Powers:** session timeline. + +### `web_vital` + +Core Web Vitals (web), for the session timeline. + +- **Span:** `session.id`, `session.start_time`, `user.id`, + `user.anonymous_id`, plus: + +| Attribute | Description | +| --------- | ----------- | +| `web.vital.name` | Vital name (e.g. LCP, CLS) | +| `web.vital.value` | Measured value | +| `web.vital.rating` | Rating bucket (good / needs-improvement / poor) | + +**Powers:** session timeline. + +--- + +## Minimum Viable Payload + +To get RUM working with the smallest possible surface: + +**On every export (resource):** + +```text +service.name, environment, service.version, +os.name, os.version, +device.model.name, device.manufacturer, +network.connection.type +``` + +**On every span:** + +```text +session.id, session.start_time, session.sampled +user.id or user.anonymous_id +``` + +Mirror the user identity onto crash spans so **Affected Users** counts work. + +**Emit at least these spans:** + +- `screen_view` - with `screen.name` +- `app_startup` - with `app_startup.type` and `app_startup.duration` (ms) +- `http.request` - with span duration set and the HTTP key pairs from + [`http.request`](#httprequest) +- `error` and/or `native_crash` - with a stable `error.message` / + `crash.reason` + +Add `screen_load`, `view_session`, `long_task`, and `anr` for full +screen-performance and stability coverage. + +--- + +## Common Mistakes + +| Symptom | Cause and fix | +| ------- | ------------- | +| Data fragments into many "apps" | A changing `service.name` per build/env. Keep it fixed; use `environment` / `service.version` for those axes. | +| A view is empty | Resource keys on the span, or span keys on the resource. `service.version` / `os.*` / `device.*` are `[R]`; `session.*` / `user.*` / `screen.name` / per-span fields are `[S]`. | +| Crash **Affected Users** empty | The panel reads `user.id` / `user.anonymous_id`. Set them on crash spans too. | +| Every startup looks ~1000x too fast | `app_startup.duration` sent in seconds - it must be **milliseconds**. | +| No network data / partial network views | Only one HTTP naming convention sent. Send both `url.full` + `http.url`, `http.request.method` + `http.method`, `http.response.status_code` + `http.status_code`, and set the span's own duration. | +| Crashes don't group (one row each) | Unstable `error.message` / `crash.reason` containing timestamps or ids. Keep titles stable. | +| No network data at all | Span named `http` instead of `http.request`. | +| Session never registers | Missing or unparseable `session.start_time`. Send valid ISO-8601. | + +--- + +## Related Guides + +- [RUM Overview](../../operate/rum/overview.md) - the product these spans power +- [Instrument a Flutter app](./flutter.md) - a prebuilt SDK that emits all of + the above +- [Sessions](../../operate/rum/sessions.md) - how session-timeline spans render +- [Crashes](../../operate/rum/crashes.md) - how crash spans render diff --git a/docs/operate/rum/_category_.json b/docs/operate/rum/_category_.json new file mode 100644 index 00000000..08f1b45b --- /dev/null +++ b/docs/operate/rum/_category_.json @@ -0,0 +1,9 @@ +{ + "label": "RUM", + "position": 8, + "link": { + "type": "generated-index", + "title": "Mobile Real User Monitoring with RUM", + "description": "Monitor real mobile user experience with RUM in base14 Scout. Track crash-free rates, app startup performance, screen load times, network calls, and session timelines for your Flutter applications." + } +} diff --git a/docs/operate/rum/anr.md b/docs/operate/rum/anr.md new file mode 100644 index 00000000..b914cf06 --- /dev/null +++ b/docs/operate/rum/anr.md @@ -0,0 +1,147 @@ +--- +title: RUM ANR +sidebar_label: ANR +sidebar_position: 5 +description: + Detect Application Not Responding (ANR) events in your Flutter apps with RUM + in base14 Scout. Group frozen-UI events by screen and analyze thread state + to find what blocked the main thread. +keywords: + [ + rum, + anr, + application not responding, + frozen ui, + mobile performance, + jank, + base14, + scout, + ] +--- + +The **ANR** (Application Not Responding) tab tracks frozen-UI events - periods +where the app's main thread was blocked and unresponsive to user input - +grouped by the screen where they occurred. + +![ANR](/img/rum/anr/list.png) + +--- + +## ANR List + +### Table Columns + +| Column | Description | +| ------ | ----------- | +| **Screen** | The screen the ANR occurred on (or `unknown` if it couldn't be attributed to a screen) | +| **Occurrences** | Total times an ANR was recorded for this screen | +| **Sessions** | Number of distinct sessions affected | +| **Users** | Number of distinct users affected | +| **App Version** | Version most recently associated with this screen's ANRs | +| **Last Seen** | When an ANR was last observed on this screen | + +The **Errors** filter category (`error.message`, `crash.kind`, `crash.type`, +`crash.last_screen`) is available here too, alongside the shared +[Filters](./getting-started.md#filters) sidebar. + +--- + +## ANR Details + +Click a screen's ANR group to open the detail view, scoped to a specific +occurrence. + +### Summary Stats + +![ANR title, badges, and Total Occurrences/Affected Users/Affected Sessions stat cards](/img/rum/anr/summary-stats.png) + +**Total Occurrences**, **Affected Users**, and **Affected Sessions** for the +selected screen and time range. + +### Occurrence Breakdown + +![Occurrences by App Version, OS Version, and Device Model charts](/img/rum/anr/occurrence-breakdown.png) + +Here - unlike the list page - occurrences are broken down **by App +Version**, **by OS Version**, and **by Device Model**, each with the usual +multi-line-chart-plus-table pattern. This is where you find out which builds +and devices freeze most often for this screen. + +### Attributes + +![Attributes panel showing app.*, device.*, session.*, and other grouped attributes](/img/rum/anr/attributes.png) + +A grouped attribute panel: + +| Group | Example attributes | +| ----- | ------------------- | +| `app.*` | `app.build`, `app.bundle_id`, `app.version` | +| `crash.*` | `crash.type` (`anr`) | +| `device.*` | `device.brand`, `device.manufacturer`, `device.model.name`, `device.locale`, `device.orientation`, `device.type` | +| `error.*` | `error.message` (for example "Application Not Responding") | +| `os.*` | `os.name`, `os.version`, `os.build` | +| `screen.*` | `screen.name` | +| `service.*` | `service.name`, `service.version` | +| `session.*` | `session.id`, `session.sample_rate`, `session.start_time`, `session.type` | +| `telemetry.sdk.*` | `telemetry.sdk.name`, `telemetry.sdk.language`, `telemetry.sdk.version` | +| `user.*` | `user.anonymous_id` | + +### Stack Trace (Main Thread) and All Threads + +![Stack Trace (Main Thread) frames and All Threads list with state badges and frame counts](/img/rum/anr/stack-trace.png) + +The **Stack Trace (Main Thread)** panel shows where the main thread was +blocked. Below it, **All Threads** lists every thread with its state +(`RUNNABLE`, `TIMED_WAITING`, `WAITING`) and frame count - expand a thread to +see its own stack. This is how you find which thread was holding the lock +the main thread was waiting on. + +As with [crash stack traces](./crashes.md#stack-trace-and-translated-report), +frames resolve to readable file, line, and symbol names once the matching +debug artifacts for that build have been uploaded. + +### Breadcrumbs + +![Breadcrumbs table with Time, Type, and Message columns](/img/rum/anr/breadcrumbs.png) + +A chronological table (**Time**, **Type**, **Message**) of lifecycle, +navigation, and tap events leading up to the freeze. + +### Affected Devices and Affected Users + +![Affected Devices and Affected Users tables](/img/rum/anr/affected.png) + +Same structure as [Crashes](./crashes.md#affected-devices-and-affected-users). + +Use **View Session Timeline** to jump into the full +[session](./sessions.md) where the ANR occurred. + +--- + +## Use Cases + +### Finding the Worst Frozen Screen + +1. Sort the **ANR List** by **Occurrences** +2. Open the top screen and check **Occurrences by App Version** to see if + it's a regression in a specific release +3. Use **All Threads** to identify what was blocking the main thread (a + `RUNNABLE` thread holding a lock the main thread is `WAITING` on is a + common culprit) + +### Confirming a Fix Reduced Freezes + +1. Open the screen's ANR group +2. Filter to the version containing the fix +3. Confirm **Occurrences by App Version** drops for that version + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Overview](./overview.md) - ANR duration trend alongside crashes and sessions +- [Screens](./screens.md) - Per-screen performance, including jank and load time +- [Sessions](./sessions.md) - Full session timeline for a specific occurrence +- [traceX](../tracex/index.md) - Distributed tracing explorer +- [logX](../logx/index.md) - Log explorer with trace correlation diff --git a/docs/operate/rum/crashes.md b/docs/operate/rum/crashes.md new file mode 100644 index 00000000..ca79c9e9 --- /dev/null +++ b/docs/operate/rum/crashes.md @@ -0,0 +1,177 @@ +--- +title: RUM Crashes +sidebar_label: Crashes +sidebar_position: 3 +description: + Investigate mobile app crashes with RUM in base14 Scout. Group crashes, + view symbolicated stack traces and translated crash reports, and see + affected devices, users, app versions, and OS versions. +keywords: + [ + rum, + crashes, + crash reporting, + symbolication, + stack trace, + native crash, + mobile crash, + base14, + scout, + ] +--- + +The **Crashes** tab groups individual crash events into deduplicated crash +groups so you can prioritize by impact instead of triaging one crash at a +time. + +![Crashes List](/img/rum/crashes/list.png) + +--- + +## Crash List + +Filter chips at the top let you toggle between crash **Kind** values; the +table below lists every crash group ranked by occurrence. + +### Table Columns + +| Column | Description | +| ------ | ----------- | +| **Title** | The crash's grouping title (exception name or synthetic label) | +| **Kind** | High-level classification badge for the crash, for example `Native` or `JS Error` | +| **Type** | More specific classification, for example `native_signal`, `mach`, `jvm_exception`, `jvm_crash`, `exit_self`, `excessive_resources`, `user_requested`, `unknown` | +| **Occurrences** | Total times this crash group has been seen | +| **Sessions** | Number of distinct sessions affected | +| **Users** | Number of distinct users affected | +| **App Version** | Version most recently associated with the group | +| **Last Seen** | When the crash group was last observed | + +Sort by **Occurrences** to prioritize the crashes affecting the most sessions +first. + +--- + +## Crash Details + +Click a crash group to open the detail view, scoped to a specific occurrence +(pick a different occurrence from the dropdown at the top). + +### Summary Stats + +![Crash title, Kind/Type badges, and Total Occurrences/Affected Users/Affected Sessions stat cards](/img/rum/crashes/summary-stats.png) + +**Total Occurrences**, **Affected Users**, and **Affected Sessions** for the +selected crash group and time range. + +### Occurrence Breakdown + +![Occurrences by App Version, OS Version, and Device Model charts](/img/rum/crashes/occurrence-breakdown.png) + +Three charts pair a multi-line time series with a Name / Min / Mean / Max +table, showing how many occurrences hit each App Version, OS Version, and +Device Model: + +- **Occurrences by App Version** +- **Occurrences by OS Version** +- **Occurrences by Device Model** + +### Attributes + +![Attributes panel showing app.*, crash.*, and other grouped attributes](/img/rum/crashes/attributes.png) + +A scrollable panel with the full attribute set captured at crash time. A +small `app.*` group sits above a single large `crash.*` block - the raw +crash report, flattened - followed by the same resource attributes you see +on other detail pages: + +| Group | Example attributes | +| ----- | ------------------- | +| `app.*` | `app.build`, `app.bundle_id`, `app.launch_id`, `app.version` | +| `crash.*` (app state) | `crash.app_id`, `crash.app_version`, `crash.app_in_foreground`, `crash.app_start_time`, `crash.app_sessions_since_launch` | +| `crash.*` (binary/build) | `crash.binary_cpu_type`, `crash.build_configuration`, `crash.build_type` | +| `crash.*` (process/report) | `crash.pid`, `crash.parent_pid`, `crash.process_name`, `crash.report_id`, `crash.report_type` | +| `crash.*` (signal/memory/threads) | `crash.signal`, `crash.signal_code`, `crash.memory_usable_bytes`, `crash.thread_count` | +| `crash.*` (type/timing) | `crash.type`, `crash.timestamp`, `crash.time_zone`, `crash.translated` | +| `device.*` | `device.model.name`, `device.locale`, `device.timezone`, `device.is_physical` | +| `host.*` | `host.arch`, `host.name`, `host.os.name`, `host.processors` | +| `os.*` | `os.name`, `os.version`, `os.build`, `os.type` | +| `process.*` | `process.executable.name`, `process.num_threads`, `process.runtime.name`, `process.runtime.version` | +| `service.*` / `session.*` | `service.name`, `service.version`, `session.id`, `session.start_time` | + +Use **Search attributes** in the sidebar to jump straight to a specific key +instead of scrolling. + +### Stack Trace and Translated Report + +![Stack Trace (Native) frames and Translated Report text block](/img/rum/crashes/stack-trace.png) + +The **Stack Trace (Native)** panel shows the raw symbolicated frames. Below +it, **Translated Report** renders the full platform crash report (process +info, exception type and codes, thread and register state, binary images) as +plain text, with a **Copy** button so you can paste it straight into an issue +tracker or share it with a native engineer. + +Frames only resolve to readable file, line, and symbol names once you've +uploaded the matching debug artifacts for that build (dSYM, Dart symbols, +NDK symbols, ProGuard mappings) - see +[scout artifacts upload](../../scout-cli/scout-access/artifacts.md). Without +an uploaded artifact, frames show raw addresses or obfuscated names instead. + +### Breadcrumbs + +![Breadcrumbs table with Time, Type, and Message columns](/img/rum/crashes/breadcrumbs.png) + +A chronological table (**Time**, **Type**, **Message**) of what the user was +doing right before the crash: session start, screen navigation, taps, long +tasks, and UI hangs. Use it to reproduce the exact sequence that triggered the +crash. + +### Affected Devices and Affected Users + +![Affected Devices and Affected Users tables](/img/rum/crashes/affected.png) + +- **Affected Devices** - device model, architecture, OS, app version, and + occurrence count +- **Affected Users** - user identifier, session count, crash count, and last + hit + +Use **View Session Timeline** to jump from a specific occurrence into the +full [session](./sessions.md) where it happened. + +--- + +## Use Cases + +### Triaging After a Release + +1. Filter by the new **App Version** +2. Sort the **Crash List** by **Occurrences** +3. Open the top crash group and check **Occurrences by App Version** to + confirm it's new (or worse) in this release +4. Use the **Translated Report** and **Breadcrumbs** to hand a native + engineer a reproducible sequence + +### Verifying a Fix + +1. Open the crash group you fixed +2. Filter to the version containing the fix +3. Confirm **Occurrences by App Version** shows zero (or near-zero) for that + version + +### Scoping a Device-Specific Crash + +1. Sort the **Crash List** by **Occurrences** +2. Open a crash group and check **Occurrences by Device Model** - a spike + concentrated on one model points at a device-specific bug (memory limits, + OS fork behavior) + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Overview](./overview.md) - Crash trends alongside sessions and ANR +- [Errors](./errors.md) - Non-fatal errors, for issues that don't crash the app +- [Sessions](./sessions.md) - Full session timeline for a specific occurrence +- [traceX](../tracex/index.md) - Distributed tracing explorer +- [logX](../logx/index.md) - Log explorer with trace correlation diff --git a/docs/operate/rum/errors.md b/docs/operate/rum/errors.md new file mode 100644 index 00000000..668d2f27 --- /dev/null +++ b/docs/operate/rum/errors.md @@ -0,0 +1,147 @@ +--- +title: RUM Errors +sidebar_label: Errors +sidebar_position: 4 +description: + Track non-fatal errors in your Flutter apps with RUM in base14 Scout. Group + and rank errors by occurrence, inspect stack traces and breadcrumbs, and + prioritize fixes. +keywords: + [ + rum, + errors, + non-fatal errors, + dart errors, + flutter errors, + mobile errors, + base14, + scout, + ] +--- + +The **Errors** tab surfaces non-fatal errors reported by the app, grouped and +ranked by occurrence so you can prioritize the errors affecting the most +users. Use it alongside [Crashes](./crashes.md) to separate fatal crashes from +recoverable errors. + +![Errors](/img/rum/errors/list.png) + +--- + +## Error List + +### Table Columns + +| Column | Description | +| ------ | ----------- | +| **Title** | The error's grouping title (exception message or a custom label) | +| **Kind** | High-level classification badge for the error | +| **Type** | More specific classification, for example `flutter_error` (framework-level, such as widget build/layout errors), `uncaught_error` (unhandled Dart exceptions), or `manual_error` (explicitly reported via the SDK) | +| **Occurrences** | Total times this error group has been seen | +| **Sessions** | Number of distinct sessions affected | +| **Users** | Number of distinct users affected | +| **App Version** | Version most recently associated with the group | +| **Last Seen** | When the error group was last observed | + +The **Errors** filter category adds `error.message`, `crash.kind`, +`crash.type`, and `crash.last_screen` to the shared +[Filters](./getting-started.md#filters) sidebar. + +--- + +## Error Details + +Click an error group to open the detail view. The header shows the exception +message along with badges for its **Type** and whether it was +**`error.handled`**. + +### Summary Stats + +![Error title, Type/handled badges, and Total Occurrences/Affected Users/Affected Sessions stat cards](/img/rum/errors/summary-stats.png) + +**Total Occurrences**, **Affected Users**, and **Affected Sessions** for the +selected error group and time range. + +### Occurrence Breakdown + +![Occurrences by App Version, OS Version, and Device Model charts](/img/rum/errors/occurrence-breakdown.png) + +**Occurrences by App Version**, **by OS Version**, and **by Device Model** - +the same multi-line-chart-plus-table pattern used throughout RUM, so you can +see which versions or devices hit this error most. + +### Attributes + +![Attributes panel showing app.*, device.*, error.*, and other grouped attributes](/img/rum/errors/attributes.png) + +A grouped attribute panel, similar to [Crashes](./crashes.md#attributes): + +| Group | Example attributes | +| ----- | ------------------- | +| `error.*` | `error.message`, `error.type`, `error.handled`, `error.source`, `error.source_type`, `error.fingerprint` | +| `app.*` | `app.build`, `app.bundle_id`, `app.launch_id`, `app.version`, `build.channel` | +| `device.*` | `device.model.name`, `device.locale`, `device.timezone`, `device.is_physical`, `device.is_jail_broken` | +| `os.*` | `os.name`, `os.version`, `os.build` | +| `process.*` | `process.runtime.name`, `process.runtime.version`, `process.num_threads` | +| `session.*` | `session.id`, `session.type`, `session.start_time` | +| `user.*` | `user.id`, `user.anonymous_id` (only present once the app identifies the user) | +| custom | feature flags and experiment attributes your app attaches, for example `feature_flag.v2_checkout`, `experiment.recommendation_model` | + +`error.source_type` shows the layer that reported the error (for example +`flutter` for framework-level errors, `custom` for manually-reported ones). + +### Stack Trace + +![Numbered stack trace frames with package paths](/img/rum/errors/stack-trace.png) + +Numbered frames pointing to the exact source location, including package +paths - useful for tracing framework-level errors (`flutter_error`) back to +the widget or gesture handler that triggered them. + +If the app is built with `flutter build --split-debug-info`, frames need the +matching Dart symbols/obfuscation map uploaded to resolve past raw addresses - +see [scout artifacts upload](../../scout-cli/scout-access/artifacts.md). + +### Breadcrumbs + +![Breadcrumbs table with Time, Type, and Message columns](/img/rum/errors/breadcrumbs.png) + +A chronological table (**Time**, **Type**, **Message**) of what happened +before the error: session start, navigation, taps, long tasks, and UI hangs. + +### Affected Devices and Affected Users + +![Affected Devices and Affected Users tables](/img/rum/errors/affected.png) + +Same structure as [Crashes](./crashes.md#affected-devices-and-affected-users): +device/OS/app-version breakdown and per-user occurrence counts. + +Use **View Session Timeline** to open the full [session](./sessions.md) where +the error was thrown. + +--- + +## Use Cases + +### Prioritizing Non-Fatal Fixes + +1. Sort the **Error List** by **Occurrences** +2. Check **Sessions**/**Users** to weigh reach vs. raw count +3. Open the top group and use **Stack Trace** + **Breadcrumbs** to reproduce it + +### Separating Framework Bugs from App Bugs + +1. Filter by **Type** = `flutter_error` to isolate framework-level issues + (layout overflows, `setState` misuse) versus `uncaught_error` + (application-level exceptions) +2. Triage each category with a different owner if useful + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Crashes](./crashes.md) - Fatal crashes and symbolicated stack traces +- [Sessions](./sessions.md) - Full session timeline for a specific occurrence +- [traceX](../tracex/index.md) - Distributed tracing explorer +- [logX](../logx/index.md) - Log explorer with trace correlation diff --git a/docs/operate/rum/getting-started.md b/docs/operate/rum/getting-started.md new file mode 100644 index 00000000..81972efe --- /dev/null +++ b/docs/operate/rum/getting-started.md @@ -0,0 +1,131 @@ +--- +title: Getting Started with RUM +sidebar_label: Getting Started +sidebar_position: 1 +description: + Get started with RUM in base14 Scout. Learn the interface, select a mobile + application, and set a time range to monitor real user experience for your + Flutter apps. +keywords: + [ + rum, + real user monitoring, + mobile monitoring, + flutter monitoring, + getting started, + base14, + scout, + ] +--- + +RUM (Real User Monitoring) is a mobile monitoring app built into Scout. +It gives you visibility into how real users experience your mobile +applications: tracking crashes, errors, ANRs, app startup, screen performance, +network calls, and full session timelines. + +RUM queries mobile telemetry stored in the Scout Telemetry Data Lake and +correlates crashes, sessions, and screens so you can move from a symptom +(a crash spike) to a root cause (a specific screen, app version, or device) in +a few clicks. Every attribute you see throughout RUM - `service.name`, +`device.model.name`, `session.id`, and the rest - is a standard OpenTelemetry +resource or span attribute, so this data lines up directly with any traces and +logs you already send to Scout. + +--- + +## Before You Start + +This page assumes your app is already sending telemetry to Scout. See +[Instrument a Flutter app](../../instrument/mobile/flutter.md) for SDK setup. +By default the SDK batches and compresses telemetry (roughly 2-4 KB/s in +normal use) and buffers to disk when offline - see +[Performance considerations](../../instrument/mobile/flutter.md#performance-considerations) +for the full breakdown. + +--- + +## Interface Overview + +Every RUM tab shares the same layout: + +![Application selector, environment selector, search bar, and time picker](/img/rum/getting-started/interface-chrome.png) + +| Section | Description | +| ------- | ----------- | +| **Application Selector** | Choose which mobile application to inspect (top left) | +| **Environment Selector** | Scope data to a specific environment, or All | +| **Search Attributes** | Free-text search across the attributes available on the page | +| **Navigation Tabs** | Switch between Overview, Crashes, Errors, ANR, Sessions, Screens, Network, and Users | +| **Time Picker** | Set the time range for every panel on the page | +| **Filters Sidebar** | Slice every panel by device, app, session, network, and user attributes | + +--- + +## Select an Application + +The **Applications** tab lists every mobile app reporting telemetry to Scout, +each tagged with its platform. + +1. Open the **Applications** tab +2. Select the application you want to monitor +3. RUM loads that app's data across all other tabs + +Each application card shows its **Crash-Free** rate, **Sessions**, **Active +Users**, and current **Version** for the selected time range, so you can spot +a struggling app before drilling in. + +![Applications](/img/rum/getting-started/applications.png) + +--- + +## Set the Time Range + +Use the time picker to scope every panel to a time window (for example, the +last 30 days). All charts, tables, and breakdowns update to the selected +range. + +--- + +## Filters + +Every RUM tab has a **Filters** sidebar for narrowing down to a specific slice +of traffic. The exact categories depend on the page, but five show up almost +everywhere: + +![Filters sidebar with Device, App, Session, and Network categories](/img/rum/getting-started/filters-sidebar.png) + +| Category | Common attributes | Use it to... | +| -------- | ------------------ | ------------ | +| **Device** | `os.name`, `os.version`, `device.manufacturer`, `device.model.name` | Isolate a specific OS version or device model | +| **App** | `service.version` | Compare behavior across app releases | +| **Session** | `session.id`, `session.sample_rate` | Jump to a specific session | +| **Network** | `network.connection.type` | Separate wifi from cellular behavior | +| **User** | `user.id`, `user.anonymous_id` | Investigate a single user's experience | + +Some pages layer on their own attributes: Crashes, Errors, and ANR add an +**Errors** category (`error.message`, `crash.kind`, `crash.type`, +`crash.last_screen`); Network adds HTTP attributes +(`http.host`, `http.route`, `http.method`, `http.status_code`); Users adds +richer user identity attributes (`user.email`, `user.name`, `user.phone`, +`user.plan`, `user.tenant`). Each page's guide below calls out what's specific +to it. + +User-identifying attributes only show up here if your app sets them - the SDK +doesn't capture them by default. If you do set them, `beforeSend` lets you +redact or drop specific attributes before they're exported; see +[Security considerations](../../instrument/mobile/flutter.md#security-considerations). + +--- + +## Related Guides + +- [Overview](./overview.md) - Health-at-a-glance dashboard +- [Crashes](./crashes.md) - Crash groups and symbolicated stack traces +- [Errors](./errors.md) - Non-fatal error groups +- [ANR](./anr.md) - Frozen-UI events +- [Sessions](./sessions.md) - Session list and event timelines +- [Screens](./screens.md) - Per-screen performance +- [Network](./network.md) - API and network performance +- [Users](./users.md) - Per-user activity and history +- [Instrument a Flutter app](../../instrument/mobile/flutter.md) - SDK setup + and configuration diff --git a/docs/operate/rum/network.md b/docs/operate/rum/network.md new file mode 100644 index 00000000..05e9bab3 --- /dev/null +++ b/docs/operate/rum/network.md @@ -0,0 +1,97 @@ +--- +title: RUM Network +sidebar_label: Network +sidebar_position: 8 +description: + Analyze API and network performance from the mobile client's perspective + with RUM in base14 Scout. Track response times, error rates, and failed + requests by endpoint. +keywords: + [ + rum, + network, + api performance, + response time, + error rate, + failed requests, + mobile network, + base14, + scout, + ] +--- + +The **Network** tab surfaces API and network performance from the mobile +client's perspective - what your app actually experienced, not what your +backend logs say it sent. + +--- + +## Avg Response Time by Endpoint + +![Avg Response Time by Endpoint (top 10) chart with Name/Min/Mean/Max table](/img/rum/network/avg-response-time.png) + +A time-series chart of the top 10 endpoints by response time, with a +Name / Min / Mean / Max table underneath so you can spot both a slow trend +and its worst-case latency per endpoint. + +--- + +## All Endpoints + +![All Endpoints table with URL, Method, Avg Duration, Error Rate, and Requests columns](/img/rum/network/all-endpoints.png) + +A table of every endpoint the app called: + +| Column | Description | +| ------ | ----------- | +| **URL** | The endpoint path | +| **Method** | HTTP method | +| **Avg Duration** | Average response time | +| **Error Rate** | Percentage of requests that failed | +| **Requests** | Total request count | + +Sort by **Error Rate** or **Requests** to find the endpoints worth +investigating first. + +--- + +## Failed Requests + +A table scoped to just the failing calls: **URL**, **Method**, **Status**, +**Occurrences**, and **First/Last Seen** - useful for catching an endpoint +that's failing consistently even if its overall request volume is low enough +to not stand out in **All Endpoints**. + +--- + +## Filters + +Network adds HTTP-specific attributes to the shared +[Filters](./getting-started.md#filters) sidebar: `http.host`, `http.route`, +`http.method`, `http.status_code`, and `network.connection.type` - use these +to scope every panel above to a specific host, route, verb, status class, or +connection type. + +--- + +## Use Cases + +### Finding a Slow Endpoint + +1. Check **Avg Response Time by Endpoint** for the top 10 offenders +2. Cross-check **All Endpoints**, sorted by **Avg Duration**, for anything + outside the top 10 that's still slow relative to its request volume + +### Catching a Silently Failing Endpoint + +1. Sort **All Endpoints** by **Error Rate** +2. Open **Failed Requests** and filter by `http.route` to confirm the + failure pattern (a specific status code, a specific host) + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Sessions](./sessions.md) - See individual `http_request` events in context +- [Screens](./screens.md) - Screen-level performance, for issues that aren't network-bound diff --git a/docs/operate/rum/overview.md b/docs/operate/rum/overview.md new file mode 100644 index 00000000..318f9450 --- /dev/null +++ b/docs/operate/rum/overview.md @@ -0,0 +1,159 @@ +--- +title: RUM Overview +sidebar_label: Overview +sidebar_position: 2 +description: + Monitor mobile app health at a glance with the RUM Overview dashboard in + base14 Scout. Track crash-free rate, sessions, active users, startup times, + and trends by app version, OS, and device. +keywords: + [ + rum, + overview, + crash-free rate, + mobile health, + app startup, + cold start, + warm start, + base14, + scout, + ] +--- + +The **Overview** tab is your health-at-a-glance dashboard for the selected +mobile application, combining top-line stats, trend charts, breakdowns by +app version/OS/device, and the screens most worth investigating. + +--- + +## Key Metrics + +![Crash-Free Sessions, Total Sessions, Active Users, Avg Cold Start, Avg Warm Start, and Total Errors stat cards](/img/rum/overview/key-metrics.png) + +| Metric | Description | +| ------ | ----------- | +| **Crash-Free Sessions** | Percentage of sessions with no crashes | +| **Total Sessions** | Number of user sessions in the range | +| **Active Users** | Distinct users in the range | +| **Avg Cold Start** | Average cold app-startup time, with a trend sparkline | +| **Avg Warm Start** | Average warm app-startup time, with a trend sparkline | +| **Total Errors** | Count of reported non-fatal errors | + +Use the shared [Filters](./getting-started.md#filters) sidebar (Device, App, +Session, Network) to scope every metric below to a specific slice of traffic. + +**Total Sessions** reflects the app's configured session sample rate (the SDK +defaults to sampling 1% of sessions). **Crash-Free Sessions** and +**Total Errors** aren't affected by that sampling - crash, error, and ANR +telemetry bypasses the session sample rate by default, so those counts stay +accurate even at a low sample rate. See +[Sessions](../../instrument/mobile/flutter.md#sessions) in the instrumentation +guide for how sampling is configured. + +--- + +## Trends Over Time + +Three daily time-series charts sit right under the Key Metrics row: + +![Sessions Over Time, Crashes Over Time, and ANR Duration Over Time charts](/img/rum/overview/trends.png) + +### Sessions Over Time + +Session volume per day. Use it to spot release-day spikes or a sudden drop in +traffic that might indicate an app outage or a broken build. + +### Crashes Over Time + +Crash volume per day. A spike here that lines up with a Sessions spike +usually means a release just went out; check [Crashes](./crashes.md) for +which crash groups are driving it. + +### ANR Duration Over Time + +Frozen-UI (ANR) duration per day. Sustained increases point at a regression +in a specific screen or build; cross-check against +[ANR](./anr.md) for the affected screens. + +--- + +## Detailed Breakdown + +Expand **Detailed Breakdown** to slice Crashes, Sessions, and ANR Duration +each three ways: by App Version, by OS Version, and by Device Model. Every +chart pairs a multi-line time series with a table of Name / Min / Mean / Max, +so you can see both the trend and the worst-case value per version, OS, or +device at a glance: + +- **Crashes by App Version / by OS Version / by Device Model** + + ![Crashes broken down by App Version, OS Version, and Device Model](/img/rum/overview/breakdown-crashes.png) + +- **Sessions by App Version / by OS Version / by Device Model** + + ![Sessions broken down by App Version, OS Version, and Device Model](/img/rum/overview/breakdown-sessions.png) + +- **ANR Duration by App Version / by OS Version / by Device Model** + + ![ANR Duration broken down by App Version, OS Version, and Device Model](/img/rum/overview/breakdown-anr.png) + +This is the fastest way to answer "did the new release make things worse?" - +compare the latest app version's line against previous versions in the same +chart. + +--- + +## Top Screens + +Two tables at the bottom of the Overview surface the screens most worth +attention: + +![Top Crashing Screens and Slowest Screens tables](/img/rum/overview/top-screens.png) + +### Top Crashing Screens + +Columns: **Screen**, **Crashes**, **Last Seen**. Ranked by crash count over +the selected range. + +### Slowest Screens + +Columns: **Screen**, **Avg Load**, **Views**. Ranked by average load time. + +Click through to [Screens](./screens.md) for the full per-screen breakdown, +including frame timing and jank. + +--- + +## Use Cases + +### Morning Health Check + +1. Check **Crash-Free Sessions** and **Total Errors** against their usual + range +2. Scan **Sessions Over Time** and **Crashes Over Time** for overnight + anomalies +3. Glance at **Top Crashing Screens** for anything new + +### Post-Release Monitoring + +1. Filter by the new **App Version** in the Filters sidebar +2. Compare its line in the **Crashes by App Version** and + **ANR Duration by App Version** breakdowns against the previous version +3. If crashes or ANR duration are elevated, jump to + [Crashes](./crashes.md) or [ANR](./anr.md) to find the specific cause + +### Investigating a Spike + +1. Find the spike in **Crashes Over Time** or **ANR Duration Over Time** +2. Narrow the time picker to that window +3. Check **Top Crashing Screens** for the screen driving it, then open + [Crashes](./crashes.md) or [Screens](./screens.md) for details + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Crashes](./crashes.md) - Crash groups and symbolicated stack traces +- [Sessions](./sessions.md) - Session list and event timelines +- [Users](./users.md) - Per-user activity and history diff --git a/docs/operate/rum/screens.md b/docs/operate/rum/screens.md new file mode 100644 index 00000000..fc8a592e --- /dev/null +++ b/docs/operate/rum/screens.md @@ -0,0 +1,134 @@ +--- +title: RUM Screens +sidebar_label: Screens +sidebar_position: 7 +description: + Measure per-screen performance in your Flutter apps with RUM in base14 + Scout. Track load times, frame rendering, memory and CPU usage, jank, and + crashes by screen. +keywords: + [ + rum, + screens, + screen performance, + load time, + frame rendering, + jank, + memory usage, + mobile performance, + base14, + scout, + ] +--- + +The **Screens** tab measures per-screen performance across your app, so you +can find the slowest or jankiest screens without knowing what to look for +up front. + +![Screen Performance](/img/rum/screens/list.png) + +--- + +## Screen List + +Four stat tiles summarize the whole app before the table: **Total Screens**, +**Slowest Screen** (with its avg load time), **Most Janky** (with its long +task count), and **Most Crashing** (with its crash count). + +### Table Columns + +| Column | Description | +| ------ | ----------- | +| **Screen** | The screen's route/name | +| **Views** | Number of times the screen was viewed | +| **Unique Sessions** | Distinct sessions that viewed it (links to a filtered session list) | +| **Avg Load** | Average load time | +| **P95 Load** | 95th-percentile load time | +| **Avg Time Spent** | Average time users spent on the screen | +| **Long Tasks** | Count of long-running UI-thread tasks (jank) | +| **Crashes** | Crashes that occurred on this screen | + +Sort by **Avg Load** or **Long Tasks** to find the screens most in need of +optimization. + +--- + +## Screen Details + +Select a screen to see its full performance breakdown. + +### Summary Stats + +![Views, Unique Sessions, Avg Load Time, P95 Load Time, Long Tasks, and Crashes stat cards](/img/rum/screens/summary-stats.png) + +**Views**, **Unique Sessions**, **Avg Load Time**, **P95 Load Time**, +**Long Tasks**, and **Crashes** for the selected screen and time range. + +### Load Time Trend and Views Over Time + +![Load Time Trend chart and Views Over Time chart](/img/rum/screens/load-time-views.png) + +- **Load Time Trend** - Avg and p95 load time over the range, with a + Name / Min / Mean / Max table +- **Views Over Time** - view volume over the range + +### Rendering and Resource Usage + +![Frame Build Time and Frame Raster Time charts](/img/rum/screens/frame-timing.png) + +- **Frame Build Time** and **Frame Raster Time** - how long each frame took + to build (widget/layout work) versus rasterize (GPU work); sustained spikes + in either indicate jank + +![Memory Usage and CPU Usage charts](/img/rum/screens/resource-usage.png) + +- **Memory Usage** - resident memory over time +- **CPU Usage** - CPU utilization over time + +### Slowest Loads and Long Tasks + +![Slowest Loads and Long Tasks (Jank Events) tables](/img/rum/screens/slowest-loads-long-tasks.png) + +- **Slowest Loads** - table of individual slow page loads (**Time**, + **Load Time**, **User**, **Session**) +- **Long Tasks (Jank Events)** - table of individual long tasks (**Time**, + **Duration**, **User**, **Session**) + +Both tables link straight to the **User** and **Session** involved, and +support **Load more** to page through additional rows. + +### Crashes on this Screen + +![Crashes on this Screen table with Time, Error Type, Message, and Session columns](/img/rum/screens/crashes-on-screen.png) + +A table of crashes attributed to this screen (**Time**, **Error Type**, +**Message**, **Session**), or "No crashes on this screen" when there are +none in range. + +--- + +## Use Cases + +### Finding the Slowest Screen + +1. Check the **Slowest Screen** stat tile, or sort the **Screen List** by + **Avg Load** +2. Open the screen and check **Load Time Trend** for a gradual regression vs. + a one-time spike +3. Cross-check **Slowest Loads** for the specific sessions affected + +### Diagnosing Jank on a Screen + +1. Check the **Most Janky** stat tile, or sort by **Long Tasks** +2. Open the screen and compare **Frame Build Time** vs. **Frame Raster Time** + to narrow down whether it's widget/layout work or GPU work +3. Check **Long Tasks (Jank Events)** for the specific sessions and times + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Overview](./overview.md) - Top Crashing Screens and Slowest Screens at a glance +- [ANR](./anr.md) - Frozen-UI events grouped by screen +- [Sessions](./sessions.md) - Full session timeline for a specific view diff --git a/docs/operate/rum/sessions.md b/docs/operate/rum/sessions.md new file mode 100644 index 00000000..8791973b --- /dev/null +++ b/docs/operate/rum/sessions.md @@ -0,0 +1,143 @@ +--- +title: RUM Sessions +sidebar_label: Sessions +sidebar_position: 6 +description: + Inspect individual user sessions with RUM in base14 Scout. Review session + and device details, and a chronological event timeline of screen views, + taps, network calls, errors, and crashes. +keywords: + [ + rum, + sessions, + session timeline, + event timeline, + mobile sessions, + user interaction, + base14, + scout, + ] +--- + +The **Sessions** tab lists individual user sessions so you can go from an +aggregate stat straight to the exact session that produced it. + +![Sessions List](/img/rum/sessions/list.png) + +--- + +## Session List + +### Table Columns + +| Column | Description | +| ------ | ----------- | +| **Session ID** | Unique identifier for the session | +| **User** | The user's identifier | +| **Started At** | When the session began | +| **Duration** | How long the session lasted | +| **Screens** | Number of distinct screens viewed | +| **Errors** | Non-fatal errors during the session | +| **Crashes** | Crashes during the session | +| **Device** | Device model the session ran on | + +Sessions with one or more crashes are highlighted in the table so you can +spot them while scanning. Sort by **Duration** or **Errors** to find outliers +worth a closer look. + +The shared [Filters](./getting-started.md#filters) sidebar applies here too, +plus `user.anonymous_id` under the User category. + +--- + +## Session Timeline + +Click a session to open its timeline: a chronological view of everything +that happened during that session. + +### Session Attributes and Resource Attributes + +Two separate attribute panels: + +![Session Attributes panel with session.id, app_lifecycle.*, device, and user identifiers](/img/rum/sessions/session-attributes.png) + +- **Session Attributes** - `session.id`, `session.sample_rate`, + `session.sampled`, `session.start_time`, `session.type`, + `app_lifecycle.id`, `app_lifecycle.state`, `app_lifecycle.timestamp`, + device and OS identifiers, and (when the user is identified) `user.id`, + `user.email`, `user.name`, `user.phone`, `user.plan`, `user.tenant`, + `user.anonymous_id` + +`session.sample_rate` is the app's configured sampling percentage (the SDK +defaults to 1%); `session.sampled` shows whether this particular session was +kept. Crash, error, and ANR sessions are typically kept regardless of the +sample rate, so a low rate doesn't mean those sessions are missing - see +[Sessions](../../instrument/mobile/flutter.md#sessions) in the +instrumentation guide. + +![Resource Attributes (mobile) panel with app.*, device.*, os.*, and telemetry.sdk.* attributes](/img/rum/sessions/resource-attributes.png) + +- **Resource Attributes (mobile)** - the static resource context attached to + every event in the session: `app.build`, `app.bundle_id`, `app.version`, + `device.battery.level`, `device.battery.state`, `device.is_physical`, + `device.locale`, `device.model.name`, `device.type`, `host.arch`, + `network.connection.type`, `os.build`, `os.name`, `os.version`, + `service.name`, `service.version`, `telemetry.sdk.language`, + `telemetry.sdk.name`, `telemetry.sdk.version` + +### Summary Stats + +![Duration, Screens, Errors, and Crashes stat cards](/img/rum/sessions/summary-stats.png) + +**Duration**, **Screens**, **Errors**, and **Crashes** for the session, +matching the columns in the Session List. + +### Event Timeline + +![Event Timeline table with filter chips and Time/Event/Details/Status columns](/img/rum/sessions/event-timeline.png) + +A chronological table (**Time**, **Event**, **Details**, **Status**) of every +event captured during the session, including: + +| Event type | What it represents | +| ---------- | ------------------- | +| `screen_view` / `screen_load` | A screen was shown / finished loading, with load duration | +| `user_interaction` | A tap or gesture, with the widget name in Details (for example "Back (ElevatedButton)") | +| `http.request` | An API call, with method, URL, status code, and duration | +| `view_session` | Time spent on a screen - an "entered" marker when the user arrives, paired with a duration when they leave | +| `app_startup` | App start, tagged cold or warm, with startup duration | +| `long_task` | A long-running task on the UI thread (potential jank) | +| `app_lifecycle.changed` | App lifecycle transitions (backgrounded, resumed) | +| `app_crash` | A crash occurred during the session | + +Failed requests and errors are highlighted in the **Status** column so they +stand out in a long timeline. Use the event-type filter chips above the +timeline (with per-type counts) to toggle categories on or off and cut a +noisy session down to just, say, `http.request` and `app_crash` events. + +--- + +## Use Cases + +### Reproducing a Bug Report + +1. Find the user's session (filter by `user.id` if known, or search by + session ID from a support ticket) +2. Open the timeline and filter down to `screen_view` and `user_interaction` + events +3. Walk through the sequence leading up to the reported issue + +### Investigating a Slow Session + +1. Sort the **Session List** by **Duration** +2. Open the timeline and filter to `http.request` and `long_task` events +3. Look for slow requests or repeated long tasks clustered together + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Overview](./overview.md) - Session volume trend +- [Crashes](./crashes.md) - Crash groups, with a link back into the session +- [Users](./users.md) - Per-user session history diff --git a/docs/operate/rum/users.md b/docs/operate/rum/users.md new file mode 100644 index 00000000..d064490e --- /dev/null +++ b/docs/operate/rum/users.md @@ -0,0 +1,108 @@ +--- +title: RUM Users +sidebar_label: Users +sidebar_position: 9 +description: + Explore identified users and their activity with RUM in base14 Scout. View + per-user sessions, errors, devices, screen performance, and session history. +keywords: + [ + rum, + users, + user monitoring, + session history, + per-user performance, + mobile users, + base14, + scout, + ] +--- + +The **Users** tab lists identified users and their activity, so you can start +from a known user (a support ticket, an account ID) and drill into exactly +what they experienced. + +![Users](/img/rum/users/list.png) + +--- + +## User List + +### Table Columns + +| Column | Description | +| ------ | ----------- | +| **Identifier** | The user's identifier | +| **Sessions** | Number of sessions in the range | +| **Errors** | Non-fatal errors across all their sessions | +| **Devices** | Device model(s) they used | + +Users with a non-zero error count are highlighted so you can spot who is +hitting problems. + +The shared [Filters](./getting-started.md#filters) sidebar applies here, with +a richer set of User attributes than elsewhere: `user.id`, +`user.anonymous_id`, `user.email`, `user.name`, `user.phone`, `user.plan`, +`user.session_seq`, and `user.tenant`. + +--- + +## User Details + +Select a user to open their detail view, which brings together everything +that user has done in the app. + +![Identifier, Devices, OS, App Versions header and Crashes/Errors/UI Freezes/Sessions stat cards](/img/rum/users/header-stats.png) + +The header identifies the user and the **Devices**, **OS**, and **App +Versions** they used, followed by **Crashes**, **Errors**, **UI Freezes**, +and **Sessions** stat cards summarizing their experience. + +### Screen Performance + +![Screen Performance table with Screen, Views, Avg Load, and Avg Time Spent columns](/img/rum/users/screen-performance.png) + +Per-screen **Views**, **Avg Load**, and **Avg Time Spent** for this user, so +you can see which screens are slow or failing for them specifically - +useful for confirming whether a reported issue is app-wide or unique to this +user's device or usage pattern. + +### Session History + +![Session History table with Session ID, Started At, Duration, Screens, Errors, and Crashes columns](/img/rum/users/session-history.png) + +The user's sessions with **Session ID**, **Started At**, **Duration**, +**Screens**, **Errors**, and **Crashes**, each linking through to its full +[session timeline](./sessions.md). Sessions with crashes are highlighted, and +**Load more** pages through additional sessions. + +--- + +## Use Cases + +### Investigating a Support Ticket + +1. Search for the user's identifier in the **User List** +2. Check the **Crashes**/**Errors**/**UI Freezes** stat cards for a quick + read on whether they're having a bad time generally +3. Open **Session History** and jump into the session around when they + reported the issue + +### Checking if an Issue Is User-Specific + +1. Open the affected user's detail view +2. Compare their **Screen Performance** numbers against the app-wide numbers + on [Screens](./screens.md) for the same screen +3. A large gap points at something specific to this user's device, network, + or account state rather than a general regression + +--- + +## Related Guides + +- [Getting Started](./getting-started.md) - Interface layout and shared filters +- [Sessions](./sessions.md) - Full session timeline and event details +- [Crashes](./crashes.md) - Crash groups, filterable by affected user +- [traceX](../tracex/index.md) - Distributed tracing explorer +- [logX](../logx/index.md) - Log explorer with trace correlation +- [Instrument a Flutter app](../../instrument/mobile/flutter.md) diff --git a/static/img/rum/anr/affected.png b/static/img/rum/anr/affected.png new file mode 100644 index 00000000..3f874478 Binary files /dev/null and b/static/img/rum/anr/affected.png differ diff --git a/static/img/rum/anr/attributes.png b/static/img/rum/anr/attributes.png new file mode 100644 index 00000000..9404ec9a Binary files /dev/null and b/static/img/rum/anr/attributes.png differ diff --git a/static/img/rum/anr/breadcrumbs.png b/static/img/rum/anr/breadcrumbs.png new file mode 100644 index 00000000..c47108f5 Binary files /dev/null and b/static/img/rum/anr/breadcrumbs.png differ diff --git a/static/img/rum/anr/list.png b/static/img/rum/anr/list.png new file mode 100644 index 00000000..0a3e0915 Binary files /dev/null and b/static/img/rum/anr/list.png differ diff --git a/static/img/rum/anr/occurrence-breakdown.png b/static/img/rum/anr/occurrence-breakdown.png new file mode 100644 index 00000000..12936ea2 Binary files /dev/null and b/static/img/rum/anr/occurrence-breakdown.png differ diff --git a/static/img/rum/anr/stack-trace.png b/static/img/rum/anr/stack-trace.png new file mode 100644 index 00000000..cb68f3c7 Binary files /dev/null and b/static/img/rum/anr/stack-trace.png differ diff --git a/static/img/rum/anr/summary-stats.png b/static/img/rum/anr/summary-stats.png new file mode 100644 index 00000000..d0d0ed94 Binary files /dev/null and b/static/img/rum/anr/summary-stats.png differ diff --git a/static/img/rum/crashes/affected.png b/static/img/rum/crashes/affected.png new file mode 100644 index 00000000..a9edb3bf Binary files /dev/null and b/static/img/rum/crashes/affected.png differ diff --git a/static/img/rum/crashes/attributes.png b/static/img/rum/crashes/attributes.png new file mode 100644 index 00000000..d3212fad Binary files /dev/null and b/static/img/rum/crashes/attributes.png differ diff --git a/static/img/rum/crashes/breadcrumbs.png b/static/img/rum/crashes/breadcrumbs.png new file mode 100644 index 00000000..928a411e Binary files /dev/null and b/static/img/rum/crashes/breadcrumbs.png differ diff --git a/static/img/rum/crashes/list.png b/static/img/rum/crashes/list.png new file mode 100644 index 00000000..87c270c6 Binary files /dev/null and b/static/img/rum/crashes/list.png differ diff --git a/static/img/rum/crashes/occurrence-breakdown.png b/static/img/rum/crashes/occurrence-breakdown.png new file mode 100644 index 00000000..bc08666b Binary files /dev/null and b/static/img/rum/crashes/occurrence-breakdown.png differ diff --git a/static/img/rum/crashes/stack-trace.png b/static/img/rum/crashes/stack-trace.png new file mode 100644 index 00000000..c002c398 Binary files /dev/null and b/static/img/rum/crashes/stack-trace.png differ diff --git a/static/img/rum/crashes/summary-stats.png b/static/img/rum/crashes/summary-stats.png new file mode 100644 index 00000000..5e8cef1a Binary files /dev/null and b/static/img/rum/crashes/summary-stats.png differ diff --git a/static/img/rum/errors/affected.png b/static/img/rum/errors/affected.png new file mode 100644 index 00000000..08544246 Binary files /dev/null and b/static/img/rum/errors/affected.png differ diff --git a/static/img/rum/errors/attributes.png b/static/img/rum/errors/attributes.png new file mode 100644 index 00000000..00148e1f Binary files /dev/null and b/static/img/rum/errors/attributes.png differ diff --git a/static/img/rum/errors/breadcrumbs.png b/static/img/rum/errors/breadcrumbs.png new file mode 100644 index 00000000..91e3c3bb Binary files /dev/null and b/static/img/rum/errors/breadcrumbs.png differ diff --git a/static/img/rum/errors/list.png b/static/img/rum/errors/list.png new file mode 100644 index 00000000..164c0fb6 Binary files /dev/null and b/static/img/rum/errors/list.png differ diff --git a/static/img/rum/errors/occurrence-breakdown.png b/static/img/rum/errors/occurrence-breakdown.png new file mode 100644 index 00000000..abbc15f2 Binary files /dev/null and b/static/img/rum/errors/occurrence-breakdown.png differ diff --git a/static/img/rum/errors/stack-trace.png b/static/img/rum/errors/stack-trace.png new file mode 100644 index 00000000..fecbb9be Binary files /dev/null and b/static/img/rum/errors/stack-trace.png differ diff --git a/static/img/rum/errors/summary-stats.png b/static/img/rum/errors/summary-stats.png new file mode 100644 index 00000000..dda265af Binary files /dev/null and b/static/img/rum/errors/summary-stats.png differ diff --git a/static/img/rum/getting-started/applications.png b/static/img/rum/getting-started/applications.png new file mode 100644 index 00000000..959d6aaf Binary files /dev/null and b/static/img/rum/getting-started/applications.png differ diff --git a/static/img/rum/getting-started/filters-sidebar.png b/static/img/rum/getting-started/filters-sidebar.png new file mode 100644 index 00000000..78185a68 Binary files /dev/null and b/static/img/rum/getting-started/filters-sidebar.png differ diff --git a/static/img/rum/getting-started/interface-chrome.png b/static/img/rum/getting-started/interface-chrome.png new file mode 100644 index 00000000..0209d774 Binary files /dev/null and b/static/img/rum/getting-started/interface-chrome.png differ diff --git a/static/img/rum/network/all-endpoints.png b/static/img/rum/network/all-endpoints.png new file mode 100644 index 00000000..0394df1c Binary files /dev/null and b/static/img/rum/network/all-endpoints.png differ diff --git a/static/img/rum/network/avg-response-time.png b/static/img/rum/network/avg-response-time.png new file mode 100644 index 00000000..3481427d Binary files /dev/null and b/static/img/rum/network/avg-response-time.png differ diff --git a/static/img/rum/overview/breakdown-anr.png b/static/img/rum/overview/breakdown-anr.png new file mode 100644 index 00000000..1314a2b7 Binary files /dev/null and b/static/img/rum/overview/breakdown-anr.png differ diff --git a/static/img/rum/overview/breakdown-crashes.png b/static/img/rum/overview/breakdown-crashes.png new file mode 100644 index 00000000..0dd734cd Binary files /dev/null and b/static/img/rum/overview/breakdown-crashes.png differ diff --git a/static/img/rum/overview/breakdown-sessions.png b/static/img/rum/overview/breakdown-sessions.png new file mode 100644 index 00000000..360129e4 Binary files /dev/null and b/static/img/rum/overview/breakdown-sessions.png differ diff --git a/static/img/rum/overview/key-metrics.png b/static/img/rum/overview/key-metrics.png new file mode 100644 index 00000000..505216c7 Binary files /dev/null and b/static/img/rum/overview/key-metrics.png differ diff --git a/static/img/rum/overview/top-screens.png b/static/img/rum/overview/top-screens.png new file mode 100644 index 00000000..cb5b8ebc Binary files /dev/null and b/static/img/rum/overview/top-screens.png differ diff --git a/static/img/rum/overview/trends.png b/static/img/rum/overview/trends.png new file mode 100644 index 00000000..74727989 Binary files /dev/null and b/static/img/rum/overview/trends.png differ diff --git a/static/img/rum/screens/crashes-on-screen.png b/static/img/rum/screens/crashes-on-screen.png new file mode 100644 index 00000000..aa385f89 Binary files /dev/null and b/static/img/rum/screens/crashes-on-screen.png differ diff --git a/static/img/rum/screens/frame-timing.png b/static/img/rum/screens/frame-timing.png new file mode 100644 index 00000000..b40d8e4b Binary files /dev/null and b/static/img/rum/screens/frame-timing.png differ diff --git a/static/img/rum/screens/list.png b/static/img/rum/screens/list.png new file mode 100644 index 00000000..1f15d59a Binary files /dev/null and b/static/img/rum/screens/list.png differ diff --git a/static/img/rum/screens/load-time-views.png b/static/img/rum/screens/load-time-views.png new file mode 100644 index 00000000..c807d1dc Binary files /dev/null and b/static/img/rum/screens/load-time-views.png differ diff --git a/static/img/rum/screens/resource-usage.png b/static/img/rum/screens/resource-usage.png new file mode 100644 index 00000000..981820d4 Binary files /dev/null and b/static/img/rum/screens/resource-usage.png differ diff --git a/static/img/rum/screens/slowest-loads-long-tasks.png b/static/img/rum/screens/slowest-loads-long-tasks.png new file mode 100644 index 00000000..30f545d9 Binary files /dev/null and b/static/img/rum/screens/slowest-loads-long-tasks.png differ diff --git a/static/img/rum/screens/summary-stats.png b/static/img/rum/screens/summary-stats.png new file mode 100644 index 00000000..84c504dc Binary files /dev/null and b/static/img/rum/screens/summary-stats.png differ diff --git a/static/img/rum/sessions/event-timeline.png b/static/img/rum/sessions/event-timeline.png new file mode 100644 index 00000000..28ed465a Binary files /dev/null and b/static/img/rum/sessions/event-timeline.png differ diff --git a/static/img/rum/sessions/list.png b/static/img/rum/sessions/list.png new file mode 100644 index 00000000..b46a142d Binary files /dev/null and b/static/img/rum/sessions/list.png differ diff --git a/static/img/rum/sessions/resource-attributes.png b/static/img/rum/sessions/resource-attributes.png new file mode 100644 index 00000000..fc8f4159 Binary files /dev/null and b/static/img/rum/sessions/resource-attributes.png differ diff --git a/static/img/rum/sessions/session-attributes.png b/static/img/rum/sessions/session-attributes.png new file mode 100644 index 00000000..485b155c Binary files /dev/null and b/static/img/rum/sessions/session-attributes.png differ diff --git a/static/img/rum/sessions/summary-stats.png b/static/img/rum/sessions/summary-stats.png new file mode 100644 index 00000000..e64b4ca6 Binary files /dev/null and b/static/img/rum/sessions/summary-stats.png differ diff --git a/static/img/rum/users/header-stats.png b/static/img/rum/users/header-stats.png new file mode 100644 index 00000000..c7c68cc4 Binary files /dev/null and b/static/img/rum/users/header-stats.png differ diff --git a/static/img/rum/users/list.png b/static/img/rum/users/list.png new file mode 100644 index 00000000..b935c549 Binary files /dev/null and b/static/img/rum/users/list.png differ diff --git a/static/img/rum/users/screen-performance.png b/static/img/rum/users/screen-performance.png new file mode 100644 index 00000000..a06a2261 Binary files /dev/null and b/static/img/rum/users/screen-performance.png differ diff --git a/static/img/rum/users/session-history.png b/static/img/rum/users/session-history.png new file mode 100644 index 00000000..4af79b04 Binary files /dev/null and b/static/img/rum/users/session-history.png differ