Logs (logcat)¶
Pulls diagnostic logs off a connected device via adb shell logcat, in dump-and-exit
mode — a snapshot of what's already in the buffer, not a live tail.
clear_logs
¶
Clear a device's log buffer: adb shell logcat -c -b BUFFER.
Pairs with read_logs for the standard debugging workflow: clear, reproduce the issue, then read_logs to see only what happened since. Wipes diagnostic history, not user/app data, so this is "write" rather than "destructive".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
serial
|
str
|
The target device's adb serial (see list_connected_devices). |
required |
buffer
|
LogBuffer
|
Which ring buffer to clear. |
'main'
|
Returns:
| Type | Description |
|---|---|
ClearLogsResult
|
The serial and buffer cleared. |
Error handling
Propagates the same way most tools do (unlike check_adb_available): if the adb binary itself can't be found or is unresponsive, or the serial doesn't match a connected device, that surfaces as an actual tool error.
Example
Called with serial="emulator-5554", buffer="main". A typical response:
{
"status": "success",
"message": "Cleared main log buffer on emulator-5554.",
"data": {"serial": "emulator-5554", "buffer": "main"},
"error": null
}
get_log_buffer_size
¶
Report a log buffer's ring size and usage: adb shell logcat -g -b BUFFER.
Cheap, read-only introspection — useful before deciding max_lines for read_logs, or whether to clear_logs first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
serial
|
str
|
The target device's adb serial (see list_connected_devices). |
required |
buffer
|
LogBuffer
|
Which ring buffer to report on. |
'main'
|
Returns:
| Type | Description |
|---|---|
LogBufferSize
|
The serial, buffer, and logd's raw size/usage text for it. |
Error handling
Propagates the same way most tools do (unlike check_adb_available): if
the adb binary itself can't be found or is unresponsive, or the
serial doesn't match a connected device, that surfaces as an actual
tool error. Verified live that an unknown buffer name (or one this
device's build doesn't have, e.g. "kernel" on a user build) fails
with "Unknown -b buffer '
Example
Called with serial="emulator-5554", buffer="crash". A typical response:
{
"status": "success",
"message": "Log buffer size for crash on emulator-5554: crash: ring buffer is 2 MiB (512 KiB consumed, 22 KiB readable), max entry is 5120 B, max payload is 4068 B",
"data": {
"serial": "emulator-5554",
"buffer": "crash",
"output": "crash: ring buffer is 2 MiB (512 KiB consumed, 22 KiB readable), max entry is 5120 B, max payload is 4068 B"
},
"error": null
}
read_logs
¶
Dump recent device logs: adb shell logcat -d -v threadtime -t N -b BUFFER.
Dump-and-exit, not a live tail: this returns a snapshot of what's already in the buffer, not a stream of future log lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
serial
|
str
|
The target device's adb serial (see list_connected_devices). |
required |
buffer
|
LogBuffer
|
Which ring buffer to read. "kernel" only exists on userdebug/eng builds and "security" only under Device Owner — either can legitimately fail on a given device. |
'main'
|
max_lines
|
int
|
How many of the most recent raw lines to read, before any tag/priority filter is applied (see Error handling below for why that ordering matters). Must be a positive integer — 0 or negative raises INVALID_ARGUMENT. |
200
|
min_priority
|
LogPriority | None
|
Minimum priority to include ("V" < "D" < "I" < "W" < "E" < "F" < "S"=silent). None means no filter (everything). |
None
|
tag
|
str | None
|
If set, show only this tag (at min_priority or above) and silence every other tag — verified live this is genuinely exclusive, not additive with min_priority's usual "everything at this level or above" meaning. |
None
|
pid
|
int | None
|
If set, show only log lines from this process ID. |
None
|
Returns:
| Type | Description |
|---|---|
LogDump
|
The raw logcat text for the requested buffer, plus the serial and buffer requested. |
Error handling
Propagates the same way most tools do (unlike check_adb_available): if the adb binary itself can't be found or is unresponsive, or the serial doesn't match a connected device, that surfaces as an actual tool error. A max_lines below 1 raises INVALID_ARGUMENT. Verified live that max_lines truncates the RAW buffer first, then filters — a narrow tag/priority filter combined with a small max_lines can come back with empty output (data, not an error) even though matching lines exist further back in the buffer; increase max_lines if that happens.
Example
Called with serial="emulator-5554", buffer="main", max_lines=3. A typical response:
{
"status": "success",
"message": "Read 3 log line(s) from main on emulator-5554.",
"data": {
"serial": "emulator-5554",
"buffer": "main",
"output": "--------- beginning of main\n08-26 08:24:26.364 462 11426 E audio_hw_generic_caremu: mixer_thread_loop error[-1] writing data to pcm\n..."
},
"error": null
}
read_package_logs
¶
Dump recent logs for one package: resolves its PID via adb shell pidof
-s PACKAGE, then adb shell logcat -d -v threadtime -t N -b BUFFER
--pid=PID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
serial
|
str
|
The target device's adb serial (see list_connected_devices). |
required |
package
|
str
|
Exact package/process name (e.g. "com.android.systemui") — pidof requires an exact match, not a substring. |
required |
buffer
|
LogBuffer
|
Which ring buffer to read. |
'main'
|
max_lines
|
int
|
How many of the most recent raw lines to read before any priority filter and the pid filter are applied. Same truncate-then-filter ordering caveat as read_logs. Must be a positive integer — 0 or negative raises INVALID_ARGUMENT. |
200
|
min_priority
|
LogPriority | None
|
Minimum priority to include. None means no filter. |
None
|
Returns:
| Type | Description |
|---|---|
PackageLogDump
|
The serial, package, resolved pid, and matching logcat text. |
Error handling
Propagates the same way most tools do (unlike check_adb_available): if the adb binary itself can't be found or is unresponsive, or the serial doesn't match a connected device, that surfaces as an actual tool error. Verified live that pidof exits 1 with no output both when the package isn't installed and when it's installed but not currently running — adb can't tell those apart, so this raises a single "no running process for package" error either way rather than guessing which. Also verified live that logcat only accepts one --pid per call, so a multi-process package (isolated services, separate process names) only returns its primary process's logs — a known limitation, not a bug.
Example
Called with serial="emulator-5554", package="com.android.systemui". A typical response:
{
"status": "success",
"message": "Read 4 log line(s) for com.android.systemui (pid 19861) on emulator-5554.",
"data": {
"serial": "emulator-5554",
"package": "com.android.systemui",
"pid": 19861,
"output": "--------- beginning of main\n08-26 08:24:32.118 19861 19934 D SystemUI: ...\n..."
},
"error": null
}
start_log_session
¶
Start a log-capture session: anchors on the device's current log position, to be replayed later by stop_log_session.
Not a live tail — this doesn't stream logs anywhere while the session is open. It records where the buffer currently is (plus whatever filter is given here), and stop_log_session later dumps everything matching that filter from that point to when it's called. See stop_log_session for how the captured logs actually reach a file. Filtering is configured here, when the session starts, not when it stops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
serial
|
str
|
The target device's adb serial (see list_connected_devices). |
required |
name
|
str
|
A human-readable label for this session (e.g. "wifi_repro") — purely for your own tracking across concurrent sessions; not interpreted by adb or validated for uniqueness. |
required |
buffer
|
LogBuffer
|
Which ring buffer to anchor on and later capture from. |
'main'
|
min_priority
|
LogPriority | None
|
Minimum priority to include at stop time. None means no filter (everything). Same semantics as read_logs's min_priority. |
None
|
tag
|
str | None
|
If set, only this tag (at min_priority or above) is captured and every other tag is silenced. Same semantics as read_logs's tag. |
None
|
pid
|
int | None
|
If set, only this process's logs are captured. Mutually exclusive with package — set at most one. |
None
|
package
|
str | None
|
If set, resolves to that package's PID the same way
read_package_logs does (exact match via |
None
|
Returns:
| Type | Description |
|---|---|
LogSessionHandle
|
A session_id to pass to stop_log_session, plus the serial, buffer, name, and (if pid or package was given) the pid that will be filtered on. |
Error handling
Propagates the same way most tools do (unlike check_adb_available): if the adb binary itself can't be found or is unresponsive, or the serial doesn't match a connected device, that surfaces as an actual tool error. Passing both pid and package is a tool error (ambiguous), not success:false data. package resolution can fail the same way read_package_logs's does: no running process for that package is a tool error, not a session that silently captures nothing. An empty buffer at start time is not an error — the session is still created; stop_log_session captures whatever's present at stop-time instead of filtering by timestamp.
Example
Called with serial="emulator-5554", name="wifi_repro", tag="WifiManager". A typical response:
{
"status": "success",
"message": "Started log session 'wifi_repro' (3fa1f2b0-...) on main@emulator-5554.",
"data": {
"session_id": "3fa1f2b0-...",
"serial": "emulator-5554",
"buffer": "main",
"name": "wifi_repro",
"pid": null,
"package": null
},
"error": null
}
stop_log_session
¶
Stop a log-capture session and write everything logged since start_log_session to a file on the host running this server.
local_path is a host filesystem path, not a device path — it's resolved against the server's configured local_root and must stay inside it (see Error handling). The captured text depends on the device's ring buffer not having wrapped past the session's start point — fine for a normal debugging session, not a hard guarantee for a very long or very high-volume one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
The id returned by start_log_session. |
required |
local_path
|
str
|
Where to write the captured log text, relative to (or, if absolute, still required to resolve inside) the server's configured local_root. |
required |
Returns:
| Type | Description |
|---|---|
LogSessionResult
|
The session_id, serial, buffer, name, pid/package (if the session was filtered by one), the resolved local_path actually written, how many lines were captured, and the session's duration in seconds. |
Error handling
session_id must refer to a session that's still open — an unknown or already-stopped id is a tool error, not success:false data. Sessions are held in memory only, for the server process's lifetime; they don't expire on their own. local_path is checked before any device round-trip: if the server has no local_root configured at all, or local_path resolves outside it (including via ".." or an absolute path elsewhere on the host), the call is refused rather than writing anywhere — there is no default local_root; an operator must set ADB_AUTOMATION_LOCAL_ROOT explicitly. Beyond that, this propagates the same way most tools do: adb being unreachable or the session's serial no longer being connected surfaces as an actual tool error.
Example
Called with session_id="3fa1f2b0-...", local_path="session1.log". A typical response:
{
"status": "success",
"message": "Wrote 148 log line(s) from session 'wifi_repro' (3fa1f2b0-...) to /var/adb-logs/session1.log.",
"data": {
"session_id": "3fa1f2b0-...",
"serial": "emulator-5554",
"buffer": "main",
"name": "wifi_repro",
"pid": null,
"package": null,
"local_path": "/var/adb-logs/session1.log",
"line_count": 148,
"duration_s": 42.7
},
"error": null
}