--- name: extracting-logs-with-logcat description: Use this skill to read device logs for test failures, debug, smoke testing, and CI repros. Covers `adb logcat` (stream), `adb logcat -d` (dump and exit), `adb logcat -c` (clear), buffer selection (`-b main|system|crash|events|radio|kernel|all`), priority ladder (V/D/I/W/E/F/S), filter expressions like `MyApp:D *:S`, format flags (`-v threadtime`, `-v json` on Android 11+), `--pid $(adb shell pidof -s pkg)`, time/count filters (`-T '01-01 12:00:00.000'`, `-t 100`), buffer rotation (`-r `, `-n `, `-f `), buffer sizing (`-G`, `-g`), and stripping `Log.d` calls in release builds via R8 `-assumenosideeffects`. If the user mentions "logcat filter only my app", "events buffer am_proc_start", "logcat json format", "grep logcat expensive", "missing logs after restart", "stripping Log.d release", or "logcat -f writes to host or device", use this skill. license: Apache-2.0. See LICENSE for complete terms. metadata: author: Jaewoong Eum (skydoves) keywords: - android-testing - adb - logcat - log-buffers - log-filters - threadtime - log-rotation - r8-keep-rules - assumenosideeffects --- # Extracting Logs With logcat — Reading Device Logs This skill covers `adb logcat` end-to-end: streaming vs dumping, buffer selection, filter expressions, format flags, PID and time filters, file rotation, and the R8 rule that strips `Log.d` from release builds. The companion CI capture-on-failure pattern lives in `../../automation/scripting-adb-for-ci/SKILL.md`. ## When to use this skill - A test fails on CI; the developer needs to dump the device log into the artefact archive. - The developer's `adb logcat | grep MyApp` is overwhelming the SSH session — the logcat-side filter is the fix. - A scenario only reproduces inside `system_server` or `crash` buffers, not the default `main`. - The developer wants structured logs (`-v json`) for machine ingestion. - A `Log.d("Sensitive", "...")` call appears to leak in release — the R8 `-assumenosideeffects` rule is missing. - Logs disappear after the app is killed by Doze/ANR — `--pid` plus a re-resolution loop is needed. ## When NOT to use this skill - Capturing a screenshot or video. Use `../../capture/capturing-screenshots-and-screenrecord/SKILL.md`. - Pulling a generic file from the device. Use `../../transfer/extracting-test-artifacts/SKILL.md`. - The whole script — retries, port forwarding, parallel device fan-out. Use `../../automation/scripting-adb-for-ci/SKILL.md`. - Driving gestures or settings changes. Use `../../control/injecting-input-and-state/SKILL.md`. ## Prerequisites - `adb get-state` returns `device`. See `../../devices/connecting-to-devices/SKILL.md`. - For `-v json`: device API 30+ (Android 11+). Stack with `-v UTC -v year` for unambiguous timestamps. - For per-PID filtering: `adb shell pidof -s ` requires API 24+ (toybox `pidof -s`); on older releases use `adb shell ps -A | grep `. ## Three fundamental operations | Command | Behavior | |---|---| | `adb logcat` | Stream the device log to stdout; runs until interrupted. | | `adb logcat -d` | "Dumps the log and exits." Snapshot mode — perfect for CI. | | `adb logcat -c` | "Clears the log buffer." Run this before reproducing a bug. | (Verbatim quotes from developer.android.com/tools/logcat.) Idiomatic CI capture pattern: ```bash adb logcat -c # clear before scenario ./run-scenario.sh # reproduce adb logcat -d > artifacts/log.txt # dump after ``` ## Buffer selection `-b ` selects which kernel/userspace ring buffer is read. Buffers (developer.android.com/tools/logcat): | Buffer | What it contains | |---|---| | `main` | Default app-side buffer. Does NOT contain system/crash. | | `system` | Framework / system_server messages. | | `crash` | Tombstones + unhandled-exception output. | | `events` | Structured/binary system event buffer. Pair with `-v descriptive` to decode tag names. | | `radio` | Radio/telephony related messages. | | `kernel` | Kernel buffer. | | `all` | Every buffer. | | `default` | Implicit set: `main`, `system`, `crash`. | Multiple `-b` flags or comma-separated lists both work: ```bash adb logcat -b radio adb logcat -b main -b radio -b events adb logcat -b main,radio,events ``` The `events` buffer is where to look for `am_*`, `wm_*`, `input_focus`, `notification_*` — emitted by the framework for instrumentation, not for human reading. Decode tag names with: ```bash adb logcat -b events -v descriptive ``` ## Priority ladder + filter expressions Filter specs are space-separated `tag:priority` pairs. `*` matches every tag. | Letter | Meaning | |---|---| | `V` | Verbose | | `D` | Debug | | `I` | Info | | `W` | Warning | | `E` | Error | | `F` | Fatal | | `S` | "Silent (highest priority, nothing is printed)" | Setting `*:S` *silences everything*, then any preceding `tag:P` re-enables that tag at priority `P` or above. The canonical "show only my app's logs" idiom: ```bash adb logcat ActivityManager:I MyApp:D *:S ``` > "Suppress all logs except ActivityManager (Info+) and MyApp (Debug+)" — developer.android.com/tools/logcat. Other staples: ```bash adb logcat *:W # warnings and above, all tags adb logcat *:E # errors and above (very common in CI) ``` zsh/bash will glob-expand `*:S` outside of quotes when there is a file named `S` in cwd — quote when scripting: ```bash adb logcat "ActivityManager:I MyApp:D *:S" ``` The same filter can be the host default via env var: ```bash export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S" ``` ## Format flags — `-v ` | Format | What you get | |---|---| | `brief` | "Displays priority, tag, and PID" | | `long` | "All metadata fields with blank lines between messages" | | `process` | "PID only" | | `raw` | "Raw log message with no metadata" | | `tag` | "Priority and tag only" | | `thread` | "Legacy format showing priority, PID, and TID" | | `threadtime` | DEFAULT. "Date, time, priority, tag, PID, and TID" | | `time` | "Date, time, priority, tag, and PID" | Format **modifiers** stack with `-v` (comma-combinable or repeatable): | Modifier | Effect | |---|---| | `color` | Per-priority colour. | | `descriptive` | Decode event log tag names. | | `epoch` | Time in seconds since 1970-01-01. | | `monotonic` | CPU seconds from last boot. | | `printable` | Escape binary content. | | `uid` | UID or Android ID of logged process. | | `usec` | Time with microsecond precision. | | `UTC` | Time as UTC. | | `year` | Add year to displayed time. | | `zone` | Add local time zone. | ```bash adb logcat -v json -v UTC -v year # Android 11+; structured stream, unambiguous time adb logcat -b all -v color -d # color dump, all buffers ``` Default-line example (developer.android.com/tools/logcat): ``` I/ActivityManager( 585): Starting activity: Intent { action=android.intent.action.MAIN ... } ``` Schema for `brief`: `/(): `. `threadtime` adds date/time/TID. ## Time and PID filters - `-T '