adb shell Logcat 以及包名称

问题描述 投票:0回答:5

是否可以在每一行中同时显示日志的包名?
使用

logcat -v 长

将包名称字段(PID 之后)保留为空。
我想用不同的标签过滤来自特定应用程序的日志,只是想知道是否可能。

android adb logcat
5个回答
51
投票

logcat
记录没有“包名称字段”。因此没有标准/内置的方法来过滤它。

尽管从 Android 7.0 开始,您可以使用

logcat --pid
选项结合
pidof -s
命令来按二进制/包名称过滤输出:

Windows

adb shell "logcat --pid=$(pidof -s <package_name>)"

Linux/MacOS

adb shell 'logcat --pid=$(pidof -s <package_name>)'

8
投票

这是我的脚本。有点生锈但仍然可以工作。

PID=`adb shell ps | grep -i <your package name> | cut -c10-15`;
adb logcat | grep $PID

实际上我有一个 python 脚本来添加更多颜色,还有一个 while 循环来在重新启动时继续监视该进程,但我想你会明白的。


7
投票

每个人似乎都指出通过 PID 过滤作为解决方案。忽略这一点。正确的方法是按 UID 进行过滤,因为 UID 永久绑定到包名称(它不会在崩溃、升级、重新启动等情况下更改)。

要查找您的包名称的 UID:

adb shell dumpsys package <PACKAGE> | grep userId

它将打印类似以下内容:

    userId=10412

然后将

--uid=10412
传递给 logcat。

很遗憾谷歌没有在任何可见的地方记录这一点,我不得不自己找到它。


2
投票

选项1

逐行输入这些:

adb shell
su
bash
PKG_PID_LIST_CACHE=$(eval $(pm list packages | cut -d ':' -f 2 | sed 's/^\(.*\)$/echo \"\$\(echo \1\) \$\(pidof \1\)\";/'))
PROC_PID_LIST_CACHE=$(ps -A -o NAME -o PID)
PID_LIST_CACHE=$(echo "$PKG_PID_LIST_CACHE\n$PROC_PID_LIST_CACHE")
function pid2pkg() { pkgName=$(echo "$PID_LIST_CACHE" | grep -w $1 | cut -d ' ' -f1 | head -1); if [ "$pkgName" != "" ] ; then echo $pkgName; else echo "*NOT RUNNING*"; fi }
eval "$(logcat -d | sed -r -e 's/([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)/\2 \$\(pid2pkg \3\) \5/g' | sed -r -e 's/(.+)/echo -e \"\1\"/g')"

logcat 输出将采用以下格式:

[Time] [Name] [Type] [Message]

示例:

14:34:59.386 wpa_supplicant E wpa_supplicant: nl80211: Failed to set IPv4 unicast in multicast filter
14:35:02.231 com.android.phone D TelephonyProvider: subIdString = 1 subId = 1
14:35:03.469 [email protected] E WifiHAL : wifi_get_logger_supported_feature_set: Error -3 happened.
14:35:03.518 system_server I WifiService: getWifiApEnabledState uid=10086
14:35:03.519 dev.ukanth.ufirewall D AFWall  : isWifiApEnabled is false
14:35:03.520 system_server I GnssLocationProvider: WakeLock released by handleMessage(UPDATE_NETWORK_STATE, 0, 123)
14:35:03.522 dev.ukanth.ufirewall I AFWall  : Now assuming wifi connection

有些系统进程没有包。例如

system_server
wpa_supplicant
。如果找不到包名称,则会显示进程名称。

注意事项

如果某个PID后面的进程不再运行,您将无法再获取包/进程名称。

进程自行退出或设备重新启动后,PID实际上可能会分配给完全不同的进程。

因此您可能想检查该进程实际运行了多长时间:

ps -e -o pid -o stime -o name

选项2

如果您希望格式更具可读性,您可以将我的日志脚本复制到您的设备并执行它:

better_logging.sh

PKG_PID_LIST_CACHE=$(eval $(pm list packages | cut -d ':' -f 2 | sed 's/^\(.*\)$/echo \"\$\(echo \1\) \$\(pidof \1\)\";/'))
PROC_PID_LIST_CACHE=$(ps -A -o NAME -o PID)
PID_LIST_CACHE=$(echo "$PKG_PID_LIST_CACHE\n$PROC_PID_LIST_CACHE")
MAX_LEN=$(echo "$PID_LIST_CACHE" | cut -d ' ' -f1 | awk '{ if ( length > L ) { L=length} }END{ print L}')
function pid2pkg() {
    pkgName=$(echo "$PID_LIST_CACHE" | grep -w $1 | cut -d ' ' -f1 | head -1);
    if [ "$pkgName" != "" ] ; then
        printf "%-${MAX_LEN}s" "$pkgName";
    else
        printf "%-${MAX_LEN}s" "<UNKNOWN (NOT RUNNING)>";
    fi
}

eval "$(\
logcat -d | \
sed -r -e 's/([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)/\2\ $\(pid2pkg \3\) \5/g' | \
sed -r -e 's/(.+)/echo -e \"\1\"/g' \
)" | \
awk '
function color(c,s) {
    printf("\033[%dm%s\033[0m\n",90+c,s)
}
/ E / {color(1,$0);next}
/ D / {color(2,$0);next}
/ W / {color(3,$0);next}
/ I / {color(4,$0);next}
{print}
'

要复制并运行它,您可以使用:

adb push better_logging.sh /sdcard/better_logging.sh
adb shell "bash /sdcard/better_logging.sh"

输出将如下所示:

log_screenshot


0
投票

这适用于

awk

adb logcat | grep -F "`adb shell ps | grep com.yourpackage  | awk '{print $2;}'`"
© www.soinside.com 2019 - 2024. All rights reserved.