Skip to content

Instantly share code, notes, and snippets.

@xaethos
Created June 22, 2012 05:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save xaethos/2970565 to your computer and use it in GitHub Desktop.
Save xaethos/2970565 to your computer and use it in GitHub Desktop.
adb logcat with color and filter by package/process name
#!/usr/bin/env ruby
require 'colorize'
require 'optparse'
class LOLCat
def initialize options = {}
@tagspecs = options[:tagspecs] || []
@whitelist = options[:processes] || []
@processes = Hash.new
end
def level_color level
case level
when 'V'
{ color: :default, background: :default }
when 'D'
{ color: :blue, background: :light_black }
when 'I'
{ color: :green, background: :light_black }
when 'W'
{ color: :black, background: :yellow }
when 'E'
{ color: :white, background: :red }
else
{ color: :default }
end
end
def fetch_processes
puts '>>> fetching processes'.light_blue
IO.popen('adb shell ps').each do |line|
# Line format:
# USER PID PPID VSIZE RSS WCHAN PC NAME
# app_5 228 32 83520 20552 ffffffff afd0c51c S com.android.music
match = line.match /(?'user'\S+)\s+(?'pid'\d+)\s+\d+\s+\d+\s+\d+\s+\S+\s+\S+\s+\S\s(?'name'\S+)/
@processes[match[:pid]] = { user: match[:user], name: match[:name] } if match
end
end
def print_processes
fetch_processes
@processes.each { |pid, info| puts "%6{pid} %10{user} %{name}" % info.merge(pid: pid) }
end
def rainbow
IO.popen(%w[adb lolcat] + @tagspecs).each do |line|
# Line format:
# level/tag( pid): msg
# I/ARMAssembler( 60): generated scanline__00000077:03515104_00001004_00000000 [ 65 ipp] (85 ins) at [0x445ed6e0:0x445ed834] in 863000 ns
match = line.match /(?'level'.)\/(?'tag'[^(]*)\(\s*(?'pid'\d+)\): (?'message'.*)/
if match
fetch_processes unless @processes.keys.include?(match[:pid])
process = @processes[match[:pid]]
if process
next unless @whitelist.empty? || @whitelist.include?(process[:name])
else
# Old process is no longer on list. Don't wanna fetch for this guy again.
@processes[match[:pid]] = false
end
head = "%5d|%-20s" % [match[:pid], match[:tag][0,20]]
puts head.to_s.colorize(level_color match[:level]) << ' ' << match[:message]
else
puts line.chomp
end
end
end
end
options = {}
optparse = OptionParser.new do |opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: lolcat [options] tagspec1 tagspec2 ..."
# Define the options, and what they do
options[:list_processes] = false
opts.on( '-l', '--list-processes', 'List processes and exit' ) do
options[:list_processes] = true
end
# Define the options, and what they do
options[:processes] = []
opts.on( '-p', '--process NAME', 'Show only this process. Can use multiple times.' ) do |name|
options[:processes] << name
end
# This displays the help screen, all programs are
# assumed to have this option.
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
optparse.parse!
options[:tagspecs] = ARGV.dup
lolcat = LOLCat.new options
if options[:list_processes]
lolcat.print_processes
else
lolcat.rainbow
end
@giangm9
Copy link

giangm9 commented Nov 28, 2017

how to use this script?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment