Refactor: AI generated enhanced version
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
logs/
|
||||||
192
README.md
Normal file
192
README.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# ADB Log Monitor (Enhanced)
|
||||||
|
|
||||||
|
A robust, configurable, enterprise-grade logcat watcher for Android development.
|
||||||
|
Automatically detects devices, tracks app restarts, captures logs into timestamped files, and optionally restarts the target app if its process disappears.
|
||||||
|
|
||||||
|
**Author:** Reza Esmaeili
|
||||||
|
**Purpose:** Reliable long-running log capture for debugging and QA.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* 🔍 **Automatic device detection** (handles single/multiple devices)
|
||||||
|
* 📦 **Monitors any Android package** via `pidof` or `ps`
|
||||||
|
* 🔁 **Auto-restart option** for apps that crash or reboot
|
||||||
|
* 📝 **Writes logs to timestamped files** in a dedicated directory
|
||||||
|
* 🎛 **Fully configurable CLI flags**
|
||||||
|
* 🧼 **Graceful cleanup** on exit (`Ctrl+C`)
|
||||||
|
* ⚙️ **Strict scripting style** for reliability
|
||||||
|
* 🚀 **Drop-in ready for CI, QA, or development machines**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
* Android `adb` (Platform-tools) installed and in PATH
|
||||||
|
* A connected Android device or emulator authorized for debugging
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Place the script anywhere in your project, e.g.:
|
||||||
|
|
||||||
|
```
|
||||||
|
scripts/adb-log-monitor.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Make it executable:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x adb-log-monitor.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
(Optional) Add to PATH:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ln -s /path/to/adb-log-monitor.sh /usr/local/bin/adb-log-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Basic usage:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
|
||||||
|
* Detect the connected device
|
||||||
|
* Wait for the app to start
|
||||||
|
* Start logging when the process becomes available
|
||||||
|
* Write logs into `logs/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CLI Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-p PACKAGE Android package name (default: ir.avaair.avaair)
|
||||||
|
-a APP_NAME Friendly name for log filenames (default: derived from package)
|
||||||
|
-d DEVICE adb device ID (serial). If omitted: auto-detect
|
||||||
|
-o DIR Output directory for logs (default: logs)
|
||||||
|
-f FILTER Logcat filter (default: "*:V")
|
||||||
|
--no-restart Do NOT restart the app automatically
|
||||||
|
--help Show usage
|
||||||
|
```
|
||||||
|
|
||||||
|
You may also pass filters as positional args:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh *:E
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Log all messages for default package
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Log only errors
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh -f "*:E"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Specify a different package
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh -p com.example.myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Target a specific device
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh -d emulator-5554
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable auto-restart behavior
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh --no-restart
|
||||||
|
```
|
||||||
|
|
||||||
|
### Save logs into a custom directory
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./adb-log-monitor.sh -o /tmp/mylogs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Log Output
|
||||||
|
|
||||||
|
Each log session is written to:
|
||||||
|
|
||||||
|
```
|
||||||
|
logs/<app_name>_YYYY-MM-DD_HH-MM-SS_pid_<pid>.log
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
logs/avaair_2025-01-14_11-07-22_pid_1234.log
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Behavior Summary
|
||||||
|
|
||||||
|
* If the app is **not running**, the script waits indefinitely.
|
||||||
|
* When the process **starts**, logging begins immediately.
|
||||||
|
* If the process **restarts**, logging restarts seamlessly.
|
||||||
|
* On **Ctrl+C**, the script kills the background logcat and exits cleanly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Suggested `.gitignore`
|
||||||
|
|
||||||
|
```
|
||||||
|
logs/
|
||||||
|
```
|
||||||
|
|
||||||
|
This keeps your repo clean and prevents accidental log uploads.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Device unauthorized"
|
||||||
|
|
||||||
|
Accept the ADB RSA prompt on your device.
|
||||||
|
|
||||||
|
### “Device offline”
|
||||||
|
|
||||||
|
Restart:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb kill-server
|
||||||
|
adb start-server
|
||||||
|
```
|
||||||
|
|
||||||
|
### No logs generated
|
||||||
|
|
||||||
|
Ensure the package name is correct:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell pm list packages | grep <keyword>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License — feel free to modify and extend.
|
||||||
384
log_avaair.sh
384
log_avaair.sh
@@ -1,129 +1,341 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Advanced ADB Logcat Monitor for Android apps
|
||||||
|
#
|
||||||
|
# Author: Reza Esmaeili
|
||||||
|
# Description:
|
||||||
|
# Tail logcat for a specific Android app process (by package) with:
|
||||||
|
# - Device selection (auto or explicit)
|
||||||
|
# - Configurable filters / logcat args
|
||||||
|
# - Optional app restart
|
||||||
|
# - Safe cleanup on exit
|
||||||
|
# - Log files with timestamps in a dedicated directory
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./adb-log-monitor.sh [options] [LOGCAT_FILTER...]
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# ./adb-log-monitor.sh
|
||||||
|
# ./adb-log-monitor.sh -p ir.avaair.avaair -a avaair -f '*:E'
|
||||||
|
# ./adb-log-monitor.sh -d emulator-5554 --no-restart
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# -p PACKAGE Android package name (default: ir.avaair.avaair)
|
||||||
|
# -a APP_NAME Logical app name used for messages & filenames (default: derived from package)
|
||||||
|
# -d DEVICE Device ID (adb serial). If omitted, will prompt if multiple devices.
|
||||||
|
# -o DIR Logs output directory (default: logs)
|
||||||
|
# -f FILTER Logcat filter spec (default: *:V) – can also pass as positional args
|
||||||
|
# --no-restart Do NOT auto-restart the app when process dies/startup fails
|
||||||
|
# --help Show this help and exit
|
||||||
|
#
|
||||||
|
# Exit codes:
|
||||||
|
# 0 Success / user interrupt
|
||||||
|
# 1 Usage / config error
|
||||||
|
# 2 adb / device error
|
||||||
|
# 3 (unused now, kept for compatibility if you want to reintroduce timeouts)
|
||||||
|
#
|
||||||
|
|
||||||
################################################
|
set -Euo pipefail
|
||||||
# Advanced ADB Logcat Monitor for android apps #
|
|
||||||
# Author: Reza Esmaeili #
|
|
||||||
################################################
|
|
||||||
|
|
||||||
APP_NAME="avaair"
|
########################
|
||||||
PACKAGE_NAME="ir.avaair" # ← Change if needed
|
# Default configuration
|
||||||
LOG_DIR="logs"
|
########################
|
||||||
mkdir -p "$LOG_DIR"
|
|
||||||
|
DEFAULT_PACKAGE_NAME="ir.avaair.avaair"
|
||||||
|
DEFAULT_LOG_DIR="logs"
|
||||||
|
DEFAULT_FILTER="*:V"
|
||||||
|
|
||||||
|
PACKAGE_NAME="${PACKAGE_NAME:-$DEFAULT_PACKAGE_NAME}"
|
||||||
|
APP_NAME="${APP_NAME:-}"
|
||||||
|
DEVICE="${DEVICE:-}"
|
||||||
|
LOG_DIR="${LOG_DIR:-$DEFAULT_LOG_DIR}"
|
||||||
|
FILTER="${DEFAULT_FILTER}"
|
||||||
|
AUTO_RESTART=true
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Pretty output helpers
|
||||||
|
########################
|
||||||
|
|
||||||
# Colors for nice console output
|
|
||||||
RED="\033[0;31m"
|
RED="\033[0;31m"
|
||||||
GREEN="\033[0;32m"
|
GREEN="\033[0;32m"
|
||||||
YELLOW="\033[1;33m"
|
YELLOW="\033[1;33m"
|
||||||
BLUE="\033[0;34m"
|
BLUE="\033[0;34m"
|
||||||
NC="\033[0m" # No Color
|
NC="\033[0m" # No Color
|
||||||
|
|
||||||
FILTER="${1:-*:V}" # Default to verbose logs if no argument passed
|
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
||||||
START_TIME=$(date +%s)
|
log_ok() { echo -e "${GREEN}[ OK ]${NC} $*"; }
|
||||||
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
log_error() { echo -e "${RED}[ERR ]${NC} $*" >&2; }
|
||||||
|
|
||||||
# --- Cleanup on exit ---
|
########################
|
||||||
cleanup() {
|
# Usage
|
||||||
echo -e "\n${YELLOW}🧹 Cleaning up...${NC}"
|
########################
|
||||||
pkill -f "adb -s $DEVICE logcat --pid" 2>/dev/null
|
|
||||||
echo -e "${GREEN}✅ Done.${NC}"
|
usage() {
|
||||||
exit 0
|
sed -n '1,80p' "$0" | sed 's/^# \{0,1\}//'
|
||||||
}
|
}
|
||||||
trap cleanup SIGINT SIGTERM
|
|
||||||
|
|
||||||
# --- Device selection ---
|
########################
|
||||||
echo -e "${BLUE}🔍 Checking connected devices...${NC}"
|
# Parse CLI args
|
||||||
DEVICES=($(adb devices | grep -w "device" | awk '{print $1}'))
|
########################
|
||||||
|
|
||||||
if [ ${#DEVICES[@]} -eq 0 ]; then
|
ARGS=()
|
||||||
echo -e "${RED}❌ No devices found. Connect a device or ensure it's authorized.${NC}"
|
while [[ $# -gt 0 ]]; do
|
||||||
exit 1
|
case "$1" in
|
||||||
|
--no-restart)
|
||||||
|
AUTO_RESTART=false
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-p)
|
||||||
|
[[ $# -lt 2 ]] && { log_error "-p requires PACKAGE"; exit 1; }
|
||||||
|
PACKAGE_NAME="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-a)
|
||||||
|
[[ $# -lt 2 ]] && { log_error "-a requires APP_NAME"; exit 1; }
|
||||||
|
APP_NAME="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d)
|
||||||
|
[[ $# -lt 2 ]] && { log_error "-d requires DEVICE serial"; exit 1; }
|
||||||
|
DEVICE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-o)
|
||||||
|
[[ $# -lt 2 ]] && { log_error "-o requires DIR"; exit 1; }
|
||||||
|
LOG_DIR="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-f)
|
||||||
|
[[ $# -lt 2 ]] && { log_error "-f requires FILTER"; exit 1; }
|
||||||
|
FILTER="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
log_error "Unknown option: $1"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
ARGS+=("$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# If user passed extra args as filters, override FILTER
|
||||||
|
if [[ ${#ARGS[@]} -gt 0 ]]; then
|
||||||
|
FILTER="${ARGS[*]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Handle unauthorized/offline states
|
# Derive APP_NAME from PACKAGE_NAME if not set
|
||||||
if adb devices | grep -q "unauthorized"; then
|
if [[ -z "${APP_NAME}" ]]; then
|
||||||
echo -e "${RED}⚠️ Device unauthorized. Accept RSA prompt on your device.${NC}"
|
APP_NAME="${PACKAGE_NAME##*.}"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if adb devices | grep -q "offline"; then
|
mkdir -p "${LOG_DIR}"
|
||||||
echo -e "${RED}⚠️ Device offline. Reconnect or restart adb server.${NC}"
|
|
||||||
exit 1
|
########################
|
||||||
|
# Cleanup
|
||||||
|
########################
|
||||||
|
|
||||||
|
LOGCAT_PID=""
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
log_warn "Cleaning up..."
|
||||||
|
if [[ -n "${LOGCAT_PID}" ]]; then
|
||||||
|
kill "${LOGCAT_PID}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
log_ok "Done."
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'exit 0' SIGINT SIGTERM
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Preconditions
|
||||||
|
########################
|
||||||
|
|
||||||
|
if ! command -v adb >/dev/null 2>&1; then
|
||||||
|
log_error "'adb' command not found. Install Android platform-tools and ensure it's in PATH."
|
||||||
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ${#DEVICES[@]} -gt 1 ]; then
|
########################
|
||||||
echo -e "${YELLOW}📱 Multiple devices found:${NC}"
|
# Device selection
|
||||||
i=1
|
########################
|
||||||
for d in "${DEVICES[@]}"; do
|
|
||||||
|
select_device() {
|
||||||
|
local devices
|
||||||
|
mapfile -t devices < <(adb devices | awk 'NR>1 && $2=="device" {print $1}')
|
||||||
|
|
||||||
|
if adb devices | grep -q "unauthorized"; then
|
||||||
|
log_error "Device unauthorized. Accept the RSA prompt on your device."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if adb devices | grep -q "offline"; then
|
||||||
|
log_error "Device offline. Reconnect or restart adb server."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${#devices[@]} -eq 0 ]]; then
|
||||||
|
log_error "No devices found. Connect a device and ensure it's authorized."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${DEVICE}" ]]; then
|
||||||
|
if printf '%s\n' "${devices[@]}" | grep -qx "${DEVICE}"; then
|
||||||
|
log_ok "Using specified device: ${DEVICE}"
|
||||||
|
return
|
||||||
|
else
|
||||||
|
log_error "Specified device '${DEVICE}' is not connected."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${#devices[@]} -eq 1 ]]; then
|
||||||
|
DEVICE="${devices[0]}"
|
||||||
|
log_ok "Using single connected device: ${DEVICE}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_warn "Multiple devices found:"
|
||||||
|
local i=1
|
||||||
|
for d in "${devices[@]}"; do
|
||||||
echo " [$i] $d"
|
echo " [$i] $d"
|
||||||
((i++))
|
((i++))
|
||||||
done
|
done
|
||||||
read -p "👉 Select device number: " choice
|
|
||||||
DEVICE=${DEVICES[$((choice-1))]}
|
|
||||||
else
|
|
||||||
DEVICE=${DEVICES[0]}
|
|
||||||
echo -e "${GREEN}📱 Using single device:${NC} $DEVICE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Helper: choose ps command dynamically ---
|
local choice
|
||||||
detect_ps_cmd() {
|
read -r -p "Select device number: " choice
|
||||||
if adb -s "$DEVICE" shell ps -A >/dev/null 2>&1; then
|
if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#devices[@]} )); then
|
||||||
echo "ps -A"
|
log_error "Invalid selection."
|
||||||
else
|
exit 1
|
||||||
echo "ps"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
DEVICE="${devices[$((choice-1))]}"
|
||||||
|
log_ok "Selected device: ${DEVICE}"
|
||||||
}
|
}
|
||||||
|
|
||||||
PS_CMD=$(detect_ps_cmd)
|
########################
|
||||||
|
# PID helpers
|
||||||
|
########################
|
||||||
|
|
||||||
# --- Get PID for app ---
|
|
||||||
get_pid() {
|
get_pid() {
|
||||||
adb -s "$DEVICE" shell $PS_CMD | grep "$APP_NAME" | awk '{print $2}' | head -n 1
|
local pid=""
|
||||||
|
|
||||||
|
# Try pidof first
|
||||||
|
if adb -s "${DEVICE}" shell "command -v pidof >/dev/null 2>&1" >/dev/null 2>&1; then
|
||||||
|
pid=$(adb -s "${DEVICE}" shell "pidof -s '${PACKAGE_NAME}' 2>/dev/null || true" | tr -d '\r' || true)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fallback to ps if pidof gave nothing
|
||||||
|
if [[ -z "${pid}" ]]; then
|
||||||
|
if adb -s "${DEVICE}" shell "ps -A >/dev/null 2>&1" >/dev/null 2>&1; then
|
||||||
|
pid=$(adb -s "${DEVICE}" shell "ps -A | grep '${PACKAGE_NAME}' | awk '{print \$2}' | head -n 1" 2>/dev/null | tr -d '\r' || true)
|
||||||
|
else
|
||||||
|
pid=$(adb -s "${DEVICE}" shell "ps | grep '${PACKAGE_NAME}' | awk '{print \$2}' | head -n 1" 2>/dev/null | tr -d '\r' || true)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${pid}"
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Start logcat session ---
|
########################
|
||||||
start_logcat() {
|
# App restart helper
|
||||||
local PID=$1
|
########################
|
||||||
local LOG_FILE="$LOG_DIR/${APP_NAME}_$(date +'%Y-%m-%d_%H-%M-%S').log"
|
|
||||||
|
|
||||||
echo -e "${GREEN}📜 Logging PID $PID ($APP_NAME) → ${LOG_FILE}${NC}"
|
|
||||||
echo -e "${BLUE}🔎 Filter:${NC} $FILTER"
|
|
||||||
echo "----------------------------------------"
|
|
||||||
adb -s "$DEVICE" logcat --pid=$PID $FILTER | tee -a "$LOG_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Restart app helper (optional) ---
|
|
||||||
restart_app() {
|
restart_app() {
|
||||||
if [ -n "$PACKAGE_NAME" ]; then
|
if [[ "${AUTO_RESTART}" != true ]]; then
|
||||||
echo -e "${YELLOW}🔁 Restarting app $PACKAGE_NAME...${NC}"
|
return
|
||||||
adb -s "$DEVICE" shell am force-stop "$PACKAGE_NAME"
|
|
||||||
adb -s "$DEVICE" shell monkey -p "$PACKAGE_NAME" 1 >/dev/null 2>&1
|
|
||||||
fi
|
fi
|
||||||
|
log_warn "Restarting app ${PACKAGE_NAME}..."
|
||||||
|
adb -s "${DEVICE}" shell am force-stop "${PACKAGE_NAME}" >/dev/null 2>&1 || true
|
||||||
|
adb -s "${DEVICE}" shell monkey -p "${PACKAGE_NAME}" -c android.intent.category.LAUNCHER 1 >/dev/null 2>&1 || true
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Main loop ---
|
########################
|
||||||
LAST_PID=""
|
# Start logcat
|
||||||
|
########################
|
||||||
|
|
||||||
while true; do
|
start_logcat() {
|
||||||
PID=$(get_pid)
|
local pid="$1"
|
||||||
|
local log_file="${LOG_DIR}/${APP_NAME}_$(date +'%Y-%m-%d_%H-%M-%S')_pid_${pid}.log"
|
||||||
|
|
||||||
if [ -z "$PID" ]; then
|
log_ok "Logging PID ${pid} (${PACKAGE_NAME}) -> ${log_file}"
|
||||||
echo -e "${YELLOW}⚠️ Waiting for process '$APP_NAME' to start...${NC}"
|
log_info "Device: ${DEVICE}"
|
||||||
sleep 3
|
log_info "Filter: ${FILTER}"
|
||||||
continue
|
echo "------------------------------------------------------------"
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$PID" != "$LAST_PID" ]; then
|
(
|
||||||
if [ -n "$LAST_PID" ]; then
|
adb -s "${DEVICE}" logcat --pid="${pid}" ${FILTER} | tee -a "${log_file}"
|
||||||
echo -e "${BLUE}🔁 Process restarted (old: $LAST_PID → new: $PID).${NC}"
|
) &
|
||||||
|
LOGCAT_PID=$!
|
||||||
|
}
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Main loop
|
||||||
|
########################
|
||||||
|
|
||||||
|
main() {
|
||||||
|
select_device
|
||||||
|
|
||||||
|
log_info "Monitoring app logs for package: ${PACKAGE_NAME} (name: ${APP_NAME})"
|
||||||
|
log_info "Log directory: ${LOG_DIR}"
|
||||||
|
log_info "Auto-restart: ${AUTO_RESTART}"
|
||||||
|
|
||||||
|
local last_pid=""
|
||||||
|
local consecutive_misses=0
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
local pid
|
||||||
|
pid="$(get_pid)"
|
||||||
|
|
||||||
|
if [[ -z "${pid}" ]]; then
|
||||||
|
((consecutive_misses++))
|
||||||
|
|
||||||
|
if (( consecutive_misses == 1 )); then
|
||||||
|
log_warn "Process '${PACKAGE_NAME}' not running. Waiting for it to start..."
|
||||||
|
restart_app
|
||||||
|
else
|
||||||
|
log_info "Still waiting for process '${PACKAGE_NAME}' to start..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LAST_PID=$PID
|
if (( consecutive_misses > 0 )); then
|
||||||
|
log_ok "Process '${PACKAGE_NAME}' started with PID ${pid}."
|
||||||
|
fi
|
||||||
|
consecutive_misses=0
|
||||||
|
|
||||||
# Stop previous logcat if running
|
if [[ "${pid}" != "${last_pid}" ]]; then
|
||||||
pkill -f "adb -s $DEVICE logcat --pid=$LAST_PID" 2>/dev/null
|
if [[ -n "${last_pid}" ]]; then
|
||||||
|
log_info "Process restarted (old PID: ${last_pid} -> new PID: ${pid})."
|
||||||
|
fi
|
||||||
|
|
||||||
# Start new logcat in background
|
if [[ -n "${LOGCAT_PID}" ]]; then
|
||||||
start_logcat "$PID" &
|
kill "${LOGCAT_PID}" 2>/dev/null || true
|
||||||
fi
|
LOGCAT_PID=""
|
||||||
|
fi
|
||||||
|
|
||||||
sleep 5
|
last_pid="${pid}"
|
||||||
done
|
start_logcat "${pid}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user