Beispiel #1
0
    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
Beispiel #2
0
    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)
Beispiel #3
0
    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