adb shell Logcat with Package Name
Asked Answered
M

5

21

Is it possible to also display the Log's Package Name in each line?
Using

logcat -v long

leaves exactly the package name field (after PID) empty.
I want to filter the Logs from a specific application with different Tags, just wondering if it is possible.

Manipular answered 23/9, 2015 at 9:25 Comment(2)
I'd like to comment for @Alexander, but apparently I only have enough brownie points to answer. The pipe through cut -c10-15 grabs the pid from the whole line of text. cut --helpLumbago
Does this answer your question? Filter LogCat to get only the messages from My Application in Android?Hippo
B
51

logcat record does not have a "package name field". Therefore there is no standard/built-in way to filter by it.

Although since Android 7.0 you can use logcat --pid option combined with pidof -s command to filter output by binary/package name:

Windows

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

Linux/MacOS

adb shell 'logcat --pid=$(pidof -s <package_name>)'
Bop answered 23/9, 2015 at 10:50 Comment(6)
Not working for me on an Marshmallow-based device: $ adb -d shell logcat --pid=6693 Unrecognized Option - Usage: logcat [options] [filterspecs]... doesn't seem like --pid is a valid option any more.Kassel
@Jules, logcat --pid was introduced in NougatBop
It work for me. The only things is that I type first adb shell then on the shell I type logcat --pid=$(pidof -s <package_name>)Gharry
It works for me. Remember to replace " with ' for Linux/MacOSCurriculum
For Windows PowerShell: adb logcat --pid=$(adb shell pidof -s <package name>)Selfwill
Finally, an answer that actually works. Thanks!Patrickpatrilateral
J
8

This is my script. A little rusty but still working.

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

Actually I have a python script to add more colours, and a while loop to keep monitoring for that process when it gets restarted, but I think you'll get the point.

Jowl answered 14/1, 2016 at 15:30 Comment(1)
I actually don't know how to use this.. I neither know how to launch scripts from the command line nor how to use this in my Android app (where I actually want/need this). I am currently doing it with Runtime.getRuntime().exec("su -c logcat -d -v long"); but I don't get Package names.Manipular
P
6

Everyone seems to point to filtering by PID as the solution. Ignore that. The proper way is to filter by UID, since a UID is permanently bound to a package name (it won't change on crashes, upgrades, reboots, etc.).

To find the UID of your package name:

adb shell dumpsys package <PACKAGE> | grep userId

It will print something like:

    userId=10412

Then pass --uid=10412 to logcat.

It's a shame Google doesn't document this anywhere visible, I've had to find it on my own. Please upvote for visibility.

Peeve answered 13/3, 2023 at 12:42 Comment(1)
Thank you, Alba! Most of the time what I used is filter by TAG $ logcat -s "TAG:*" "*:S". TAG is a custom string which you used by logging over your favourite logger.Posner
D
2

Option 1

Enter these line by line:

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')"

The logcat output will be in the following format:

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

Example:

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

Some system processes don't have packages. system_server and wpa_supplicant for instance. If a package name can't be found, the process name will be displayed instead.

Caveats:

If the process behind a certain PID is not running anymore, you can't get the package/process name anymore.

After a process exited itself or your device restarted, the PIDs may actually be assigned to completely different processes.

So you might want to check for how long the process has actually been running:

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

Option 2

If you want the formatting to be a bit more readable, you can copy my logging script to your device and execute it:

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}
'

To copy and run it, you can use:

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

Output will look like this:

log_screenshot

Detention answered 27/7, 2018 at 12:52 Comment(1)
Is there anyway to do this without root? Having the PID updated to the process name in a adb logcat would be amazing.Scintillometer
S
0

This works with awk.

adb logcat | grep -F "`adb shell ps | grep com.yourpackage  | awk '{print $2;}'`"
Salesroom answered 23/6, 2022 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.