Last active
April 23, 2025 22:05
-
-
Save Terrance/2600d51594ec1672a2acb1f5530e88cd to your computer and use it in GitHub Desktop.
Script to parse Android logcat entries, show package names, highlight by level and mute noise.
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 python3 | |
import argparse | |
from collections import defaultdict | |
from datetime import date, datetime | |
import os.path | |
from pathlib import Path | |
import re | |
import subprocess | |
import sys | |
LEVELS = {"V": 30, "I": 35, "W": 33, "E": 31} | |
NOISE_TAGS = set() | |
NOISE_PKGS = set() | |
NOISE_MSGS = set() | |
def style(text, *codes): | |
return "\33[{}m{}\33[0m".format(";".join(str(code) for code in codes), text) | |
def main(noise=False): | |
dumpsys = subprocess.run(("/system/bin/dumpsys", "package", "packages"), capture_output=True) | |
uids = defaultdict(list) | |
for line in dumpsys.stdout.decode().splitlines(): | |
if line.startswith(" Package ["): | |
package = line.split("[")[1].split("]")[0] | |
elif line.startswith(" userId="): | |
uids[line.split("=", 1)[1]].append(package) | |
packages = { | |
uid: names[0] if len(names) == 1 else f"{sorted(names)[0]} +{len(names)}" | |
for uid, names in uids.items() | |
} | |
logcat = subprocess.Popen(("rish", "-c", "logcat -v uid"), stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
prev = today = date.today() | |
try: | |
while True: | |
line = logcat.stdout.readline() | |
if not line: | |
break | |
safe = line[:38].decode() | |
if not safe[0].isdigit(): | |
sys.stdout.buffer.write(line) | |
continue | |
ts = datetime.strptime(safe[:18], "%m-%d %H:%M:%S.%f").replace(year=today.year) | |
if ts.day != prev.day: | |
prev = ts.date() | |
today = date.today() | |
time = ts.strftime("%H:%M:%S.%f")[:-3] if ts.day == today.day else ts.strftime("%d/%m %H:%M") | |
uid = safe[19:24].strip() | |
pkg = packages.get(uid, "") | |
pid = safe[25:30].strip() | |
tid = safe[31:36] | |
lvl = safe[37] | |
tag, msg = re.split(b" *: ?", line[39:-1], 1) | |
tag = tag.decode() | |
try: | |
msg = msg.decode() | |
except UnicodeDecodeError: | |
msg = repr(msg)[2:-1] | |
if tag in NOISE_TAGS or pkg in NOISE_PKGS or any(noise in msg for noise in NOISE_MSGS): | |
colour = 30 | |
else: | |
colour = LEVELS.get(lvl, 0) | |
if not noise and colour == 30: | |
continue | |
print(style(f"{time} {uid:>5} {pkg:30.30} {pid:>5} {lvl} {tag:40.40} {msg}", colour)) | |
except KeyboardInterrupt: | |
pass | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument("-n", "--noise", action="store_true", help="include noise") | |
args = parser.parse_args() | |
main(args.noise) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment