diff --git a/CHANGELOG.md b/CHANGELOG.md index 55372921..3dcc731d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.22.8 - Updated dependency: `tar: ^2.0.0`. +- New text logging format. ## 0.22.7 diff --git a/bin/pana.dart b/bin/pana.dart index c7c192e7..fc706591 100755 --- a/bin/pana.dart +++ b/bin/pana.dart @@ -13,6 +13,7 @@ import 'package:io/ansi.dart'; import 'package:io/io.dart'; import 'package:logging/logging.dart' as log; import 'package:pana/pana.dart'; +import 'package:pana/src/logging.dart'; import 'package:path/path.dart' as p; const defaultHostedUrl = 'https://pub.dev'; @@ -132,32 +133,7 @@ Future main(List args) async { } log.Logger.root.level = log.Level.ALL; - - if (isJson) { - log.Logger.root.onRecord.listen((log) { - var map = {}; - - if (log.loggerName.isNotEmpty) { - map['logName'] = log.loggerName; - } - - map.addAll({ - 'level': log.level.name, - 'message': log.message, - }); - - if (log.error != null) { - map['error'] = log.error.toString(); - } - - if (log.stackTrace != null) { - map['stackTrace'] = log.stackTrace.toString(); - } - stderr.writeln(json.encode(map)); - }); - } else { - log.Logger.root.onRecord.listen(_logWriter); - } + initializePanaLogging(isJson: isJson); // Docker is WEIRD // The SIGTERM signal sent to `docker run...` DOES propagate a signal to the @@ -285,28 +261,6 @@ Future main(List args) async { await subscription.cancel(); } -void _logWriter(log.LogRecord record) { - var wroteHeader = false; - - var msg = LineSplitter.split([record.message, record.error, record.stackTrace] - .where((e) => e != null) - .join('\n')) - .map((l) { - String prefix; - if (wroteHeader) { - prefix = ''; - } else { - wroteHeader = true; - prefix = record.level.toString(); - } - return '${prefix.padRight(10)} $l'; - }).join('\n'); - - overrideAnsiOutput(stderr.supportsAnsiEscapes, () { - stderr.writeln(darkGray.wrap(msg)); - }); -} - /// A merged stream of all signals that tell the test runner to shut down /// gracefully. /// diff --git a/lib/src/logging.dart b/lib/src/logging.dart index 3300ac83..f1f5344f 100644 --- a/lib/src/logging.dart +++ b/lib/src/logging.dart @@ -3,7 +3,10 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'package:io/ansi.dart'; import 'package:logging/logging.dart'; final Logger _log = Logger('pana'); @@ -16,3 +19,50 @@ Future withLogger(Future Function() fn, {Logger? logger}) => runZoned( ); Logger get log => (Zone.current[_key] as Logger?) ?? _log; + +void initializePanaLogging({bool isJson = false}) { + if (isJson) { + Logger.root.onRecord.listen((log) { + final map = { + if (log.loggerName.isNotEmpty) 'logName': log.loggerName, + 'level': log.level.name, + 'message': log.message, + if (log.error != null) 'error': log.error.toString(), + if (log.stackTrace != null) 'stackTrace': log.stackTrace.toString(), + }; + + stderr.writeln(json.encode(map)); + }); + } else { + Logger.root.onRecord.listen(_logWriter); + } +} + +void _logWriter(LogRecord record) { + var wroteHeader = false; + + final output = []; + final prefix = '${record.time} ${record.level.name}:'; + final emptyPrefix = ' ' * prefix.length; + void printLinesWithPrefix(String lines) { + for (final line in lines.split('\n')) { + final currentPrefix = wroteHeader ? emptyPrefix : prefix; + output.add('$currentPrefix $line'); + wroteHeader = true; + } + } + + printLinesWithPrefix(record.message); + final e = record.error; + if (e != null) { + printLinesWithPrefix(e.toString()); + final st = record.stackTrace; + if (st != null) { + printLinesWithPrefix(st.toString()); + } + } + + overrideAnsiOutput(stderr.supportsAnsiEscapes, () { + stderr.writeln(darkGray.wrap(output.join('\n'))); + }); +}