r'^.*: Start proc (\d+):([a-zA-Z0-9._:]+)/[a-z0-9]+ for (.*)$') PID_START_DALVIK = re.compile( r'^E/dalvikvm\(\s*(\d+)\): >>>>> ([a-zA-Z0-9._:]+) \[ userId:0 \| appId:(\d+) \]$' ) PID_KILL = re.compile(r'^Killing (\d+):([a-zA-Z0-9._:]+)/[^:]+: (.*)$') PID_LEAVE = re.compile(r'^No longer want ([a-zA-Z0-9._:]+) \(pid (\d+)\): .*$') PID_DEATH = re.compile(r'^Process ([a-zA-Z0-9._:]+) \(pid (\d+)\) has died.?$') ADB_LOG_REGEX_EXP = 'data,time,process,thread,level,tag,message="(.\S*) *(.\S*) *(\d*) *(\d*) *([A-Z]) *([^:]*): *(.*?)$"' BUG_LINE = re.compile(r'.*nativeGetEnabledTags.*') BACKTRACE_LINE = re.compile(r'^#(.*?)pc\s(.*?)$') RULES = { # 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), } class Adb: all = None min_level = None package_name = None tag = None header_size = None ignored_tag = None log_regex = None catchall_package = None named_processes = None pids = None
def setup(self, args): self.processor = LogProcessor(args.hide_same_tags) self.min_level = LOG_LEVELS_MAP[args.min_level.upper()] self.all = args.all self.ignored_tag = args.ignored_tag self.tag = args.tag self.package_name = args.package_or_path self.processor.setup_condition(tag_keywords=args.tag_keywords) if args.yml is not None: conf_file_path = get_conf_path(args.yml) if not exists(handle_home_case(conf_file_path)): exit('you provide conf file path: ' + conf_file_path + ' is not exist!') conf_loader = ConfLoader() conf_loader.load(conf_file_path) yml_package = conf_loader.get_package() if yml_package is not None: self.package_name.append(yml_package) yml_adb_log_regex = conf_loader.get_adb_log_line_regex() if yml_adb_log_regex is not None: self.log_regex = LogRegex(yml_adb_log_regex) self.processor.setup_condition( tag_keywords=conf_loader.get_tag_keyword_list()) self.processor.setup_trans( trans_msg_map=conf_loader.get_trans_msg_map(), trans_tag_map=conf_loader.get_trans_tag_map(), hide_msg_list=conf_loader.get_hide_msg_list()) self.processor.setup_highlight( highlight_list=conf_loader.get_highlight_list()) self.processor.setup_separator( separator_rex_list=conf_loader.get_separator_regex_list()) if self.log_regex is None: self.log_regex = LogRegex(ADB_LOG_REGEX_EXP) base_adb_command = ['adb'] if args.device_serial: base_adb_command.extend(['-s', args.device_serial]) if args.use_device: base_adb_command.append('-d') if args.use_emulator: base_adb_command.append('-e') if args.current_app: system_dump_command = base_adb_command + [ "shell", "dumpsys", "activity", "activities" ] system_dump = subprocess.Popen(system_dump_command, stdout=PIPE, stderr=PIPE).communicate()[0] running_package_name = re.search(".*TaskRecord.*A[= ]([^ ^}]*)", system_dump).group(1) self.package_name.append(running_package_name) if len(self.package_name) == 0: self.all = True # Store the names of packages for which to match all processes. self.catchall_package = list( filter(lambda package: package.find(":") == -1, self.package_name)) # Store the name of processes to match exactly. named_processes = filter(lambda package: package.find(":") != -1, self.package_name) # Convert default process names from <package>: (cli notation) to <package> (android notation) in the exact names match group. self.named_processes = map( lambda package: package if package.find(":") != len(package) - 1 else package[:-1], named_processes) self.header_size = args.tag_width + 1 + 3 + 1 # space, level, space # 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_M?ALLOC|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 adb_command = base_adb_command[:] adb_command.append('logcat') adb_command.extend(['-v', 'brief']) adb_command.extend(['-v', 'threadtime']) # Clear log before starting logcat if args.clear_logcat: adb_clear_command = list(adb_command) adb_clear_command.append('-c') adb_clear = subprocess.Popen(adb_clear_command) while adb_clear.poll() is None: pass if sys.stdin.isatty(): self.adb = subprocess.Popen(adb_command, stdout=PIPE, stderr=STDOUT, stdin=PIPE) else: self.adb = FakeStdinProcess() self.pids = set() ps_command = base_adb_command + ['shell', 'ps'] ps_pid = subprocess.Popen(ps_command, stdin=PIPE, stdout=PIPE, stderr=PIPE) while True: try: line = ps_pid.stdout.readline().decode('utf-8', 'replace').strip() except KeyboardInterrupt: break if len(line) == 0: break pid_match = PID_LINE.match(line) if pid_match is not None: pid = pid_match.group(1) proc = pid_match.group(2) if proc in self.catchall_package: self.pids.add(pid)
def process_decode_content(self, line, time, level, tag, process, thread, message): match_condition = True # filter if self.tag_keywords is not None and tag is not None: if not keywords_regex(tag, self.tag_keywords): match_condition = False self.pre_line_match = False else: self.pre_line_match = True if self.line_keywords is not None: if not keywords_regex(line, self.line_keywords): match_condition = False self.pre_line_match = False else: self.pre_line_match = True if match_condition and tag is None and not self.pre_line_match: match_condition = False # if 'special world' in line: # match_precondition = True if not match_condition: return None, None, None msgkey = None # the handled current line linebuf = '' # time if time is not None: time = time[-TIME_WIDTH:].rjust(TIME_WIDTH) linebuf += time linebuf += ' ' elif self.regex_parser.is_contain_time(): linebuf += ' ' * TIME_WIDTH linebuf += ' ' # thread if thread is not None: thread = thread.strip() thread = thread[-THREAD_WIDTH:].rjust(THREAD_WIDTH) linebuf += thread linebuf += ' ' elif self.regex_parser.is_contain_thread(): linebuf += ' ' * THREAD_WIDTH linebuf += ' ' # tag if tag is not None and (not self.hide_same_tags or tag != self.last_tag): self.last_tag = tag tag = tag.strip() color = allocate_color(tag) tag = tag.strip() tag = tag[-TAG_WIDTH:].rjust(TAG_WIDTH) linebuf += colorize(tag, fg=color) linebuf += ' ' elif self.regex_parser.is_contain_tag(): linebuf += ' ' * TAG_WIDTH linebuf += ' ' # level if level is not None: if level in TAGTYPES: linebuf += TAGTYPES[level] else: linebuf += ' ' + level + ' ' linebuf += ' ' elif self.regex_parser.is_contain_level(): linebuf += ' ' linebuf += ' ' # message # -separator if self.separator is not None: msgkey = self.separator.process(message) # -trans if self.trans is not None: message = self.trans.trans_msg(message) message = self.trans.hide_msg(message) message = self.trans.trans_tag(tag, message) if self.highlight_list is not None: for highlight in self.highlight_list: if highlight in message: message = message.replace( highlight, termcolor(fg=BLACK, bg=allocate_color(highlight)) + highlight + RESET) linebuf += message return msgkey, linebuf, match_condition