Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 # pylint: disable=unused-argument | 5 # pylint: disable=unused-argument |
| 6 | 6 |
| 7 import collections | 7 import collections |
| 8 import itertools | 8 import itertools |
| 9 import logging | 9 import logging |
| 10 import subprocess | 10 import subprocess |
| 11 import tempfile | 11 import tempfile |
| 12 import time | 12 import time |
| 13 import re | 13 import re |
| 14 | 14 |
| 15 from pylib.device import adb_wrapper | 15 from pylib.device import adb_wrapper |
| 16 from pylib.device import decorators | 16 from pylib.device import decorators |
| 17 from pylib.device import device_errors | 17 from pylib.device import device_errors |
| 18 | 18 |
| 19 | 19 |
| 20 class LogcatMonitor(object): | 20 class LogcatMonitor(object): |
| 21 | 21 |
| 22 # Format: <DATE> <TIME> <PID> <TID> <LEVEL> <COMPONENT>: <MESSAGE> | 22 _THREADTIME_RE_FORMAT = ( |
| 23 _THREADTIME_RE_FORMAT = r'\S* +\S* +(%s) +(%s) +(%s) +(%s): +(%s)$' | 23 r'(?P<date>\S*) +(?P<time>\S*) +(?P<proc_id>%s) +(?P<thread_id>%s) +' |
| 24 r'(?P<log_level>%s) +(?P<component>%s): +(?P<message>%s)$') | |
| 24 | 25 |
| 25 def __init__(self, adb, clear=True, filter_specs=None): | 26 def __init__(self, adb, clear=True, filter_specs=None): |
| 26 """Create a LogcatMonitor instance. | 27 """Create a LogcatMonitor instance. |
| 27 | 28 |
| 28 Args: | 29 Args: |
| 29 adb: An instance of adb_wrapper.AdbWrapper. | 30 adb: An instance of adb_wrapper.AdbWrapper. |
| 30 clear: If True, clear the logcat when monitoring starts. | 31 clear: If True, clear the logcat when monitoring starts. |
| 31 filter_specs: An optional list of '<tag>[:priority]' strings. | 32 filter_specs: An optional list of '<tag>[:priority]' strings. |
| 32 """ | 33 """ |
| 33 if isinstance(adb, adb_wrapper.AdbWrapper): | 34 if isinstance(adb, adb_wrapper.AdbWrapper): |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 """Finds all lines in the logcat that match the provided constraints. | 91 """Finds all lines in the logcat that match the provided constraints. |
| 91 | 92 |
| 92 Args: | 93 Args: |
| 93 message_regex: The regular expression that the <message> section must | 94 message_regex: The regular expression that the <message> section must |
| 94 match. | 95 match. |
| 95 proc_id: The process ID to match. If None, matches any process ID. | 96 proc_id: The process ID to match. If None, matches any process ID. |
| 96 thread_id: The thread ID to match. If None, matches any thread ID. | 97 thread_id: The thread ID to match. If None, matches any thread ID. |
| 97 log_level: The log level to match. If None, matches any log level. | 98 log_level: The log level to match. If None, matches any log level. |
| 98 component: The component to match. If None, matches any component. | 99 component: The component to match. If None, matches any component. |
| 99 | 100 |
| 100 Returns: | 101 Yields: |
|
jbudorick
2015/03/18 16:58:40
Why is this more useful? Why is it easier to do:
perezju
2015/03/18 17:38:41
I want to be able to write, e.g.:
for m in lo
jbudorick
2015/03/18 17:43:43
I can see the case for wanting named capture group
| |
| 101 An iterable containing objects with five attributes: | 102 A match object for each matching line in the logcat. The match object |
| 102 |proc_id|: the process ID | 103 will always contain, in addition to groups defined in |message_regex|, |
| 103 |thread_id|: the thread ID | 104 the following named groups: 'date', 'time', 'proc_id', 'thread_id', |
| 104 |log_level|: the log level | 105 'log_level', 'component', and 'message'. |
| 105 |component|: the component | |
| 106 |message|: the logcat message | |
| 107 """ | 106 """ |
| 108 LogcatLine = collections.namedtuple( | |
| 109 'LogcatLine', | |
| 110 ['proc_id', 'thread_id', 'log_level', 'component', 'message']) | |
| 111 | |
| 112 if proc_id is None: | 107 if proc_id is None: |
| 113 proc_id = r'\d+' | 108 proc_id = r'\d+' |
| 114 if thread_id is None: | 109 if thread_id is None: |
| 115 thread_id = r'\d+' | 110 thread_id = r'\d+' |
| 116 if log_level is None: | 111 if log_level is None: |
| 117 log_level = r'[VDIWEF]' | 112 log_level = r'[VDIWEF]' |
| 118 if component is None: | 113 if component is None: |
| 119 component = r'[^\s:]+' | 114 component = r'[^\s:]+' |
| 120 threadtime_re = re.compile( | 115 threadtime_re = re.compile( |
| 121 type(self)._THREADTIME_RE_FORMAT % ( | 116 type(self)._THREADTIME_RE_FORMAT % ( |
| 122 proc_id, thread_id, log_level, component, message_regex)) | 117 proc_id, thread_id, log_level, component, message_regex)) |
| 123 | 118 |
| 124 regexed_lines = ( | 119 for line in self._adb.Logcat(dump=True, logcat_format='threadtime'): |
| 125 re.match(threadtime_re, l) | 120 m = re.match(threadtime_re, line) |
| 126 for l in self._adb.Logcat(dump=True, logcat_format='threadtime')) | 121 if m: |
| 127 only_matches = (m for m in regexed_lines if m) | 122 yield m |
| 128 return (LogcatLine(*m.group(1, 2, 3, 4, 5)) for m in only_matches) | |
| 129 | 123 |
| 130 def Start(self): | 124 def Start(self): |
| 131 """Starts the logcat monitor. | 125 """Starts the logcat monitor. |
| 132 | 126 |
| 133 Clears the logcat if |clear| was set in |__init__|. | 127 Clears the logcat if |clear| was set in |__init__|. |
| 134 """ | 128 """ |
| 135 if self._clear: | 129 if self._clear: |
| 136 self._adb.Logcat(clear=True) | 130 self._adb.Logcat(clear=True) |
| 137 | 131 |
| 138 def __enter__(self): | 132 def __enter__(self): |
| 139 """Starts the logcat monitor.""" | 133 """Starts the logcat monitor.""" |
| 140 self.Start() | 134 self.Start() |
| 141 return self | 135 return self |
| 142 | 136 |
| 143 def __exit__(self, exc_type, exc_val, exc_tb): | 137 def __exit__(self, exc_type, exc_val, exc_tb): |
| 144 """Stops the logcat monitor.""" | 138 """Stops the logcat monitor.""" |
| 145 pass | 139 pass |
| OLD | NEW |