From decd14471b59296851d3cbf7349d0afee5525843 Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Wed, 12 Jun 2013 14:45:48 -0700 Subject: [PATCH 1/3] Automatically color StrictMode violations log messages. If the user opts-in to GC coloring (with --color-gc flag) then color freed space and main thread block times. --- pidcat.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/pidcat.py b/pidcat.py index 71ab7d9..482210f 100755 --- a/pidcat.py +++ b/pidcat.py @@ -32,6 +32,7 @@ import struct parser = argparse.ArgumentParser(description='Filter logcat by package name') parser.add_argument('package', help='Application package name') parser.add_argument('--tag-width', metavar='N', dest='tag_width', type=int, default=22, help='Width of log tag') +parser.add_argument('--color-gc', dest='color_gc', action='store_true', help='Color garbage collection') args = parser.parse_args() @@ -43,17 +44,16 @@ HEIGHT, WIDTH = struct.unpack('hh',data) BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) -def colorize(message, fg=None, bg=None): - ret = '' +RESET = '\033[0m' + +def termcolor(fg=None, bg=None): codes = [] if fg is not None: codes.append('3%d' % fg) if bg is not None: codes.append('10%d' % bg) - if codes: - ret += '\033[%sm' % ';'.join(codes) - ret += message - if codes: - ret += '\033[0m' - return ret + return '\033[%sm' % ';'.join(codes) if codes else '' + +def colorize(message, fg=None, bg=None): + return termcolor(fg, bg) + message + RESET def indent_wrap(message): wrap_area = WIDTH - header_size @@ -77,6 +77,7 @@ KNOWN_TAGS = { 'ActivityThread': WHITE, 'AndroidRuntime': CYAN, 'jdwp': WHITE, + 'StrictMode': WHITE, } def allocate_color(tag): @@ -92,9 +93,20 @@ def allocate_color(tag): RULES = { - #re.compile(r"([\w\.@]+)=([\w\.@]+)"): r"%s\1%s=%s\2%s" % (format(fg=BLUE), format(fg=GREEN), format(fg=BLUE), format(reset=True)), + # StrictMode policy violation; ~duration=319 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1 + re.compile(r'^(StrictMode policy violation)(; ~duration=)(\d+ ms)') + : r'%s\1%s\2%s\3%s' % (termcolor(RED), RESET, termcolor(YELLOW), RESET), } +# Only enable GC coloring if the user opted-in +if args.color_gc: + # GC_CONCURRENT freed 3617K, 29% free 20525K/28648K, paused 4ms+5ms, total 85ms + key = re.compile(r'^(GC_(?:CONCURRENT|FOR_MALLOC|EXTERNAL_ALLOC|EXPLICIT) )(freed \d+.)(, \d+\% free \d+./\d+., )(paused \d+ms\+\d+ms)') + val = r'\1%s\2%s\3%s\4%s' % (termcolor(GREEN), RESET, termcolor(YELLOW), RESET) + + RULES[key] = val + + TAGTYPES = { 'V': colorize(' V ', fg=WHITE, bg=BLACK), 'D': colorize(' D ', fg=BLACK, bg=BLUE), From 27d30b66b1422c04c190e02f45dca844f7bd049e Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Wed, 12 Jun 2013 14:53:14 -0700 Subject: [PATCH 2/3] Multiple package support. Closes #7. --- pidcat.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pidcat.py b/pidcat.py index 482210f..069025a 100755 --- a/pidcat.py +++ b/pidcat.py @@ -30,7 +30,7 @@ import termios import struct parser = argparse.ArgumentParser(description='Filter logcat by package name') -parser.add_argument('package', help='Application package name') +parser.add_argument('package', nargs='+', help='Application package name(s)') parser.add_argument('--tag-width', metavar='N', dest='tag_width', type=int, default=22, help='Width of log tag') parser.add_argument('--color-gc', dest='color_gc', action='store_true', help='Color garbage collection') @@ -132,17 +132,17 @@ def parse_death(tag, message): kill = PID_KILL.match(message) if kill: pid = kill.group(1) - if kill.group(2) == args.package and pid in pids: + if kill.group(2) in args.package and pid in pids: return pid leave = PID_LEAVE.match(message) if leave: pid = leave.group(2) - if leave.group(1) == args.package and pid in pids: + if leave.group(1) in args.package and pid in pids: return pid death = PID_DEATH.match(message) if death: pid = death.group(2) - if death.group(1) == args.package and pid in pids: + if death.group(1) in args.package and pid in pids: return pid return None @@ -166,7 +166,7 @@ while True: if start is not None: line_package, target, line_pid, line_uid, line_gids = start.groups() - if line_package == args.package: + if line_package in args.package: pids.add(line_pid) linebuf = colorize(' ' * (header_size - 1), bg=WHITE) From bce5ad6529605bd673fa1146dff5ab9abaa4d720 Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Wed, 12 Jun 2013 22:26:58 -0700 Subject: [PATCH 3/3] Better GC message detection. --- pidcat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pidcat.py b/pidcat.py index 069025a..3603cc4 100755 --- a/pidcat.py +++ b/pidcat.py @@ -101,7 +101,7 @@ RULES = { # Only enable GC coloring if the user opted-in if args.color_gc: # GC_CONCURRENT freed 3617K, 29% free 20525K/28648K, paused 4ms+5ms, total 85ms - key = re.compile(r'^(GC_(?:CONCURRENT|FOR_MALLOC|EXTERNAL_ALLOC|EXPLICIT) )(freed \d+.)(, \d+\% free \d+./\d+., )(paused \d+ms\+\d+ms)') + key = re.compile(r'^(GC_(?:CONCURRENT|FOR_M?ALLOC|EXTERNAL_ALLOC|EXPLICIT) )(freed