Created
May 9, 2013 20:24
-
-
Save teslacoil/5550294 to your computer and use it in GitHub Desktop.
Slightly modified version of https://github.com/jasta/android-dev-tools/blob/master/proclogcat that has improved support for Samsung ICS+ devices which hide the process name in the ActivityManager log messages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
############################################################################### | |
## | |
## Simple script designed to insert after "adb logcat" in a pipeline to track a | |
## specific package's logcat messages. | |
## | |
## I typically invoke this script as a function in my profile: | |
## | |
## function plogcat() { | |
## adb logcat | proclogcat $* | coloredlogcat.py | |
## } | |
## | |
## Then run as: | |
## | |
## $ plogcat org.devtcg.five | |
## | |
############################################################################### | |
use strict; | |
use Data::Dumper; | |
############################################################################### | |
@ARGV > 0 or usage($0); | |
# We support tracking multiple process names. Fill %trackingInfo keys with the | |
# process names, where the values are to be filled with the current pid for | |
# that process or -1 if it is presumed dead. | |
my $trackingInfo = { map { $_ => -1 } @ARGV }; | |
# Flush all writes immediately. This is necessary as we expect this script to | |
# be placed between two other programs in a pipe which outputs text very slowly | |
# (adb logcat outputs only when events happen), so it's rare to fill up the | |
# buffer quickly. Without this, the normal buffering that occurs between piped | |
# programs not directly attached to a pty would prevent the user from seeing | |
# messages as they arrive. | |
$| = 1; | |
# Lookup the pids of the processes before we start. From then on, rely on | |
# the ActivityManager to tell us as the processes dies and starts. | |
my $numPids = get_pids($trackingInfo); | |
if ($numPids == 0) { | |
print "- waiting for process ", join(' or ', keys %$trackingInfo), " -\n"; | |
} | |
while (<STDIN>) { | |
my $line = $_; | |
my ($level, $tag, $pid, $message) = $line =~ | |
m/^([A-Z])\/(.*?)\(\s*(\d+)\s*\): (.*)$/; | |
chomp $message; | |
if ($tag eq 'ActivityManager') { | |
if ($message =~ m/^Start proc (.*?) .*?: pid=(\d+) /) { | |
# Seems Samsung ICS devices are doing this for some reason... | |
if ($1 eq "app.processName") { | |
my $needPids = 0; | |
foreach my $key (keys %$trackingInfo) { | |
if (-1 == $trackingInfo->{$key}) { | |
$needPids = 1; | |
last; | |
} | |
} | |
if ($needPids) { | |
# Sometimes ps isn't ready for us, wait a bit | |
sleep(1); | |
get_pids($trackingInfo); | |
} | |
} | |
if (exists $trackingInfo->{$1}) { | |
$trackingInfo->{$1} = $2; | |
print $line; | |
} | |
} elsif ($message =~ m/Process (.*?) \(pid (\d+)\) has died./) { | |
if ($1 eq "app.processName") { | |
my $logpid = $2; | |
foreach my $key (keys %$trackingInfo) { | |
if ($logpid == $trackingInfo->{$key}) { | |
$trackingInfo->{$key} = -1; | |
} | |
} | |
} | |
if (exists $trackingInfo->{$1}) { | |
$trackingInfo->{$1} = -1; | |
print $line; | |
} | |
} elsif ($message =~ m/Killing proc (\d+):(.*?)\//) { | |
if (exists $trackingInfo->{$2}) { | |
$trackingInfo->{$2} = -1; | |
} | |
} | |
} elsif (in_list($pid, values %$trackingInfo)) { | |
print $line; | |
} | |
} | |
############################################################################### | |
sub in_list($@) { | |
my $needle = shift; | |
my @haystack = @_; | |
foreach my $hay (@haystack) { | |
if ($hay eq $needle) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
sub get_pids { | |
my $info = shift; | |
my @ps = qx{adb shell ps}; | |
if (@ps == 0) { | |
return -1; | |
} | |
my @columns = split /\s+/, (shift @ps); | |
# There's a "STATE" column slipped in between WCHAN and NAME that has no | |
# room for a column... | |
splice @columns, $#columns, 0, 'STATE'; | |
my $numFound = 0; | |
foreach (@ps) { | |
s/\s+$//; | |
my @data = split /\s+/, $_, scalar @columns; | |
my %row = map { $_ => (shift @data) } @columns; | |
if (exists $info->{$row{NAME}}) { | |
$info->{$row{NAME}} = $row{PID}; | |
$numFound++; | |
} | |
} | |
return $numFound; | |
} | |
sub usage { | |
my $prog = shift; | |
die <<"EOF" | |
Usage: adb logcat | $0 <process-name> | |
Usually, `process-name' is usually the same as your package, but not | |
necessarily. To make sure, type `adb shell ps' and look through the list. | |
EOF | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment