skip to content

In Appium, how do you capture a caving trip-log app's crash output on Android and on iOS?

level: seniorimportance: should knowfreq 39%

answer

  1. same route, different bucket names
  2. one platform can stream, one pulls
  3. crash detail has two different names
  4. capture before the session id dies

basics

~20 s

Pull it through the session. On Android the drivers serve logcat and bugreport over POST /session/:sessionId/se/log; on Apple platforms the XCUITest driver serves crashlog and syslog. The Android drivers also stream live through mobile: startLogsBroadcast.

solid answer

~40 s

Crash evidence comes out of the session, under a platform-specific bucket name. On **Android**, `POST /session/:sessionId/se/log` with `logcat` gives the app's own output around the moment it died, and `bugreport` gives the wider device state that came with it. On **Apple platforms**, the XCUITest driver serves `crashlog` for the crash detail itself and `syslog` for the system-side stream. Android additionally offers a live channel: the Android drivers declare `mobile: startLogsBroadcast` and `mobile: stopLogsBroadcast`, so you can subscribe to the stream as it happens rather than pulling after the fact; the measured XCUITest execute-method surface lists no equivalent. Pull before the session ends — both routes are keyed by session id.

go deeper

for a junior

Know that when the app under test crashes, the evidence is a device log fetched from the session, and that Android and Apple platforms call the relevant bucket by different names.

for a middle

Be ready to name the buckets per platform and explain why the same route serves both. Say what the server's own log covers and where the device log takes over.

for a senior

Show that you capture inside the session scope, that you know Android can stream while the Apple lane pulls, and that you can justify reaching for the heavier device-state artefact rather than the rolling log.

for a principal

Own where the platform mapping lives and what it costs. Decide whether streaming on one lane and pulling on the other is worth the asymmetry in your driver layer, or whether a lowest-common-denominator pull is simpler to keep correct.

## Crash evidence lives in two places, and only one of them is Appium's When a caving trip-log app dies mid-run — say while writing a survey leg to storage — there are two records of it and they answer different questions. The **server's own log** records the automation side: which command was in flight, what the driver returned, and roughly when the session stopped behaving. It tells you the shape of the failure. The **device log** records the application side: the app's own output, the platform's complaint, the crash detail. It tells you the cause. That record is the platform's, and Appium's contribution is a route to fetch it — `POST /session/:sessionId/se/log`, with a body naming one log type. The route is uniform. The type name is not. ## Android: what the Android drivers serve On an Android session, whether it is driven by UiAutomator2 or by Espresso, the buckets are: - **`logcat`** — the device's rolling system log, which carries the app's own output and, when a process dies, the trace it printed on the way out. This is the first pull for almost any Android failure. - **`bugreport`** — the wider device state captured as one artefact. Bigger, slower to produce, and worth it when the question is *what else was going on* rather than *what did my app print*. Because both names are served by the Android drivers rather than by one specific engine, an Espresso session and a UiAutomator2 session behave the same way here. Android also offers a second mechanism the other platform does not, in the measured surface: the Android drivers declare `mobile: startLogsBroadcast` and `mobile: stopLogsBroadcast`. Instead of pulling a bucket after the fact, you start a broadcast and consume the stream as it is produced. That matters when the failure kills the session too — a stream you were already receiving does not depend on the session surviving long enough for you to ask it a question afterwards. ## Apple platforms: what the XCUITest driver serves On an Apple session the same route carries different names: - **`crashlog`** — the crash detail proper. When the trip-log process itself went away, this is the bucket that says why. - **`syslog`** — the system-side stream, the closest analogue to the Android rolling log, and the place to look when the app misbehaved without dying. - **`safariConsole`** — web-view console output, relevant when part of the trip-log UI is rendered in a web view rather than natively. The XCUITest driver's execute-method surface is the largest of the mobile drivers, and no log-broadcast pair appears on it. So the honest statement for the Apple lane is: pull the bucket, and pull it while the session is still there. ## The two lanes side by side | question you are asking | Android drivers | XCUITest driver | |---|---|---| | what did my app print before it died | `logcat` | `syslog` | | why did the process go away | `logcat`, then `bugreport` | `crashlog` | | what did the web view's console say | not under these names | `safariConsole` | | can I stream it live | `mobile: startLogsBroadcast` / `stopLogsBroadcast` | not on the measured surface | ## Ordering the capture in a real run A sequence that survives contact with a crashing app looks like this: 1. **Decide the platform's bucket name once**, in your driver layer, not at each call site. One abstract idea — "the device log" — mapped to `logcat` on Android and `syslog` on Apple platforms, with `bugreport` and `crashlog` as the deeper pull. 2. **On Android, consider starting a broadcast** at session start with `mobile: startLogsBroadcast`, and stopping it with `mobile: stopLogsBroadcast`. You are then not relying on the session outliving the crash. 3. **Pull while the session id still resolves.** Both log routes are session-scoped; once the session is gone, so is your access. 4. **Keep the server's own log alongside it**, timestamped, so the device-side evidence can be lined up against the command that provoked it. ## What goes wrong - Asking an Apple session for `logcat`, or an Android session for `crashlog`. The route resolves, the name does not exist on that driver, and the helper that worked on one lane is silently useless on the other. - Pulling after teardown, in an after-suite hook, when the ids have already stopped addressing anything. - Expecting a broadcast on both platforms because Android has one. Attributing a driver's execute method to the other platform's driver is the single easiest mistake to make here, because both names are real Appium identifiers — they just belong to different drivers. - Treating `bugreport` as an everyday pull. It is the heavy artefact; the rolling log answers most questions and costs far less. The underlying discipline is the same one that runs through this whole subject: the transport is shared, the vocabulary is not, and every sentence you write about it should name which platform it speaks for.

  • Why can a live log broadcast be more reliable than a post-hoc pull when an app crashes?
    A pull needs the session to still be alive when you ask. If the crash also takes the session down, the id no longer resolves and the bucket is unreachable through Appium. A broadcast you started earlier has already delivered the lines leading up to the crash. On Android the Android drivers declare `mobile: startLogsBroadcast` and `mobile: stopLogsBroadcast` for exactly that.
  • When is bugreport the right pull on Android rather than logcat?
    When the question is about the device rather than the app. `logcat` gives the rolling stream your app wrote into, which answers most failures. `bugreport` is the wider device-state artefact — larger and slower to produce — and is worth it when you suspect something outside the trip-log app itself contributed.

saying these in an interview costs you the question

  • Asks an Apple session for logcat because Android works that way
  • Attributes mobile: startLogsBroadcast to the XCUITest driver
  • Pulls device logs in an after-suite hook, once sessions are gone
  • Treats bugreport as a routine per-test capture
  • Thinks the server log alone explains why the app crashed
  • Assumes crashlog and bugreport are the same bucket renamed