Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Message logging. | 5 /// Message logging. |
| 6 library pub.log; | 6 library pub.log; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:io'; | 10 import 'dart:io'; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 | 41 |
| 42 /// The list of recorded log messages. Will only be recorded if | 42 /// The list of recorded log messages. Will only be recorded if |
| 43 /// [recordTranscript()] is called. | 43 /// [recordTranscript()] is called. |
| 44 Transcript<Entry> _transcript; | 44 Transcript<Entry> _transcript; |
| 45 | 45 |
| 46 /// The currently-animated progress indicator, if any. | 46 /// The currently-animated progress indicator, if any. |
| 47 /// | 47 /// |
| 48 /// This will also be in [_progresses]. | 48 /// This will also be in [_progresses]. |
| 49 Progress _animatedProgress; | 49 Progress _animatedProgress; |
| 50 | 50 |
| 51 /// The Timer used to coalesce a number of collapsible messages. | |
| 52 /// | |
| 53 /// This is `null` if no collapsible messages are waiting to be displayed. | |
| 54 Timer _collapsibleTimer; | |
| 55 | |
| 56 /// The queue of collapsible messages waiting to be displayed. | |
| 57 final _collapsibleMessages = []; | |
| 58 | |
| 51 final _cyan = getSpecial('\u001b[36m'); | 59 final _cyan = getSpecial('\u001b[36m'); |
| 52 final _green = getSpecial('\u001b[32m'); | 60 final _green = getSpecial('\u001b[32m'); |
| 53 final _magenta = getSpecial('\u001b[35m'); | 61 final _magenta = getSpecial('\u001b[35m'); |
| 54 final _red = getSpecial('\u001b[31m'); | 62 final _red = getSpecial('\u001b[31m'); |
| 55 final _yellow = getSpecial('\u001b[33m'); | 63 final _yellow = getSpecial('\u001b[33m'); |
| 56 final _gray = getSpecial('\u001b[1;30m'); | 64 final _gray = getSpecial('\u001b[1;30m'); |
| 57 final _none = getSpecial('\u001b[0m'); | 65 final _none = getSpecial('\u001b[0m'); |
| 58 final _noColor = getSpecial('\u001b[39m'); | 66 final _noColor = getSpecial('\u001b[39m'); |
| 59 final _bold = getSpecial('\u001b[1m'); | 67 final _bold = getSpecial('\u001b[1m'); |
| 60 | 68 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 void io(message) => write(Level.IO, message); | 210 void io(message) => write(Level.IO, message); |
| 203 | 211 |
| 204 /// Logs [message] at [Level.SOLVER]. | 212 /// Logs [message] at [Level.SOLVER]. |
| 205 void solver(message) => write(Level.SOLVER, message); | 213 void solver(message) => write(Level.SOLVER, message); |
| 206 | 214 |
| 207 /// Logs [message] at [Level.FINE]. | 215 /// Logs [message] at [Level.FINE]. |
| 208 void fine(message) => write(Level.FINE, message); | 216 void fine(message) => write(Level.FINE, message); |
| 209 | 217 |
| 210 /// Logs [message] at [level]. | 218 /// Logs [message] at [level]. |
| 211 void write(Level level, message) { | 219 void write(Level level, message) { |
| 220 // Don't allow interleaving collapsible messages with other kinds. | |
| 221 if (_collapsibleTimer != null) _flushCollapsible(); | |
| 222 | |
| 212 message = message.toString(); | 223 message = message.toString(); |
| 213 var lines = splitLines(message); | 224 var lines = splitLines(message); |
| 214 | 225 |
| 215 // Discard a trailing newline. This is useful since StringBuffers often end | 226 // Discard a trailing newline. This is useful since StringBuffers often end |
| 216 // up with an extra newline at the end from using [writeln]. | 227 // up with an extra newline at the end from using [writeln]. |
| 217 if (lines.isNotEmpty && lines.last == "") { | 228 if (lines.isNotEmpty && lines.last == "") { |
| 218 lines.removeLast(); | 229 lines.removeLast(); |
| 219 } | 230 } |
| 220 | 231 |
| 221 var entry = new Entry(level, lines.map(format).toList()); | 232 var entry = new Entry(level, lines.map(format).toList()); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 _numMutes++; | 413 _numMutes++; |
| 403 } | 414 } |
| 404 | 415 |
| 405 /// Resumes animating any ongoing progress once all calls to [muteProgress] | 416 /// Resumes animating any ongoing progress once all calls to [muteProgress] |
| 406 /// have made their matching [unmuteProgress]. | 417 /// have made their matching [unmuteProgress]. |
| 407 void unmuteProgress() { | 418 void unmuteProgress() { |
| 408 assert(_numMutes > 0); | 419 assert(_numMutes > 0); |
| 409 _numMutes--; | 420 _numMutes--; |
| 410 } | 421 } |
| 411 | 422 |
| 423 /// Logs a collapsible [message]. | |
| 424 /// | |
| 425 /// If a number of collapsible messages are printed in short succession, they | |
| 426 /// are collapsed to just showing the first one followed by a count of the | |
| 427 /// elided ones. Avoids spamming the output with not-very-interesting output. | |
| 428 /// | |
| 429 /// Internally, every time this is called, a time is set (or reset). When it | |
| 430 /// fires, any collapsible messages enqueued since the last time it fired are | |
| 431 /// displayed. | |
| 432 void collapsible(String message) { | |
|
nweiz
2015/07/31 22:42:35
Rather than only printing this once the timeout ha
Bob Nystrom
2015/08/03 21:51:02
I thought about that, but the output lines can be
nweiz
2015/08/03 22:11:10
Since this is pub, we should be able to safely use
Bob Nystrom
2015/08/05 21:25:39
Tried a different approach based on our discussion
| |
| 433 // Only collapse messages when the output is not verbose. | |
| 434 if (verbosity._loggers[Level.MESSAGE] != _logToStdout) { | |
| 435 write(Level.MESSAGE, message); | |
| 436 return; | |
| 437 } | |
| 438 | |
| 439 // Reset the timer. | |
| 440 if (_collapsibleTimer != null) _collapsibleTimer.cancel(); | |
| 441 | |
| 442 _collapsibleMessages.add(message); | |
| 443 _collapsibleTimer = new Timer(new Duration(milliseconds: 100), | |
|
nweiz
2015/07/31 22:42:35
Consider making this duration a top-level constant
Bob Nystrom
2015/08/03 21:51:02
Done.
| |
| 444 _flushCollapsible); | |
| 445 } | |
| 446 | |
| 447 /// Displays any queued collapsible messages. | |
| 448 void _flushCollapsible() { | |
| 449 if (_collapsibleMessages.isEmpty) return; | |
| 450 | |
| 451 if (_collapsibleTimer != null) { | |
| 452 _collapsibleTimer.cancel(); | |
| 453 _collapsibleTimer = null; | |
| 454 } | |
| 455 | |
| 456 if (_collapsibleMessages.length == 1) { | |
| 457 message(_collapsibleMessages.single); | |
| 458 } else { | |
| 459 var trailing = gray("(and ${_collapsibleMessages.length - 1} more...)"); | |
| 460 message("${_collapsibleMessages.first} $trailing"); | |
| 461 } | |
| 462 | |
| 463 _collapsibleMessages.clear(); | |
| 464 } | |
| 465 | |
| 412 /// Wraps [text] in the ANSI escape codes to make it bold when on a platform | 466 /// Wraps [text] in the ANSI escape codes to make it bold when on a platform |
| 413 /// that supports that. | 467 /// that supports that. |
| 414 /// | 468 /// |
| 415 /// Use this to highlight the most important piece of a long chunk of text. | 469 /// Use this to highlight the most important piece of a long chunk of text. |
| 416 /// | 470 /// |
| 417 /// This is disabled under [withPrejudice] since all text is bold with | 471 /// This is disabled under [withPrejudice] since all text is bold with |
| 418 /// prejudice. | 472 /// prejudice. |
| 419 String bold(text) => withPrejudice ? text : "$_bold$text$_none"; | 473 String bold(text) => withPrejudice ? text : "$_bold$text$_none"; |
| 420 | 474 |
| 421 /// Wraps [text] in the ANSI escape codes to make it gray when on a platform | 475 /// Wraps [text] in the ANSI escape codes to make it gray when on a platform |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 this.message(errorJson); | 592 this.message(errorJson); |
| 539 } | 593 } |
| 540 | 594 |
| 541 /// Encodes [message] to JSON and prints it if JSON output is enabled. | 595 /// Encodes [message] to JSON and prints it if JSON output is enabled. |
| 542 void message(message) { | 596 void message(message) { |
| 543 if (!enabled) return; | 597 if (!enabled) return; |
| 544 | 598 |
| 545 print(JSON.encode(message)); | 599 print(JSON.encode(message)); |
| 546 } | 600 } |
| 547 } | 601 } |
| OLD | NEW |