Skip to content

Repository files navigation

Android Logcat plugin icon

Android Logcat

Every device its own tab.

A LogSquirl plugin that streams Android logcat straight into the log viewer.

Capture from several ADB devices at once and read the output with the same regex search and highlighters you use on any other log.

CI Build Latest release Downloads Platforms License: GPL-3.0-or-later

Install  /  Usage  /  Build  /  Architecture  /  Changelog


Why this plugin?

adb logcat in a terminal scrolls away faster than you can read it, and one terminal means one device. This plugin puts every device in its own tab, in the viewer where your other logs already are.

Less setup More signal
Finds adb itself. Looks in ANDROID_HOME, ANDROID_SDK_ROOT, PATH and the usual platform locations; override it in the settings dialog. Every device its own tab. Start as many as you like — each opens in follow mode and keeps streaming.
Devices found for you. Automatic ADB scanning with one-click refresh. Nothing lost on stop. Captured output stays in the tab after the session ends.
Written to disk. Configurable log directory, automatic YYYY-MM-dd_HHmmss_<serial>.log names, path remembered. Filter with the host. No filter UI of its own — LogSquirl's regex search and highlighters do it better.
Sessions in the sidebar. Device dropdown, start/stop, and a live list with rotate and stop per session. A worked example. Heavily commented reference implementation for the Plugin SDK.

Install

From LogSquirl

Plugins → Browse Plugins… → Android Logcat → Install. The archive is downloaded, verified against its SHA-256 checksum and loaded — no file copying.

From a release

Download the archive for your platform from the releases page and unpack it into LogSquirl's plugin directory:

Platform Plugin Directory
macOS ~/Library/Application Support/logsquirl/plugins/io.github.logsquirl.logcat/
Linux ~/.local/share/logsquirl/plugins/io.github.logsquirl.logcat/
Windows %APPDATA%/logsquirl/plugins/io.github.logsquirl.logcat/

From source

See Build, then:

DEST="$HOME/Library/Application Support/logsquirl/plugins/io.github.logsquirl.logcat"
mkdir -p "$DEST"
cp build/liblogsquirl_logcat.dylib "$DEST/"
cp plugin.json icon.png "$DEST/"

Or cmake --install build --prefix "$HOME/.local".

After installing, restart LogSquirl or re-scan via Plugins → Manage Plugins….

Usage

  1. Enable the plugin in Plugins → Manage Plugins… — check "Android Logcat" and click OK. (On first run, the plugin is auto-enabled if no other plugins are configured.)

  2. The Logcat sidebar tab appears automatically. Use the sidebar panel to manage sessions:

    • Device dropdown — Select a connected ADB device.
    • Refresh — Re-scan for devices.
    • Start — Begin capturing logcat for the selected device. A new tab opens in LogSquirl with live output in follow mode.
    • Stop — Stop the capture for the selected device. The tab remains open with all captured output preserved.
  3. Active Sessions — Running sessions are listed below the controls. Each session row shows the device name with:

    • ↻ — Rotate log (close current session, start a new one)
    • ■ — Stop the session
  4. Log directory — Set a directory path in the "Log Directory" section. Use the Browse button or type a path directly. Log files are automatically named YYYY-MM-dd_HHmmss_<serial>.log.

  5. Multiple devices — Select another device, click Start again. Each device gets its own tab and session entry.

  6. Configure ADB path — Plugins → Manage Plugins… → select plugin → Configure. Enter the full path to the adb executable (or leave empty for auto-detection).

Prerequisites

  • LogSquirl ≥ 26.03 with the plugin system enabled
  • Qt6 (Core + Widgets) — same version LogSquirl was built with
  • CMake ≥ 3.16
  • ADB (Android Debug Bridge) — part of the Android SDK Platform-Tools
  • A C++17-capable compiler (GCC ≥ 9, Clang ≥ 14, MSVC ≥ 19.29)

Build

# Clone
git clone https://github.com/64x-lunicorn/LogSquirl-Logcat.git
cd LogSquirl-Logcat

# Configure
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release

# If Qt6 is not in PATH (e.g. Homebrew on macOS):
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_PREFIX_PATH="$(brew --prefix qt6)"

# Build
cmake --build build

# The shared library is in build/:
#   macOS:   build/liblogsquirl_logcat.dylib
#   Linux:   build/liblogsquirl_logcat.so
#   Windows: build/logsquirl_logcat.dll

Running Tests

cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON
cmake --build build
cd build && ctest --output-on-failure

Architecture

graph TD
    subgraph LogSquirl Host
        H[MainWindow]
        SB[Sidebar Panel]
    end

    subgraph Plugin — C ABI Boundary
        P[plugin.cpp<br/>get_info / init /<br/>shutdown / configure]
        SW[SidebarWidget<br/>device selector + session list]
        DW[DeviceWidget<br/>session management]
        AP1[AdbProcess #1<br/>emulator-5554]
        AP2[AdbProcess #2<br/>R5CR10XXXXX]
    end

    H -- register_sidebar_tab --> P
    P -- creates --> SW
    SW -- uses --> DW
    SW --> SB
    DW -- manages --> AP1
    DW -- manages --> AP2
    AP1 -- writes --> TF1[Temp File #1]
    AP2 -- writes --> TF2[Temp File #2]
    TF1 -- open_file follow=1 --> H
    TF2 -- open_file follow=1 --> H
Loading

Data Flow

sequenceDiagram
    participant User
    participant DW as DeviceWidget
    participant AP as AdbProcess
    participant ADB as adb logcat
    participant TF as Temp File
    participant LS as LogSquirl Tab

    User->>SW: Click Start
    SW->>DW: startSession(serial)
    DW->>AP: start()
    AP->>ADB: spawn adb -s SERIAL logcat
    AP->>TF: create temp file
    AP-->>DW: open_file(tempPath, follow=1)
    DW-->>LS: New tab opens
    loop Streaming
        ADB->>AP: stdout lines
        AP->>TF: write + flush
        LS->>TF: tail/follow reads
    end
    User->>SW: Click Stop
    SW->>DW: stopSession(serial)
    DW->>AP: preserveTempFile() + stop()
    AP->>ADB: SIGTERM
    Note over LS: Tab stays open with captured output
Loading

Key Design Decisions

Decision Rationale
Plugin type = UI The DataSource type is limited to 1 stream per plugin. UI type allows managing multiple independent streams.
open_file() instead of push_line() Each device writes to its own temp file. The host opens each file with follow/tail mode → one tab per device.
register_sidebar_tab() Plugin registers a sidebar widget that is always visible while the plugin is loaded. The sidebar contains device selection, session controls, and active session list.
QProcess for ADB Cross-platform, integrates with Qt event loop, no need for threading.
No built-in filtering LogSquirl's regex search and highlighters are more powerful than any filter we could build.
Library name without extension plugin.json uses "library": "logsquirl_logcat" — QLibrary resolves the platform suffix automatically.

Project Structure

logsquirl-logcat/
├── CMakeLists.txt              # Standalone build — finds Qt6, builds shared lib
├── plugin.json                 # Plugin manifest (cross-platform)
├── LICENSE                     # GPL-3.0-or-later
├── README.md                   # This file
├── CHANGELOG.md                # Release history
├── .gitignore
├── include/
│   └── logsquirl_plugin_api.h  # Vendored SDK header (MIT license)
├── src/
│   ├── plugin.h                # Global state shared across translation units
│   ├── plugin.cpp              # C ABI entry points (get_info, init, shutdown)
│   ├── adbprocess.h            # ADB discovery + per-device QProcess wrapper
│   ├── adbprocess.cpp
│   ├── devicewidget.h          # Session management (start/stop/rotate)
│   ├── devicewidget.cpp
│   ├── sidebarwidget.h         # LogSquirl sidebar tab (device list + controls)
│   └── sidebarwidget.cpp
├── tests/
│   ├── CMakeLists.txt          # Catch2 test setup
│   ├── tests_main.cpp          # QApplication + Catch2 runner
│   ├── parsedevicelist_test.cpp
│   ├── plugininfo_test.cpp
│   └── adbprocess_test.cpp
└── docs/
    └── DEVELOPER_GUIDE.md      # How to use this as a plugin template

Plugin Registry

This plugin is listed in the LogSquirl-Plugins catalog, so it installs from Plugins → Browse Plugins… with no manual file copying.

The catalog holds one entry per plugin and does not change between releases. Versions, download URLs and checksums live in this repository's releases.json — update that when you publish a release, and fill in every sha256: an empty checksum silently disables verification in the host.

flowchart LR
    LS["LogSquirl"] -- "GET plugins.json" --> C["LogSquirl-Plugins<br/>(catalog)"]
    C -- "releases_url" --> RJ["releases.json<br/>(this repo)"]
    RJ -- "download_url + sha256" --> Z["Android Logcat release ZIP"]
Loading

Using This as a Plugin Template

This plugin is designed to be a starting point for your own LogSquirl plugins. See docs/DEVELOPER_GUIDE.md for a step-by-step guide on how the Plugin SDK works, annotated code walkthroughs, and tips for building your own plugins.

Quick start to fork this as a template:

  1. Copy this directory
  2. Rename the library in CMakeLists.txt
  3. Update plugin.json with your plugin's identity
  4. Modify plugin.cpp entry points
  5. Replace AdbProcess + DeviceWidget with your own logic
  6. Build and install

License

GPL-3.0-or-later — see LICENSE for the full license text.

The vendored include/logsquirl_plugin_api.h header is MIT-licensed, so plugins of any license can build against the LogSquirl Plugin SDK without taking on GPL obligations. See NOTICE for details.

About

LogSquirl plugin that streams Android logcat from multiple ADB-connected devices into live tabs. Also the documented reference implementation for the LogSquirl Plugin SDK. Qt6/C++17.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages