Index: sdk/lib/_internal/pub/lib/src/log.dart |
diff --git a/sdk/lib/_internal/pub/lib/src/log.dart b/sdk/lib/_internal/pub/lib/src/log.dart |
index fd1166d99644e29795f0301e41fbcf2c3e532e8b..07a1195c39a46100ff886e0ea0f0c88ce48554e0 100644 |
--- a/sdk/lib/_internal/pub/lib/src/log.dart |
+++ b/sdk/lib/_internal/pub/lib/src/log.dart |
@@ -6,14 +6,21 @@ |
library pub.log; |
import 'dart:async'; |
+import 'dart:convert'; |
import 'dart:io'; |
import 'package:path/path.dart' as p; |
+import 'package:stack_trace/stack_trace.dart'; |
import 'io.dart'; |
import 'transcript.dart'; |
import 'utils.dart'; |
+/// The singleton instance so that we can have a nice api like: |
+/// |
+/// log.json.error(...); |
+final json = new _JsonLogger(); |
+ |
typedef LogFn(Entry entry); |
final Map<Level, LogFn> _loggers = new Map<Level, LogFn>(); |
@@ -209,7 +216,9 @@ void dumpTranscript() { |
if (_transcript == null) return; |
stderr.writeln('---- Log transcript ----'); |
- _transcript.forEach(_logToStderrWithLabel, (discarded) { |
+ _transcript.forEach((entry) { |
+ _printToStream(stderr, entry, showLabel: true); |
+ }, (discarded) { |
stderr.writeln('---- ($discarded discarded) ----'); |
}); |
stderr.writeln('---- End log transcript ----'); |
@@ -219,6 +228,8 @@ void dumpTranscript() { |
/// future returned by [callback] completes. If anything else is logged during |
/// this, it cancels the progress. |
Future progress(String message, Future callback()) { |
+ if (json.enabled) return callback(); |
+ |
if (_progressTimer != null) throw new StateError("Already in progress."); |
_progressMessage = '$message...'; |
@@ -356,6 +367,12 @@ void _logToStderrWithLabel(Entry entry) { |
} |
void _logToStream(IOSink sink, Entry entry, {bool showLabel}) { |
+ if (json.enabled) return; |
+ |
+ _printToStream(sink, entry, showLabel: showLabel); |
+} |
+ |
+void _printToStream(IOSink sink, Entry entry, {bool showLabel}) { |
_stopProgress(); |
bool firstLine = true; |
@@ -373,3 +390,35 @@ void _logToStream(IOSink sink, Entry entry, {bool showLabel}) { |
firstLine = false; |
} |
} |
+ |
+/// Namespace-like class for collecting the methods for JSON logging. |
+class _JsonLogger { |
+ /// Whether logging should use machine-friendly JSON output or human-friendly |
+ /// text. |
+ /// |
+ /// If set to `true`, then no regular logging is printed. Logged messages |
+ /// will still be recorded and displayed if the transcript is printed. |
+ bool enabled = false; |
+ |
+ /// Creates an error JSON object for [error] and prints it if JSON output |
+ /// is enabled. |
+ /// |
+ /// Always prints to stdout. |
+ void error(error, [stackTrace]) { |
+ var errorJson = {"error": error.toString()}; |
+ |
+ if (stackTrace == null && error is Error) stackTrace = error.stackTrace; |
+ if (stackTrace != null) { |
+ errorJson["stackTrace"] = new Chain.forTrace(stackTrace).toString(); |
+ } |
+ |
+ this.message(errorJson); |
+ } |
+ |
+ /// Encodes [message] to JSON and prints it if JSON output is enabled. |
+ void message(message) { |
+ if (!enabled) return; |
+ |
+ print(JSON.encode(message)); |
+ } |
+} |