Skip to content

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 ''", exit 1.

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 pidof -s, must be currently running) and captures only that process's logs. Mutually exclusive with pid.

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
}