Do not buffer logs in the verbose logger (#6465)

With the old policy the most recent log would not be printed until the next
log is produced (which may be indefinitely).  This change prints logs
immediately along with a time delta since the previous log.
diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart
index d8a3b5c..75179f9 100644
--- a/packages/flutter_tools/lib/executable.dart
+++ b/packages/flutter_tools/lib/executable.dart
@@ -206,9 +206,6 @@
   // Run shutdown hooks before flushing logs
   await runShutdownHooks();
 
-  // Write any buffered output.
-  logger.flush();
-
   // Give the task / timer queue one cycle through before we hard exit.
   Timer.run(() {
     printTrace('exiting with code $code');
diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart
index 8989216..38300c6 100644
--- a/packages/flutter_tools/lib/src/base/logger.dart
+++ b/packages/flutter_tools/lib/src/base/logger.dart
@@ -34,9 +34,6 @@
 
   /// Start an indeterminate progress display.
   Status startProgress(String message);
-
-  /// Flush any buffered output.
-  void flush() { }
 }
 
 class Status {
@@ -87,9 +84,6 @@
       return new Status();
     }
   }
-
-  @override
-  void flush() { }
 }
 
 class BufferLogger extends Logger {
@@ -123,34 +117,31 @@
     printStatus(message);
     return new Status();
   }
-
-  @override
-  void flush() { }
 }
 
 class VerboseLogger extends Logger {
-  _LogMessage lastMessage;
+  Stopwatch stopwatch = new Stopwatch();
+
+  VerboseLogger() {
+    stopwatch.start();
+  }
 
   @override
   bool get isVerbose => true;
 
   @override
   void printError(String message, [StackTrace stackTrace]) {
-    _emit();
-    lastMessage = new _LogMessage(_LogType.error, message, stackTrace);
+    _emit(_LogType.error, message, stackTrace);
   }
 
   @override
   void printStatus(String message, { bool emphasis: false, bool newline: true }) {
-    // TODO(ianh): We ignore newline and emphasis here.
-    _emit();
-    lastMessage = new _LogMessage(_LogType.status, message);
+    _emit(_LogType.status, message);
   }
 
   @override
   void printTrace(String message) {
-    _emit();
-    lastMessage = new _LogMessage(_LogType.trace, message);
+    _emit(_LogType.trace, message);
   }
 
   @override
@@ -159,40 +150,25 @@
     return new Status();
   }
 
-  @override
-  void flush() => _emit();
-
-  void _emit() {
-    lastMessage?.emit();
-    lastMessage = null;
-  }
-}
-
-enum _LogType {
-  error,
-  status,
-  trace
-}
-
-class _LogMessage {
-  _LogMessage(this.type, this.message, [this.stackTrace]) {
-    stopwatch.start();
-  }
-
-  final _LogType type;
-  final String message;
-  final StackTrace stackTrace;
-
-  Stopwatch stopwatch = new Stopwatch();
-
-  void emit() {
-    stopwatch.stop();
+  void _emit(_LogType type, String message, [StackTrace stackTrace]) {
+    if (message.trim().isEmpty)
+      return;
 
     int millis = stopwatch.elapsedMilliseconds;
-    String prefix = '${millis.toString().padLeft(4)} ms • ';
+    stopwatch.reset();
+
+    String prefix;
+    const int prefixWidth = 8;
+    if (millis == 0) {
+      prefix = ''.padLeft(prefixWidth);
+    } else {
+      prefix = '+$millis ms'.padLeft(prefixWidth);
+      if (millis >= 100)
+        prefix = terminal.writeBold(prefix);
+    }
+    prefix = '[$prefix] ';
+
     String indent = ''.padLeft(prefix.length);
-    if (millis >= 100)
-      prefix = terminal.writeBold(prefix.substring(0, prefix.length - 3)) + ' • ';
     String indentMessage = message.replaceAll('\n', '\n$indent');
 
     if (type == _LogType.error) {
@@ -207,6 +183,12 @@
   }
 }
 
+enum _LogType {
+  error,
+  status,
+  trace
+}
+
 class AnsiTerminal {
   AnsiTerminal() {
     // TODO(devoncarew): This detection does not work for Windows.
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index 6dc6ce2..0044c9d 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -415,9 +415,6 @@
       await _operations.writeSource(fsName, '.packages', sb.toString());
 
     printTrace('DevFS: Sync finished');
-    // NB: You must call flush after a printTrace if you want to be printed
-    // immediately.
-    logger.flush();
   }
 
   void _scanFile(String devicePath, FileSystemEntity file) {
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index ced1a89..e592d4f 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -129,11 +129,7 @@
     if (args.length == 1 && args.first == 'build')
       args = <String>['build', '-h'];
 
-    return super.run(args).then((dynamic result) {
-      return result;
-    }).whenComplete(() {
-      logger.flush();
-    });
+    return super.run(args);
   }
 
   @override