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:io'; | 10 import 'dart:io'; |
| 10 | 11 |
| 11 import 'package:path/path.dart' as p; | 12 import 'package:path/path.dart' as p; |
| 12 | 13 |
| 13 import 'io.dart'; | 14 import 'io.dart'; |
| 14 import 'transcript.dart'; | 15 import 'transcript.dart'; |
| 15 import 'utils.dart'; | 16 import 'utils.dart'; |
| 16 | 17 |
| 17 typedef LogFn(Entry entry); | 18 typedef LogFn(Entry entry); |
| 18 final Map<Level, LogFn> _loggers = new Map<Level, LogFn>(); | 19 final Map<Level, LogFn> _loggers = new Map<Level, LogFn>(); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 void recordTranscript() { | 203 void recordTranscript() { |
| 203 _transcript = new Transcript<Entry>(_MAX_TRANSCRIPT); | 204 _transcript = new Transcript<Entry>(_MAX_TRANSCRIPT); |
| 204 } | 205 } |
| 205 | 206 |
| 206 /// If [recordTranscript()] was called, then prints the previously recorded log | 207 /// If [recordTranscript()] was called, then prints the previously recorded log |
| 207 /// transcript to stderr. | 208 /// transcript to stderr. |
| 208 void dumpTranscript() { | 209 void dumpTranscript() { |
| 209 if (_transcript == null) return; | 210 if (_transcript == null) return; |
| 210 | 211 |
| 211 stderr.writeln('---- Log transcript ----'); | 212 stderr.writeln('---- Log transcript ----'); |
| 212 _transcript.forEach(_logToStderrWithLabel, (discarded) { | 213 _transcript.forEach((entry) { |
| 214 _printToStream(stderr, entry, showLabel: true); | |
|
nweiz
2014/03/05 02:36:52
If you're keeping _logToStderrWithLabel, I don't u
Bob Nystrom
2014/03/07 00:42:18
Calling _printToStream() directly skips the if (js
| |
| 215 }, (discarded) { | |
| 213 stderr.writeln('---- ($discarded discarded) ----'); | 216 stderr.writeln('---- ($discarded discarded) ----'); |
| 214 }); | 217 }); |
| 215 stderr.writeln('---- End log transcript ----'); | 218 stderr.writeln('---- End log transcript ----'); |
| 216 } | 219 } |
| 217 | 220 |
| 218 /// Prints [message] then slowly prints additional "..." after it until the | 221 /// Prints [message] then slowly prints additional "..." after it until the |
| 219 /// future returned by [callback] completes. If anything else is logged during | 222 /// future returned by [callback] completes. If anything else is logged during |
| 220 /// this, it cancels the progress. | 223 /// this, it cancels the progress. |
| 221 Future progress(String message, Future callback()) { | 224 Future progress(String message, Future callback()) { |
| 225 if (json.enabled) return callback(); | |
| 226 | |
| 222 if (_progressTimer != null) throw new StateError("Already in progress."); | 227 if (_progressTimer != null) throw new StateError("Already in progress."); |
| 223 | 228 |
| 224 _progressMessage = '$message...'; | 229 _progressMessage = '$message...'; |
| 225 stdout.write(_progressMessage); | 230 stdout.write(_progressMessage); |
| 226 | 231 |
| 227 _progressTimer = new Timer.periodic(new Duration(milliseconds: 500), (_) { | 232 _progressTimer = new Timer.periodic(new Duration(milliseconds: 500), (_) { |
| 228 stdout.write('.'); | 233 stdout.write('.'); |
| 229 _progressMessage += '.'; | 234 _progressMessage += '.'; |
| 230 }); | 235 }); |
| 231 | 236 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 void _logToStderr(Entry entry) { | 354 void _logToStderr(Entry entry) { |
| 350 _logToStream(stderr, entry, showLabel: false); | 355 _logToStream(stderr, entry, showLabel: false); |
| 351 } | 356 } |
| 352 | 357 |
| 353 /// Log function that prints the message to stderr with the level name. | 358 /// Log function that prints the message to stderr with the level name. |
| 354 void _logToStderrWithLabel(Entry entry) { | 359 void _logToStderrWithLabel(Entry entry) { |
| 355 _logToStream(stderr, entry, showLabel: true); | 360 _logToStream(stderr, entry, showLabel: true); |
| 356 } | 361 } |
| 357 | 362 |
| 358 void _logToStream(IOSink sink, Entry entry, {bool showLabel}) { | 363 void _logToStream(IOSink sink, Entry entry, {bool showLabel}) { |
| 364 if (json.enabled) return; | |
| 365 | |
| 366 _printToStream(sink, entry, showLabel: showLabel); | |
| 367 } | |
| 368 | |
| 369 void _printToStream(IOSink sink, Entry entry, {bool showLabel}) { | |
| 359 _stopProgress(); | 370 _stopProgress(); |
| 360 | 371 |
| 361 bool firstLine = true; | 372 bool firstLine = true; |
| 362 for (var line in entry.lines) { | 373 for (var line in entry.lines) { |
| 363 if (showLabel) { | 374 if (showLabel) { |
| 364 if (firstLine) { | 375 if (firstLine) { |
| 365 sink.write('${entry.level.name}: '); | 376 sink.write('${entry.level.name}: '); |
| 366 } else { | 377 } else { |
| 367 sink.write(' | '); | 378 sink.write(' | '); |
| 368 } | 379 } |
| 369 } | 380 } |
| 370 | 381 |
| 371 sink.writeln(line); | 382 sink.writeln(line); |
| 372 | 383 |
| 373 firstLine = false; | 384 firstLine = false; |
| 374 } | 385 } |
| 375 } | 386 } |
| 387 | |
| 388 /// Namespace-like class for collecting the methods for JSON logging. | |
| 389 class _JsonLogger { | |
| 390 /// Whether logging should use machine-friendl JSON output or human-friendly | |
|
nweiz
2014/03/05 02:36:52
"friendl" -> "friendly"
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| 391 /// text. | |
| 392 /// | |
| 393 /// If set to `true`, then all regular logging is not printed. Logged | |
|
nweiz
2014/03/05 02:36:52
"no regular logging is printed"
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| 394 /// messages will still be recorded and displayed if the transcript is | |
| 395 /// printed. | |
| 396 bool enabled = false; | |
| 397 | |
| 398 /// Creates an error JSON object for [error] and prints it if JSON output | |
| 399 /// is enabled. | |
|
nweiz
2014/03/05 02:36:52
Mention that this prints to stdout as opposed to s
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| 400 void error(error) { | |
|
nweiz
2014/03/05 02:36:52
This should take an optional StackTrace as well.
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| 401 var errorJson = {"error": error.toString()}; | |
| 402 | |
| 403 var trace; | |
| 404 if (error is Error) trace = error.stackTrace; | |
| 405 if (trace != null) { | |
| 406 errorJson["stackTrace"] = trace; | |
|
nweiz
2014/03/05 02:36:52
We should [new Chain.forTrace] this.
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| 407 } | |
| 408 | |
| 409 this.message(errorJson); | |
| 410 } | |
| 411 | |
| 412 /// Encodes [message] to JSON and prints it if JSON output is enabled. | |
| 413 void message(message) { | |
| 414 if (!enabled) return; | |
| 415 | |
| 416 // TODO(rnystrom): Should errors be printed to stderr? | |
|
nweiz
2014/03/05 02:36:52
I think stdout is fine. Since the errors have iden
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| 417 print(JSON.encode(message)); | |
| 418 } | |
| 419 } | |
| 420 | |
| 421 /// The singleton instance so that we can have a nice api like: | |
| 422 /// | |
| 423 /// log.json.error(...); | |
| 424 final json = new _JsonLogger(); | |
|
nweiz
2014/03/05 02:36:52
Nit: I'd expect this to be at the top of the file,
Bob Nystrom
2014/03/07 00:42:18
Done.
| |
| OLD | NEW |