Commit 488e5dcd authored by Devon Carew's avatar Devon Carew

log for specific adb devices

parent 4ec96084
......@@ -307,7 +307,7 @@ class AndroidDevice extends Device {
TargetPlatform get platform => TargetPlatform.android;
void clearLogs() {
runSync(adbCommandForDevice(<String>['logcat', '-c']));
runSync(adbCommandForDevice(<String>['-s', id, 'logcat', '-c']));
}
DeviceLogReader createLogReader() => new _AdbLogReader(this);
......@@ -322,10 +322,12 @@ class AndroidDevice extends Device {
]));
}
// Return the most recent timestamp in the Android log. The format can be
// Return the most recent timestamp in the Android log. The format can be
// passed to logcat's -T option.
String lastLogcatTimestamp() {
String output = runCheckedSync(adbCommandForDevice(<String>['logcat', '-v', 'time', '-t', '1']));
String output = runCheckedSync(adbCommandForDevice(<String>[
'-s', id, 'logcat', '-v', 'time', '-t', '1'
]));
RegExp timeRegExp = new RegExp(r'^\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}', multiLine: true);
Match timeMatch = timeRegExp.firstMatch(output);
......@@ -350,7 +352,9 @@ class AndroidDevice extends Device {
String tracePath = null;
bool isComplete = false;
while (!isComplete) {
String logs = runCheckedSync(adbCommandForDevice(<String>['logcat', '-d', '-T', beforeStop]));
String logs = runCheckedSync(adbCommandForDevice(<String>[
'-s', id, 'logcat', '-d', '-T', beforeStop
]));
Match fileMatch = traceRegExp.firstMatch(logs);
if (fileMatch != null && fileMatch[1] != null) {
tracePath = fileMatch[1];
......@@ -484,16 +488,15 @@ List<AndroidDevice> getAdbDevices() {
return devices;
}
/// A log reader that logs from `adb logcat`. This will have the same output as
/// another copy of [_AdbLogReader], and the two instances will be equivalent.
/// A log reader that logs from `adb logcat`.
class _AdbLogReader extends DeviceLogReader {
_AdbLogReader(this.device);
final AndroidDevice device;
String get name => 'Android';
String get name => device.name;
Future<int> logs({bool clear: false}) async {
Future<int> logs({ bool clear: false, bool showPrefix: false }) async {
if (!device.isConnected())
return 2;
......@@ -501,6 +504,8 @@ class _AdbLogReader extends DeviceLogReader {
device.clearLogs();
return await runCommandAndStreamOutput(device.adbCommandForDevice(<String>[
'-s',
device.id,
'logcat',
'-v',
'tag', // Only log the tag and the message
......@@ -509,15 +514,16 @@ class _AdbLogReader extends DeviceLogReader {
'ActivityManager:W',
'System.err:W',
'*:F',
]), prefix: '[Android] ');
]), prefix: showPrefix ? '[$name] ' : '');
}
// Intentionally constant; overridden because we've overridden the `operator ==` method below.
int get hashCode => name.hashCode;
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
return other is _AdbLogReader;
if (other is! _AdbLogReader)
return false;
return other.device.id == device.id;
}
}
......@@ -35,15 +35,15 @@ class LogsCommand extends FlutterCommand {
bool clear = argResults['clear'];
Set<DeviceLogReader> readers = new Set<DeviceLogReader>();
List<DeviceLogReader> readers = new List<DeviceLogReader>();
for (Device device in devices) {
readers.add(device.createLogReader());
}
printStatus('Showing logs for ${readers.join(', ')}:');
printStatus('Showing ${readers.join(', ')} logs:');
List<int> results = await Future.wait(readers.map((DeviceLogReader reader) async {
int result = await reader.logs(clear: clear);
int result = await reader.logs(clear: clear, showPrefix: devices.length > 1);
if (result != 0)
printError('Error listening to $reader logs.');
return result;
......
......@@ -189,7 +189,7 @@ abstract class Device {
abstract class DeviceLogReader {
String get name;
Future<int> logs({ bool clear: false });
Future<int> logs({ bool clear: false, bool showPrefix: false });
int get hashCode;
bool operator ==(dynamic other);
......
......@@ -232,13 +232,13 @@ class _IOSDeviceLogReader extends DeviceLogReader {
String get name => device.name;
// TODO(devoncarew): Support [clear].
Future<int> logs({ bool clear: false }) async {
Future<int> logs({ bool clear: false, bool showPrefix: false }) async {
if (!device.isConnected())
return 2;
return await runCommandAndStreamOutput(
<String>[device.loggerPath],
prefix: '[$name] ',
prefix: showPrefix ? '[$name] ' : '',
filter: new RegExp(r'Runner')
);
}
......
......@@ -410,7 +410,7 @@ class _IOSSimulatorLogReader extends DeviceLogReader {
String get name => device.name;
Future<int> logs({ bool clear: false }) async {
Future<int> logs({ bool clear: false, bool showPrefix: false }) async {
if (!device.isConnected())
return 2;
......@@ -432,7 +432,7 @@ class _IOSSimulatorLogReader extends DeviceLogReader {
Future<int> result = runCommandAndStreamOutput(
<String>['tail', '-n', '+0', '-F', device.logFilePath],
prefix: '[$name] ',
prefix: showPrefix ? '[$name] ' : '',
mapFunction: (String string) {
Match match = mapRegex.matchAsPrefix(string);
if (match != null) {
......@@ -465,7 +465,7 @@ class _IOSSimulatorLogReader extends DeviceLogReader {
// ReportCrash[37965]: Saved crash report for FlutterRunner[37941]...
runCommandAndStreamOutput(
<String>['tail', '-F', '/private/var/log/system.log'],
prefix: '[$name] ',
prefix: showPrefix ? '[$name] ' : '',
filter: new RegExp(r' FlutterRunner\[\d+\] '),
mapFunction: (String string) {
Match match = mapRegex.matchAsPrefix(string);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment