Unverified Commit 22a61b94 authored by Lau Ching Jun's avatar Lau Ching Jun Committed by GitHub

Allow passing verbose log from flutter daemon. (#132828)

It would be helpful for debugging if we can choose to also receive remote verbose logs.
parent 865b5b48
......@@ -335,6 +335,7 @@ class DaemonDomain extends Domain {
registerHandler('version', version);
registerHandler('shutdown', shutdown);
registerHandler('getSupportedPlatforms', getSupportedPlatforms);
registerHandler('setNotifyVerbose', setNotifyVerbose);
sendEvent(
'daemon.connected',
......@@ -346,7 +347,7 @@ class DaemonDomain extends Domain {
_subscription = daemon.notifyingLogger!.onMessage.listen((LogMessage message) {
if (daemon.logToStdout) {
if (message.level == 'status') {
if (message.level == 'status' || message.level == 'trace') {
// We use `print()` here instead of `stdout.writeln()` in order to
// capture the print output for testing.
// ignore: avoid_print
......@@ -461,6 +462,11 @@ class DaemonDomain extends Domain {
};
}
}
/// If notifyVerbose is set, the daemon will forward all verbose logs.
Future<void> setNotifyVerbose(Map<String, Object?> args) async {
daemon.notifyingLogger?.notifyVerbose = _getBoolArg(args, 'verbose') ?? true;
}
}
typedef RunOrAttach = Future<void> Function({
......@@ -1210,7 +1216,7 @@ Object? _toJsonable(Object? obj) {
}
class NotifyingLogger extends DelegatingLogger {
NotifyingLogger({ required this.verbose, required Logger parent }) : super(parent) {
NotifyingLogger({ required this.verbose, required Logger parent, this.notifyVerbose = false }) : super(parent) {
_messageController = StreamController<LogMessage>.broadcast(
onListen: _onListen,
);
......@@ -1220,6 +1226,8 @@ class NotifyingLogger extends DelegatingLogger {
final List<LogMessage> messageBuffer = <LogMessage>[];
late StreamController<LogMessage> _messageController;
bool notifyVerbose = false;
void _onListen() {
if (messageBuffer.isNotEmpty) {
messageBuffer.forEach(_messageController.add);
......@@ -1277,6 +1285,10 @@ class NotifyingLogger extends DelegatingLogger {
@override
void printTrace(String message) {
if (notifyVerbose) {
_sendMessage(LogMessage('trace', message));
return;
}
if (!verbose) {
return;
}
......
......@@ -195,6 +195,63 @@ void main() {
Logger: () => notifyingLogger,
});
testUsingContext('printTrace should send daemon.logMessage event when notifyVerbose is enabled', () async {
daemon = Daemon(
daemonConnection,
notifyingLogger: notifyingLogger,
);
notifyingLogger.notifyVerbose = false;
globals.printTrace('daemon.logMessage test 1');
notifyingLogger.notifyVerbose = true;
globals.printTrace('daemon.logMessage test 2');
final DaemonMessage response = await daemonStreams.outputs.stream.firstWhere((DaemonMessage message) {
return message.data['event'] == 'daemon.logMessage' && (message.data['params']! as Map<String, Object?>)['level'] == 'trace';
});
expect(response.data['id'], isNull);
expect(response.data['event'], 'daemon.logMessage');
final Map<String, String> logMessage = castStringKeyedMap(response.data['params'])!.cast<String, String>();
expect(logMessage['level'], 'trace');
expect(logMessage['message'], 'daemon.logMessage test 2');
}, overrides: <Type, Generator>{
Logger: () => notifyingLogger,
});
testUsingContext('daemon.setNotifyVerbose command should update the notify verbose status to true', () async {
daemon = Daemon(
daemonConnection,
notifyingLogger: notifyingLogger,
);
expect(notifyingLogger.notifyVerbose, false);
daemonStreams.inputs.add(DaemonMessage(<String, Object?>{
'id': 0,
'method': 'daemon.setNotifyVerbose',
'params': <String, Object?>{
'verbose': true,
},
}));
await daemonStreams.outputs.stream.firstWhere(_notEvent);
expect(notifyingLogger.notifyVerbose, true);
});
testUsingContext('daemon.setNotifyVerbose command should update the notify verbose status to false', () async {
daemon = Daemon(
daemonConnection,
notifyingLogger: notifyingLogger,
);
notifyingLogger.notifyVerbose = false;
daemonStreams.inputs.add(DaemonMessage(<String, Object?>{
'id': 0,
'method': 'daemon.setNotifyVerbose',
'params': <String, Object?>{
'verbose': false,
},
}));
await daemonStreams.outputs.stream.firstWhere(_notEvent);
expect(notifyingLogger.notifyVerbose, false);
});
testUsingContext('daemon.shutdown command should stop daemon', () async {
daemon = Daemon(
daemonConnection,
......@@ -755,6 +812,19 @@ void main() {
expect(bufferLogger.errorText, isEmpty);
});
testUsingContext('sends trace messages in notify verbose mode', () async {
final NotifyingLogger logger = NotifyingLogger(verbose: false, parent: bufferLogger, notifyVerbose: true);
final Future<LogMessage> messageResult = logger.onMessage.first;
logger.printTrace('hello');
final LogMessage message = await messageResult;
expect(message.level, 'trace');
expect(message.message, 'hello');
expect(bufferLogger.errorText, isEmpty);
});
testUsingContext('buffers messages sent before a subscription', () async {
final NotifyingLogger logger = NotifyingLogger(verbose: false, parent: bufferLogger);
......
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