From 8e8bd91ba9cf26acd6fd27040823f7d1bc42c546 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Sun, 3 Mar 2024 23:41:17 +0100 Subject: [PATCH 01/18] Changed `File file` to `String path` --- lib/src/outputs/file_output.dart | 17 +++++++++++++---- lib/src/outputs/file_output_stub.dart | 10 +++++++++- test/outputs/file_output_test.dart | 25 ++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/lib/src/outputs/file_output.dart b/lib/src/outputs/file_output.dart index a5bb5e5..eb4a1c5 100644 --- a/lib/src/outputs/file_output.dart +++ b/lib/src/outputs/file_output.dart @@ -1,25 +1,34 @@ import 'dart:convert'; import 'dart:io'; +import 'package:meta/meta.dart'; + import '../log_output.dart'; import '../output_event.dart'; /// Writes the log output to a file. class FileOutput extends LogOutput { - final File file; + late final File _file; final bool overrideExisting; final Encoding encoding; IOSink? _sink; FileOutput({ - required this.file, + required String path, this.overrideExisting = false, this.encoding = utf8, - }); + }) { + _file = createFile(path); + } + + @protected + File createFile(String path) { + return File(path); + } @override Future init() async { - _sink = file.openWrite( + _sink = _file.openWrite( mode: overrideExisting ? FileMode.writeOnly : FileMode.writeOnlyAppend, encoding: encoding, ); diff --git a/lib/src/outputs/file_output_stub.dart b/lib/src/outputs/file_output_stub.dart index c992a22..868afe5 100644 --- a/lib/src/outputs/file_output_stub.dart +++ b/lib/src/outputs/file_output_stub.dart @@ -1,18 +1,26 @@ import 'dart:convert'; import 'dart:io'; +import 'package:meta/meta.dart'; + import '../log_output.dart'; import '../output_event.dart'; +/// Writes the log output to a file. class FileOutput extends LogOutput { FileOutput({ - required File file, + required String path, bool overrideExisting = false, Encoding encoding = utf8, }) { throw UnsupportedError("Not supported on this platform."); } + @protected + File createFile(String path) { + throw UnsupportedError("Not supported on this platform."); + } + @override void output(OutputEvent event) { throw UnsupportedError("Not supported on this platform."); diff --git a/test/outputs/file_output_test.dart b/test/outputs/file_output_test.dart index 02ebb32..810ff50 100644 --- a/test/outputs/file_output_test.dart +++ b/test/outputs/file_output_test.dart @@ -1,20 +1,39 @@ +import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:logger/logger.dart'; import 'package:test/test.dart'; var memory = MemoryFileSystem(); +class MemoryFileOutput extends FileOutput { + MemoryFileOutput({ + required super.path, + super.encoding, + super.overrideExisting, + }); + + late File _file; + + get file => _file; + + @override + File createFile(String path) { + return _file = memory.file(path); + } +} + void main() { - final file = memory.file("dart_logger_test.log"); + final fileName = "dart_logger_test.log"; tearDown(() { + var file = memory.file(fileName); if (file.existsSync()) { file.deleteSync(); } }); test('Real file read and write', () async { - var output = FileOutput(file: file); + var output = MemoryFileOutput(path: fileName); await output.init(); final event0 = OutputEvent(LogEvent(Level.info, ""), ["First event"]); @@ -27,7 +46,7 @@ void main() { await output.destroy(); - var content = await file.readAsString(); + var content = await output.file.readAsString(); expect( content, allOf( From a6e4a98175f13a175972f9172f4cf0680545354c Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 00:45:36 +0200 Subject: [PATCH 02/18] Removed obsolete web safe export --- lib/logger.dart | 25 ++++++++++++++++++++++--- lib/web.dart | 23 ----------------------- 2 files changed, 22 insertions(+), 26 deletions(-) delete mode 100644 lib/web.dart diff --git a/lib/logger.dart b/lib/logger.dart index 7571068..71782de 100644 --- a/lib/logger.dart +++ b/lib/logger.dart @@ -1,8 +1,27 @@ /// Small, easy to use and extensible logger which prints beautiful logs. library logger; -export 'src/outputs/file_output_stub.dart' - if (dart.library.io) 'src/outputs/file_output.dart'; +export 'src/ansi_color.dart'; +export 'src/date_time_format.dart'; +export 'src/filters/development_filter.dart'; +export 'src/filters/production_filter.dart'; +export 'src/log_event.dart'; +export 'src/log_filter.dart'; +export 'src/log_level.dart'; +export 'src/log_output.dart'; +export 'src/log_printer.dart'; +export 'src/logger.dart'; +export 'src/output_event.dart'; export 'src/outputs/advanced_file_output_stub.dart' if (dart.library.io) 'src/outputs/advanced_file_output.dart'; -export 'web.dart'; +export 'src/outputs/console_output.dart'; +export 'src/outputs/file_output_stub.dart' + if (dart.library.io) 'src/outputs/file_output.dart'; +export 'src/outputs/memory_output.dart'; +export 'src/outputs/multi_output.dart'; +export 'src/outputs/stream_output.dart'; +export 'src/printers/hybrid_printer.dart'; +export 'src/printers/logfmt_printer.dart'; +export 'src/printers/prefix_printer.dart'; +export 'src/printers/pretty_printer.dart'; +export 'src/printers/simple_printer.dart'; diff --git a/lib/web.dart b/lib/web.dart deleted file mode 100644 index 10cc405..0000000 --- a/lib/web.dart +++ /dev/null @@ -1,23 +0,0 @@ -/// Web-safe logger. -library web; - -export 'src/ansi_color.dart'; -export 'src/date_time_format.dart'; -export 'src/filters/development_filter.dart'; -export 'src/filters/production_filter.dart'; -export 'src/log_event.dart'; -export 'src/log_filter.dart'; -export 'src/log_level.dart'; -export 'src/log_output.dart'; -export 'src/log_printer.dart'; -export 'src/logger.dart'; -export 'src/output_event.dart'; -export 'src/outputs/console_output.dart'; -export 'src/outputs/memory_output.dart'; -export 'src/outputs/multi_output.dart'; -export 'src/outputs/stream_output.dart'; -export 'src/printers/hybrid_printer.dart'; -export 'src/printers/logfmt_printer.dart'; -export 'src/printers/prefix_printer.dart'; -export 'src/printers/pretty_printer.dart'; -export 'src/printers/simple_printer.dart'; From 3d5d00f4dafb58064bea57f85af4f41aed3712f8 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 00:48:13 +0200 Subject: [PATCH 03/18] Changed message type from `dynamic` to `Object?` --- lib/src/log_event.dart | 2 +- lib/src/logger.dart | 18 +++++++++--------- lib/src/printers/logfmt_printer.dart | 12 +++++++----- lib/src/printers/pretty_printer.dart | 2 +- lib/src/printers/simple_printer.dart | 2 +- test/logger_test.dart | 6 +++--- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/src/log_event.dart b/lib/src/log_event.dart index 38067d0..b27368f 100644 --- a/lib/src/log_event.dart +++ b/lib/src/log_event.dart @@ -2,7 +2,7 @@ import 'log_level.dart'; class LogEvent { final Level level; - final dynamic message; + final Object? message; final Object? error; final StackTrace? stackTrace; diff --git a/lib/src/logger.dart b/lib/src/logger.dart index bcfc0b3..4719573 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -71,7 +71,7 @@ class Logger { @Deprecated( "[Level.verbose] is being deprecated in favor of [Level.trace], use [t] instead.") void v( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -81,7 +81,7 @@ class Logger { /// Log a message at level [Level.trace]. void t( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -91,7 +91,7 @@ class Logger { /// Log a message at level [Level.debug]. void d( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -101,7 +101,7 @@ class Logger { /// Log a message at level [Level.info]. void i( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -111,7 +111,7 @@ class Logger { /// Log a message at level [Level.warning]. void w( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -122,7 +122,7 @@ class Logger { /// Log a message at level [Level.error]. void e( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -134,7 +134,7 @@ class Logger { @Deprecated( "[Level.wtf] is being deprecated in favor of [Level.fatal], use [f] instead.") void wtf( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -144,7 +144,7 @@ class Logger { /// Log a message at level [Level.fatal]. void f( - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, @@ -155,7 +155,7 @@ class Logger { /// Log a message with [level]. void log( Level level, - dynamic message, { + Object? message, { DateTime? time, Object? error, StackTrace? stackTrace, diff --git a/lib/src/printers/logfmt_printer.dart b/lib/src/printers/logfmt_printer.dart index de21b6a..5763196 100644 --- a/lib/src/printers/logfmt_printer.dart +++ b/lib/src/printers/logfmt_printer.dart @@ -19,16 +19,18 @@ class LogfmtPrinter extends LogPrinter { @override List log(LogEvent event) { var output = StringBuffer('level=${levelPrefixes[event.level]}'); - if (event.message is String) { - output.write(' msg="${event.message}"'); - } else if (event.message is Map) { - event.message.entries.forEach((entry) { + var message = event.message; + + if (message is String) { + output.write(' msg="$message"'); + } else if (message is Map) { + for (var entry in message.entries) { if (entry.value is num) { output.write(' ${entry.key}=${entry.value}'); } else { output.write(' ${entry.key}="${entry.value}"'); } - }); + } } if (event.error != null) { output.write(' error="${event.error}"'); diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart index 7bee727..a2eee90 100644 --- a/lib/src/printers/pretty_printer.dart +++ b/lib/src/printers/pretty_printer.dart @@ -358,7 +358,7 @@ class PrettyPrinter extends LogPrinter { return object.toString(); } - String stringifyMessage(dynamic message) { + String stringifyMessage(Object? message) { final finalMessage = message is Function ? message() : message; if (finalMessage is Map || finalMessage is Iterable) { var encoder = JsonEncoder.withIndent(' ', toEncodableFallback); diff --git a/lib/src/printers/simple_printer.dart b/lib/src/printers/simple_printer.dart index d56fe4d..b186e56 100644 --- a/lib/src/printers/simple_printer.dart +++ b/lib/src/printers/simple_printer.dart @@ -48,7 +48,7 @@ class SimplePrinter extends LogPrinter { return colors ? color(prefix) : prefix; } - String _stringifyMessage(dynamic message) { + String _stringifyMessage(Object? message) { final finalMessage = message is Function ? message() : message; if (finalMessage is Map || finalMessage is Iterable) { var encoder = const JsonEncoder.withIndent(null); diff --git a/test/logger_test.dart b/test/logger_test.dart index f2d5768..3fa002f 100644 --- a/test/logger_test.dart +++ b/test/logger_test.dart @@ -5,7 +5,7 @@ import 'package:test/test.dart'; typedef PrinterCallback = List Function( Level level, - dynamic message, + Object? message, Object? error, StackTrace? stackTrace, ); @@ -99,8 +99,8 @@ class LazyLogger { void main() { Level? printedLevel; - dynamic printedMessage; - dynamic printedError; + Object? printedMessage; + Object? printedError; StackTrace? printedStackTrace; var callbackPrinter = _CallbackPrinter((l, m, e, s) { printedLevel = l; From 9e955953de8fe2579f52fb330a1db8338529571c Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 01:01:51 +0200 Subject: [PATCH 04/18] Globally allow functions as message --- lib/src/log_event.dart | 16 ++++++++++++++++ lib/src/logger.dart | 3 +++ lib/src/printers/pretty_printer.dart | 7 +++---- lib/src/printers/simple_printer.dart | 7 +++---- test/logger_test.dart | 8 ++++++++ test/printers/pretty_printer_test.dart | 19 ------------------- test/printers/simple_printer_test.dart | 15 --------------- 7 files changed, 33 insertions(+), 42 deletions(-) diff --git a/lib/src/log_event.dart b/lib/src/log_event.dart index b27368f..f4f0847 100644 --- a/lib/src/log_event.dart +++ b/lib/src/log_event.dart @@ -16,4 +16,20 @@ class LogEvent { this.error, this.stackTrace, }) : time = time ?? DateTime.now(); + + LogEvent copyWith({ + Level? level, + Object? message, + DateTime? time, + Object? error, + StackTrace? stackTrace, + }) { + return LogEvent( + level ?? this.level, + message ?? this.message, + time: time ?? this.time, + error: error ?? this.error, + stackTrace: stackTrace ?? this.stackTrace, + ); + } } diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 4719573..1167d52 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -183,6 +183,9 @@ class Logger { } if (_filter.shouldLog(logEvent)) { + if (message is Function) { + logEvent = logEvent.copyWith(message: message()); + } var output = _printer.log(logEvent); if (output.isNotEmpty) { diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart index a2eee90..5faabea 100644 --- a/lib/src/printers/pretty_printer.dart +++ b/lib/src/printers/pretty_printer.dart @@ -359,12 +359,11 @@ class PrettyPrinter extends LogPrinter { } String stringifyMessage(Object? message) { - final finalMessage = message is Function ? message() : message; - if (finalMessage is Map || finalMessage is Iterable) { + if (message is Map || message is Iterable) { var encoder = JsonEncoder.withIndent(' ', toEncodableFallback); - return encoder.convert(finalMessage); + return encoder.convert(message); } else { - return finalMessage.toString(); + return message.toString(); } } diff --git a/lib/src/printers/simple_printer.dart b/lib/src/printers/simple_printer.dart index b186e56..7d7f8d8 100644 --- a/lib/src/printers/simple_printer.dart +++ b/lib/src/printers/simple_printer.dart @@ -49,12 +49,11 @@ class SimplePrinter extends LogPrinter { } String _stringifyMessage(Object? message) { - final finalMessage = message is Function ? message() : message; - if (finalMessage is Map || finalMessage is Iterable) { + if (message is Map || message is Iterable) { var encoder = const JsonEncoder.withIndent(null); - return encoder.convert(finalMessage); + return encoder.convert(message); } else { - return finalMessage.toString(); + return message.toString(); } } } diff --git a/test/logger_test.dart b/test/logger_test.dart index 3fa002f..cc620d9 100644 --- a/test/logger_test.dart +++ b/test/logger_test.dart @@ -240,6 +240,14 @@ void main() { expect(printedStackTrace, stackTrace); }); + test('Deal with function messages', () { + final heavyComputation = 'heavily computed very pretty Message'; + + var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + logger.f(() => heavyComputation); + expect(printedMessage, heavyComputation); + }); + test('setting log level above log level of message', () { printedMessage = null; var logger = Logger( diff --git a/test/printers/pretty_printer_test.dart b/test/printers/pretty_printer_test.dart index b0eaad8..b09a323 100644 --- a/test/printers/pretty_printer_test.dart +++ b/test/printers/pretty_printer_test.dart @@ -156,25 +156,6 @@ void main() { } }); - test('deal with Function type message', () { - final prettyPrinter = PrettyPrinter(); - final expectedMessage = 'heavily computed very pretty Message'; - final withFunction = LogEvent( - Level.debug, - () => expectedMessage, - error: 'some error', - stackTrace: StackTrace.current, - ); - - final actualLog = prettyPrinter.log(withFunction); - final actualLogString = readMessage(actualLog); - - expect( - actualLogString, - contains(expectedMessage), - ); - }); - test('stackTraceBeginIndex', () { final prettyPrinter = PrettyPrinter( stackTraceBeginIndex: 2, diff --git a/test/printers/simple_printer_test.dart b/test/printers/simple_printer_test.dart index 5b1c173..f3376f2 100644 --- a/test/printers/simple_printer_test.dart +++ b/test/printers/simple_printer_test.dart @@ -87,19 +87,4 @@ void main() { '[D] [1,2,3,4] ERROR: some error', ); }); - - test('deal with Function type message', () { - var expectedMessage = 'heavily computed Message'; - var withFunction = LogEvent( - Level.debug, - () => expectedMessage, - error: 'some error', - stackTrace: StackTrace.current, - ); - - expect( - plainPrinter.log(withFunction)[0], - '[D] $expectedMessage ERROR: some error', - ); - }); } From 18f3f189b576e8a62063d9fde73b07af73ab9c37 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 01:18:24 +0200 Subject: [PATCH 05/18] Pulled `stringifyMessage` up to LogPrinter --- lib/src/log_printer.dart | 17 +++++++++++++++++ lib/src/printers/pretty_printer.dart | 15 --------------- lib/src/printers/simple_printer.dart | 13 +++++-------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/src/log_printer.dart b/lib/src/log_printer.dart index 6b4bf10..893ad9e 100644 --- a/lib/src/log_printer.dart +++ b/lib/src/log_printer.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'log_event.dart'; /// An abstract handler of log events. @@ -15,4 +17,19 @@ abstract class LogPrinter { List log(LogEvent event); Future destroy() async {} + + String stringifyMessage(Object? message) { + if (message is String) return message; + + if (message is Map || message is Iterable) { + return encodeJson(message); + } else { + return message.toString(); + } + } + + String encodeJson(Object? message) { + var encoder = JsonEncoder.withIndent(' ', (object) => object.toString()); + return encoder.convert(message); + } } diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart index 5faabea..167c64d 100644 --- a/lib/src/printers/pretty_printer.dart +++ b/lib/src/printers/pretty_printer.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'dart:math'; import '../ansi_color.dart'; @@ -353,20 +352,6 @@ class PrettyPrinter extends LogPrinter { return dateTimeFormat(time); } - // Handles any object that is causing JsonEncoder() problems - Object toEncodableFallback(dynamic object) { - return object.toString(); - } - - String stringifyMessage(Object? message) { - if (message is Map || message is Iterable) { - var encoder = JsonEncoder.withIndent(' ', toEncodableFallback); - return encoder.convert(message); - } else { - return message.toString(); - } - } - AnsiColor _getLevelColor(Level level) { AnsiColor? color; if (colors) { diff --git a/lib/src/printers/simple_printer.dart b/lib/src/printers/simple_printer.dart index 7d7f8d8..da96c6f 100644 --- a/lib/src/printers/simple_printer.dart +++ b/lib/src/printers/simple_printer.dart @@ -35,7 +35,7 @@ class SimplePrinter extends LogPrinter { @override List log(LogEvent event) { - var messageStr = _stringifyMessage(event.message); + var messageStr = stringifyMessage(event.message); var errorStr = event.error != null ? ' ERROR: ${event.error}' : ''; var timeStr = printTime ? 'TIME: ${event.time.toIso8601String()}' : ''; return ['${_labelFor(event.level)} $timeStr $messageStr$errorStr']; @@ -48,12 +48,9 @@ class SimplePrinter extends LogPrinter { return colors ? color(prefix) : prefix; } - String _stringifyMessage(Object? message) { - if (message is Map || message is Iterable) { - var encoder = const JsonEncoder.withIndent(null); - return encoder.convert(message); - } else { - return message.toString(); - } + @override + String encodeJson(Object? message) { + var encoder = const JsonEncoder.withIndent(null); + return encoder.convert(message); } } From 69d1e036f4dfdf0ba45ad138c9c3ffa04bed790b Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 01:38:39 +0200 Subject: [PATCH 06/18] Renamed static `level` to `defaultLevel` --- lib/src/log_filter.dart | 4 ++-- lib/src/logger.dart | 2 +- test/logger_test.dart | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/log_filter.dart b/lib/src/log_filter.dart index af6bbd8..b94d718 100644 --- a/lib/src/log_filter.dart +++ b/lib/src/log_filter.dart @@ -5,12 +5,12 @@ import 'logger.dart'; /// An abstract filter of log messages. /// /// You can implement your own `LogFilter` or use [DevelopmentFilter]. -/// Every implementation should consider [Logger.level]. +/// Every implementation should consider [level]. abstract class LogFilter { Level? _level; // Still nullable for backwards compatibility. - Level? get level => _level ?? Logger.level; + Level? get level => _level ?? Logger.defaultLevel; set level(Level? value) => _level = value; diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 1167d52..aac56e7 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -17,7 +17,7 @@ class Logger { /// The current logging level of the app. /// /// All logs with levels below this level will be omitted. - static Level level = Level.trace; + static Level defaultLevel = Level.trace; /// The current default implementation of log filter. static LogFilter Function() defaultFilter = () => DevelopmentFilter(); diff --git a/test/logger_test.dart b/test/logger_test.dart index cc620d9..f4f4f02 100644 --- a/test/logger_test.dart +++ b/test/logger_test.dart @@ -265,7 +265,7 @@ void main() { test('Setting filter Levels', () { var filter = ProductionFilter(); - expect(filter.level, Logger.level); + expect(filter.level, Logger.defaultLevel); final initLevel = Level.warning; // ignore: unused_local_variable From 5bab40abc40f0b1212f3b17ed91dc7afb59bdc9b Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 01:40:54 +0200 Subject: [PATCH 07/18] Added `filter`, `printer` and `output` getter --- lib/src/logger.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/src/logger.dart b/lib/src/logger.dart index aac56e7..3f2d024 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -67,6 +67,12 @@ class Logger { /// uses `async` in their `init` method. Future get init => _initialization; + LogFilter get filter => _filter; + + LogPrinter get printer => _printer; + + LogOutput get output => _output; + /// Log a message at level [Level.verbose]. @Deprecated( "[Level.verbose] is being deprecated in favor of [Level.trace], use [t] instead.") From b84e505740fab10aa1e75b05f032b56a5e9393b0 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Mon, 15 Apr 2024 01:43:56 +0200 Subject: [PATCH 08/18] Moved `level` from LogFilter to Logger, closes #38 --- lib/src/filters/development_filter.dart | 2 +- lib/src/filters/production_filter.dart | 2 +- lib/src/log_filter.dart | 10 +++----- lib/src/log_output.dart | 3 +++ lib/src/log_printer.dart | 3 +++ lib/src/logger.dart | 20 +++++++++------ test/logger_test.dart | 34 +++++-------------------- 7 files changed, 30 insertions(+), 44 deletions(-) diff --git a/lib/src/filters/development_filter.dart b/lib/src/filters/development_filter.dart index a2414e2..6290425 100644 --- a/lib/src/filters/development_filter.dart +++ b/lib/src/filters/development_filter.dart @@ -10,7 +10,7 @@ class DevelopmentFilter extends LogFilter { bool shouldLog(LogEvent event) { var shouldLog = false; assert(() { - if (event.level >= level!) { + if (event.level >= level) { shouldLog = true; } return true; diff --git a/lib/src/filters/production_filter.dart b/lib/src/filters/production_filter.dart index 533b0b2..21e6c63 100644 --- a/lib/src/filters/production_filter.dart +++ b/lib/src/filters/production_filter.dart @@ -5,6 +5,6 @@ import '../log_filter.dart'; class ProductionFilter extends LogFilter { @override bool shouldLog(LogEvent event) { - return event.level >= level!; + return event.level >= level; } } diff --git a/lib/src/log_filter.dart b/lib/src/log_filter.dart index b94d718..0113723 100644 --- a/lib/src/log_filter.dart +++ b/lib/src/log_filter.dart @@ -5,14 +5,12 @@ import 'logger.dart'; /// An abstract filter of log messages. /// /// You can implement your own `LogFilter` or use [DevelopmentFilter]. -/// Every implementation should consider [level]. +/// Every implementation should consider [Logger.level]. abstract class LogFilter { - Level? _level; + late Logger logger; - // Still nullable for backwards compatibility. - Level? get level => _level ?? Logger.defaultLevel; - - set level(Level? value) => _level = value; + /// Shortcut getter for [Logger.level]. + Level get level => logger.level; Future init() async {} diff --git a/lib/src/log_output.dart b/lib/src/log_output.dart index ab35e1a..d8c9e53 100644 --- a/lib/src/log_output.dart +++ b/lib/src/log_output.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'logger.dart'; import 'output_event.dart'; /// Log output receives a [OutputEvent] from [LogPrinter] and sends it to the @@ -8,6 +9,8 @@ import 'output_event.dart'; /// This can be an output stream, a file or a network target. [LogOutput] may /// cache multiple log messages. abstract class LogOutput { + late Logger logger; + Future init() async {} void output(OutputEvent event); diff --git a/lib/src/log_printer.dart b/lib/src/log_printer.dart index 893ad9e..7b5a6cb 100644 --- a/lib/src/log_printer.dart +++ b/lib/src/log_printer.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'log_event.dart'; +import 'logger.dart'; /// An abstract handler of log events. /// @@ -10,6 +11,8 @@ import 'log_event.dart'; /// /// You can implement a `LogPrinter` from scratch or extend [PrettyPrinter]. abstract class LogPrinter { + late Logger logger; + Future init() async {} /// Is called every time a new [LogEvent] is sent and handles printing or diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 3f2d024..15250b7 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -14,9 +14,7 @@ typedef OutputCallback = void Function(OutputEvent event); /// Use instances of logger to send log messages to the [LogPrinter]. class Logger { - /// The current logging level of the app. - /// - /// All logs with levels below this level will be omitted. + /// The default logging level of new loggers. static Level defaultLevel = Level.trace; /// The current default implementation of log filter. @@ -33,6 +31,10 @@ class Logger { static final Set _outputCallbacks = {}; late final Future _initialization; + + /// All logs with levels below this level will be omitted. + Level level; + final LogFilter _filter; final LogPrinter _printer; final LogOutput _output; @@ -44,17 +46,19 @@ class Logger { /// defaults: [PrettyPrinter], [DevelopmentFilter] and [ConsoleOutput] will be /// used. Logger({ + Level? level, LogFilter? filter, LogPrinter? printer, LogOutput? output, - Level? level, - }) : _filter = filter ?? defaultFilter(), + }) : level = level ?? defaultLevel, + _filter = filter ?? defaultFilter(), _printer = printer ?? defaultPrinter(), _output = output ?? defaultOutput() { + _filter.logger = this; + _printer.logger = this; + _output.logger = this; + var filterInit = _filter.init(); - if (level != null) { - _filter.level = level; - } var printerInit = _printer.init(); var outputInit = _output.init(); _initialization = Future.wait([filterInit, printerInit, outputInit]); diff --git a/test/logger_test.dart b/test/logger_test.dart index f4f4f02..58ff1df 100644 --- a/test/logger_test.dart +++ b/test/logger_test.dart @@ -86,17 +86,6 @@ class _AsyncOutput extends LogOutput { } } -/// Test class for the lazy-initialization of variables. -class LazyLogger { - static bool? printed; - static final filter = ProductionFilter(); - static final printer = _CallbackPrinter((l, m, e, s) { - printed = true; - return []; - }); - static final logger = Logger(filter: filter, printer: printer); -} - void main() { Level? printedLevel; Object? printedMessage; @@ -248,7 +237,7 @@ void main() { expect(printedMessage, heavyComputation); }); - test('setting log level above log level of message', () { + test('Setting log level above log level of message', () { printedMessage = null; var logger = Logger( filter: ProductionFilter(), @@ -263,21 +252,17 @@ void main() { expect(printedMessage, 'This is'); }); - test('Setting filter Levels', () { - var filter = ProductionFilter(); - expect(filter.level, Logger.defaultLevel); - + test('Setting log level', () { final initLevel = Level.warning; - // ignore: unused_local_variable var logger = Logger( - filter: filter, + filter: ProductionFilter(), printer: callbackPrinter, level: initLevel, ); - expect(filter.level, initLevel); + expect(logger.filter.level, initLevel); - filter.level = Level.fatal; - expect(filter.level, Level.fatal); + logger.level = Level.fatal; + expect(logger.filter.level, Level.fatal); }); test('Logger.close', () async { @@ -287,13 +272,6 @@ void main() { expect(logger.isClosed(), true); }); - test('Lazy Logger Initialization', () { - expect(LazyLogger.printed, isNull); - LazyLogger.filter.level = Level.warning; - LazyLogger.logger.i("This is an info message and should not show"); - expect(LazyLogger.printed, isNull); - }); - test('Async Filter Initialization', () async { var comp = _AsyncFilter(const Duration(milliseconds: 100)); var logger = Logger( From c98e455aceb0950e3790a9383e7570b403385302 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Tue, 20 Aug 2024 00:51:12 +0200 Subject: [PATCH 09/18] Removed deprecated `printTime` flag in favor of `dateTimeFormat` --- lib/src/printers/pretty_printer.dart | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart index 167c64d..125f656 100644 --- a/lib/src/printers/pretty_printer.dart +++ b/lib/src/printers/pretty_printer.dart @@ -112,13 +112,12 @@ class PrettyPrinter extends LogPrinter { /// Whether emojis are prefixed to the log line. final bool printEmojis; - /// Whether [LogEvent.time] is printed. - @Deprecated("Use `dateTimeFormat` instead.") - bool get printTime => dateTimeFormat != DateTimeFormat.none; - /// Controls the format of [LogEvent.time]. final DateTimeFormatter dateTimeFormat; + /// Whether [LogEvent.time] is printed. + bool get _printTimestamp => dateTimeFormat != DateTimeFormat.none; + /// Controls the ascii 'boxing' of different [Level]s. /// /// By default all levels are 'boxed', @@ -195,24 +194,13 @@ class PrettyPrinter extends LogPrinter { this.lineLength = 120, this.colors = true, this.printEmojis = true, - @Deprecated( - "Use `dateTimeFormat` with `DateTimeFormat.onlyTimeAndSinceStart` or `DateTimeFormat.none` instead.") - bool? printTime, - DateTimeFormatter dateTimeFormat = DateTimeFormat.none, + this.dateTimeFormat = DateTimeFormat.none, this.excludeBox = const {}, this.noBoxingByDefault = false, this.excludePaths = const [], this.levelColors, this.levelEmojis, - }) : assert( - (printTime != null && dateTimeFormat == DateTimeFormat.none) || - printTime == null, - "Don't set printTime when using dateTimeFormat"), - dateTimeFormat = printTime == null - ? dateTimeFormat - : (printTime - ? DateTimeFormat.onlyTimeAndSinceStart - : DateTimeFormat.none) { + }) { startTime ??= DateTime.now(); var doubleDividerLine = StringBuffer(); @@ -256,9 +244,7 @@ class PrettyPrinter extends LogPrinter { var errorStr = event.error?.toString(); String? timeStr; - // Keep backwards-compatibility to `printTime` check - // ignore: deprecated_member_use_from_same_package - if (printTime) { + if (_printTimestamp) { timeStr = getTime(event.time); } From adeef0b1c9d75242ea216540b9f1df93a3428925 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Tue, 20 Aug 2024 01:02:58 +0200 Subject: [PATCH 10/18] Moved shared logic from `PrettyPrinter` up to `LogPrinter` --- lib/src/log_printer.dart | 190 +++++++++++++++++++++++++ lib/src/printers/pretty_printer.dart | 200 ++------------------------- 2 files changed, 199 insertions(+), 191 deletions(-) diff --git a/lib/src/log_printer.dart b/lib/src/log_printer.dart index 7b5a6cb..37bad37 100644 --- a/lib/src/log_printer.dart +++ b/lib/src/log_printer.dart @@ -1,5 +1,7 @@ import 'dart:convert'; +import 'dart:math'; +import 'date_time_format.dart'; import 'log_event.dart'; import 'logger.dart'; @@ -11,8 +13,94 @@ import 'logger.dart'; /// /// You can implement a `LogPrinter` from scratch or extend [PrettyPrinter]. abstract class LogPrinter { + /// Matches a stacktrace line as generated on Android/iOS devices. + /// + /// For example: + /// * #1 Logger.log (package:logger/src/logger.dart:115:29) + static final deviceStackTraceRegex = RegExp(r'#[0-9]+\s+(.+) \((\S+)\)'); + + /// Matches a stacktrace line as generated by Flutter web. + /// + /// For example: + /// * packages/logger/src/printers/pretty_printer.dart 91:37 + static final webStackTraceRegex = RegExp(r'^((?:packages|dart-sdk)/\S+/)'); + + /// Matches a stacktrace line as generated by browser Dart. + /// + /// For example: + /// * dart:sdk_internal + /// * package:logger/src/logger.dart + static final browserStackTraceRegex = RegExp(r'^((?:package:)?dart:\S+|\S+)'); + late Logger logger; + /// Controls the format of [LogEvent.time]. + final DateTimeFormatter dateTimeFormat; + + /// Whether [LogEvent.time] is printed. + bool get printTimestamp => dateTimeFormat != DateTimeFormat.none; + + /// The index at which the stack trace should start. + /// + /// This can be useful if, for instance, Logger is wrapped in another class and + /// you wish to remove these wrapped calls from stack trace + /// + /// See also: + /// * [excludePaths] + final int stackTraceBeginIndex; + + /// A list of custom paths that are excluded from the stack trace. + /// + /// For example, to exclude your `MyLog` util that redirects to this logger: + /// ```dart + /// excludePaths: [ + /// // To exclude a whole package + /// "package:test", + /// // To exclude a single file + /// "package:test/util/my_log.dart", + /// ], + /// ``` + /// + /// See also: + /// * [stackTraceBeginIndex] + final List excludePaths; + + /// Controls the method count in stack traces + /// when no [LogEvent.error] was provided. + /// + /// In case no [LogEvent.stackTrace] was provided, + /// [StackTrace.current] will be used to create one. + /// + /// * Set to `0` in order to disable printing a stack trace + /// without an error parameter. + /// * Set to `null` to remove the method count limit all together. + /// + /// See also: + /// * [errorMethodCount] + final int? methodCount; + + /// Controls the method count in stack traces + /// when [LogEvent.error] was provided. + /// + /// In case no [LogEvent.stackTrace] was provided, + /// [StackTrace.current] will be used to create one. + /// + /// * Set to `0` in order to disable printing a stack trace + /// in case of an error parameter. + /// * Set to `null` to remove the method count limit all together. + /// + /// See also: + /// * [methodCount] + final int? errorMethodCount; + + LogPrinter({ + this.dateTimeFormat = DateTimeFormat.none, + this.stackTraceBeginIndex = 0, + this.excludePaths = const [], + this.methodCount = 2, + this.errorMethodCount = 8, + }); + Future init() async {} /// Is called every time a new [LogEvent] is sent and handles printing or @@ -35,4 +123,106 @@ abstract class LogPrinter { var encoder = JsonEncoder.withIndent(' ', (object) => object.toString()); return encoder.convert(message); } + + String? getTime(DateTime time) { + if (printTimestamp) { + return dateTimeFormat(time); + } + return null; + } + + String? getStackTrace(LogEvent event) { + String? stackTraceStr; + if (event.error != null) { + if (errorMethodCount == null || errorMethodCount! > 0) { + stackTraceStr = formatStackTrace( + event.stackTrace ?? StackTrace.current, + methodCount: errorMethodCount, + ); + } + } else if (methodCount == null || methodCount! > 0) { + stackTraceStr = formatStackTrace( + event.stackTrace ?? StackTrace.current, + methodCount: methodCount, + ); + } + return stackTraceStr; + } + + String? formatStackTrace(StackTrace stackTrace, {int? methodCount}) { + List lines = stackTrace + .toString() + .split('\n') + .where( + (line) => + !discardDeviceStacktraceLine(line) && + !discardWebStacktraceLine(line) && + !discardBrowserStacktraceLine(line) && + line.isNotEmpty, + ) + .toList(); + List formatted = []; + + int stackTraceLength = + (methodCount != null ? min(lines.length, methodCount) : lines.length); + for (int count = 0; count < stackTraceLength; count++) { + var line = lines[count]; + if (count < stackTraceBeginIndex) { + continue; + } + formatted.add('#$count ${line.replaceFirst(RegExp(r'#\d+\s+'), '')}'); + } + + if (formatted.isEmpty) { + return null; + } else { + return formatted.join('\n'); + } + } + + bool isInExcludePaths(String segment) { + for (var element in excludePaths) { + if (segment.startsWith(element)) { + return true; + } + } + return false; + } + + bool discardDeviceStacktraceLine(String line) { + var match = deviceStackTraceRegex.matchAsPrefix(line); + if (match == null) { + return false; + } + final segment = match.group(2)!; + if (segment.startsWith('package:logger')) { + return true; + } + return isInExcludePaths(segment); + } + + bool discardWebStacktraceLine(String line) { + var match = webStackTraceRegex.matchAsPrefix(line); + if (match == null) { + return false; + } + final segment = match.group(1)!; + if (segment.startsWith('packages/logger') || + segment.startsWith('dart-sdk/lib')) { + return true; + } + return isInExcludePaths(segment); + } + + bool discardBrowserStacktraceLine(String line) { + var match = browserStackTraceRegex.matchAsPrefix(line); + if (match == null) { + return false; + } + final segment = match.group(1)!; + if (segment.startsWith('package:logger') || segment.startsWith('dart:')) { + return true; + } + return isInExcludePaths(segment); + } } diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart index 125f656..852e5c9 100644 --- a/lib/src/printers/pretty_printer.dart +++ b/lib/src/printers/pretty_printer.dart @@ -1,7 +1,4 @@ -import 'dart:math'; - import '../ansi_color.dart'; -import '../date_time_format.dart'; import '../log_event.dart'; import '../log_level.dart'; import '../log_printer.dart'; @@ -44,65 +41,8 @@ class PrettyPrinter extends LogPrinter { Level.fatal: '👾', }; - /// Matches a stacktrace line as generated on Android/iOS devices. - /// - /// For example: - /// * #1 Logger.log (package:logger/src/logger.dart:115:29) - static final _deviceStackTraceRegex = RegExp(r'#[0-9]+\s+(.+) \((\S+)\)'); - - /// Matches a stacktrace line as generated by Flutter web. - /// - /// For example: - /// * packages/logger/src/printers/pretty_printer.dart 91:37 - static final _webStackTraceRegex = RegExp(r'^((?:packages|dart-sdk)/\S+/)'); - - /// Matches a stacktrace line as generated by browser Dart. - /// - /// For example: - /// * dart:sdk_internal - /// * package:logger/src/logger.dart - static final _browserStackTraceRegex = - RegExp(r'^((?:package:)?dart:\S+|\S+)'); - static DateTime? startTime; - /// The index at which the stack trace should start. - /// - /// This can be useful if, for instance, Logger is wrapped in another class and - /// you wish to remove these wrapped calls from stack trace - /// - /// See also: - /// * [excludePaths] - final int stackTraceBeginIndex; - - /// Controls the method count in stack traces - /// when no [LogEvent.error] was provided. - /// - /// In case no [LogEvent.stackTrace] was provided, - /// [StackTrace.current] will be used to create one. - /// - /// * Set to `0` in order to disable printing a stack trace - /// without an error parameter. - /// * Set to `null` to remove the method count limit all together. - /// - /// See also: - /// * [errorMethodCount] - final int? methodCount; - - /// Controls the method count in stack traces - /// when [LogEvent.error] was provided. - /// - /// In case no [LogEvent.stackTrace] was provided, - /// [StackTrace.current] will be used to create one. - /// - /// * Set to `0` in order to disable printing a stack trace - /// in case of an error parameter. - /// * Set to `null` to remove the method count limit all together. - /// - /// See also: - /// * [methodCount] - final int? errorMethodCount; - /// Controls the length of the divider lines. final int lineLength; @@ -112,12 +52,6 @@ class PrettyPrinter extends LogPrinter { /// Whether emojis are prefixed to the log line. final bool printEmojis; - /// Controls the format of [LogEvent.time]. - final DateTimeFormatter dateTimeFormat; - - /// Whether [LogEvent.time] is printed. - bool get _printTimestamp => dateTimeFormat != DateTimeFormat.none; - /// Controls the ascii 'boxing' of different [Level]s. /// /// By default all levels are 'boxed', @@ -155,22 +89,6 @@ class PrettyPrinter extends LogPrinter { /// * [excludeBox] final bool noBoxingByDefault; - /// A list of custom paths that are excluded from the stack trace. - /// - /// For example, to exclude your `MyLog` util that redirects to this logger: - /// ```dart - /// excludePaths: [ - /// // To exclude a whole package - /// "package:test", - /// // To exclude a single file - /// "package:test/util/my_log.dart", - /// ], - /// ``` - /// - /// See also: - /// * [stackTraceBeginIndex] - final List excludePaths; - /// Contains the parsed rules resulting from [excludeBox] and [noBoxingByDefault]. late final Map _includeBox; String _topBorder = ''; @@ -188,16 +106,16 @@ class PrettyPrinter extends LogPrinter { final Map? levelEmojis; PrettyPrinter({ - this.stackTraceBeginIndex = 0, - this.methodCount = 2, - this.errorMethodCount = 8, + super.stackTraceBeginIndex, + super.methodCount, + super.errorMethodCount, this.lineLength = 120, this.colors = true, this.printEmojis = true, - this.dateTimeFormat = DateTimeFormat.none, + super.dateTimeFormat, this.excludeBox = const {}, this.noBoxingByDefault = false, - this.excludePaths = const [], + super.excludePaths, this.levelColors, this.levelEmojis, }) { @@ -224,29 +142,10 @@ class PrettyPrinter extends LogPrinter { @override List log(LogEvent event) { - var messageStr = stringifyMessage(event.message); - - String? stackTraceStr; - if (event.error != null) { - if ((errorMethodCount == null || errorMethodCount! > 0)) { - stackTraceStr = formatStackTrace( - event.stackTrace ?? StackTrace.current, - errorMethodCount, - ); - } - } else if (methodCount == null || methodCount! > 0) { - stackTraceStr = formatStackTrace( - event.stackTrace ?? StackTrace.current, - methodCount, - ); - } - - var errorStr = event.error?.toString(); - - String? timeStr; - if (_printTimestamp) { - timeStr = getTime(event.time); - } + String messageStr = stringifyMessage(event.message); + String? stackTraceStr = getStackTrace(event); + String? timeStr = getTime(event.time); + String? errorStr = event.error?.toString(); return _formatAndPrint( event.level, @@ -257,87 +156,6 @@ class PrettyPrinter extends LogPrinter { ); } - String? formatStackTrace(StackTrace? stackTrace, int? methodCount) { - List lines = stackTrace - .toString() - .split('\n') - .where( - (line) => - !_discardDeviceStacktraceLine(line) && - !_discardWebStacktraceLine(line) && - !_discardBrowserStacktraceLine(line) && - line.isNotEmpty, - ) - .toList(); - List formatted = []; - - int stackTraceLength = - (methodCount != null ? min(lines.length, methodCount) : lines.length); - for (int count = 0; count < stackTraceLength; count++) { - var line = lines[count]; - if (count < stackTraceBeginIndex) { - continue; - } - formatted.add('#$count ${line.replaceFirst(RegExp(r'#\d+\s+'), '')}'); - } - - if (formatted.isEmpty) { - return null; - } else { - return formatted.join('\n'); - } - } - - bool _isInExcludePaths(String segment) { - for (var element in excludePaths) { - if (segment.startsWith(element)) { - return true; - } - } - return false; - } - - bool _discardDeviceStacktraceLine(String line) { - var match = _deviceStackTraceRegex.matchAsPrefix(line); - if (match == null) { - return false; - } - final segment = match.group(2)!; - if (segment.startsWith('package:logger')) { - return true; - } - return _isInExcludePaths(segment); - } - - bool _discardWebStacktraceLine(String line) { - var match = _webStackTraceRegex.matchAsPrefix(line); - if (match == null) { - return false; - } - final segment = match.group(1)!; - if (segment.startsWith('packages/logger') || - segment.startsWith('dart-sdk/lib')) { - return true; - } - return _isInExcludePaths(segment); - } - - bool _discardBrowserStacktraceLine(String line) { - var match = _browserStackTraceRegex.matchAsPrefix(line); - if (match == null) { - return false; - } - final segment = match.group(1)!; - if (segment.startsWith('package:logger') || segment.startsWith('dart:')) { - return true; - } - return _isInExcludePaths(segment); - } - - String getTime(DateTime time) { - return dateTimeFormat(time); - } - AnsiColor _getLevelColor(Level level) { AnsiColor? color; if (colors) { From ab8387858e5ed6a6e133652332bc0ef9d4a7b851 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Tue, 20 Aug 2024 01:03:23 +0200 Subject: [PATCH 11/18] Added `iso8601` DateTimeFormatter --- lib/src/date_time_format.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/src/date_time_format.dart b/lib/src/date_time_format.dart index d93b5a3..39af99d 100644 --- a/lib/src/date_time_format.dart +++ b/lib/src/date_time_format.dart @@ -30,6 +30,12 @@ class DateTimeFormat { /// * `2019-06-04 12:30:40.550` static const DateTimeFormatter dateAndTime = _dateAndTime; + /// Prints date and time in ISO-8601 format. + /// + /// See also: + /// [DateTime.toIso8601String] + static const DateTimeFormatter iso8601 = _iso8601; + DateTimeFormat._(); static String _none(DateTime t) => throw UnimplementedError(); @@ -67,4 +73,8 @@ class DateTimeFormat { static String _dateAndTime(DateTime t) { return "${_onlyDate(t)} ${_onlyTime(t)}"; } + + static String _iso8601(DateTime t) { + return t.toIso8601String(); + } } From e1b689a30b62b46bcd14a425ed4f2d64d90eb127 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Tue, 20 Aug 2024 01:04:29 +0200 Subject: [PATCH 12/18] Added `dateTimeFormat` support --- lib/src/printers/logfmt_printer.dart | 10 ++++++++++ test/printers/logfmt_printer_test.dart | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/src/printers/logfmt_printer.dart b/lib/src/printers/logfmt_printer.dart index 5763196..5cf1b8f 100644 --- a/lib/src/printers/logfmt_printer.dart +++ b/lib/src/printers/logfmt_printer.dart @@ -1,3 +1,4 @@ +import '../date_time_format.dart'; import '../log_event.dart'; import '../log_level.dart'; import '../log_printer.dart'; @@ -16,6 +17,10 @@ class LogfmtPrinter extends LogPrinter { Level.fatal: 'fatal', }; + LogfmtPrinter({ + super.dateTimeFormat = DateTimeFormat.iso8601, + }); + @override List log(LogEvent event) { var output = StringBuffer('level=${levelPrefixes[event.level]}'); @@ -32,6 +37,11 @@ class LogfmtPrinter extends LogPrinter { } } } + + if (printTimestamp) { + output.write(' time="${getTime(event.time)}"'); + } + if (event.error != null) { output.write(' error="${event.error}"'); } diff --git a/test/printers/logfmt_printer_test.dart b/test/printers/logfmt_printer_test.dart index 8212cbe..02015ef 100644 --- a/test/printers/logfmt_printer_test.dart +++ b/test/printers/logfmt_printer_test.dart @@ -40,6 +40,20 @@ void main() { expect(output, contains('foo="bar baz"')); }); + test('includes time', () { + var timestamp = DateTime.now(); + expect( + printer.log(LogEvent( + Level.debug, + 'some message', + error: Exception('boom'), + stackTrace: StackTrace.current, + time: timestamp, + ))[0], + contains('time="${timestamp.toIso8601String()}"'), + ); + }); + test('handles an error/exception', () { var output = printer.log(LogEvent( Level.debug, From 0a04017865baca947c0c68d308e977c4796acf2d Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Tue, 20 Aug 2024 01:07:42 +0200 Subject: [PATCH 13/18] Replaced `printTime` with `dateTimeFormat` --- lib/src/printers/simple_printer.dart | 9 ++++++--- test/printers/simple_printer_test.dart | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/src/printers/simple_printer.dart b/lib/src/printers/simple_printer.dart index da96c6f..62953f4 100644 --- a/lib/src/printers/simple_printer.dart +++ b/lib/src/printers/simple_printer.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import '../ansi_color.dart'; +import '../date_time_format.dart'; import '../log_event.dart'; import '../log_level.dart'; import '../log_printer.dart'; @@ -28,16 +29,18 @@ class SimplePrinter extends LogPrinter { Level.fatal: const AnsiColor.fg(199), }; - final bool printTime; final bool colors; - SimplePrinter({this.printTime = false, this.colors = true}); + SimplePrinter({ + super.dateTimeFormat = DateTimeFormat.none, + this.colors = true, + }); @override List log(LogEvent event) { var messageStr = stringifyMessage(event.message); var errorStr = event.error != null ? ' ERROR: ${event.error}' : ''; - var timeStr = printTime ? 'TIME: ${event.time.toIso8601String()}' : ''; + var timeStr = printTimestamp ? 'TIME: ${getTime(event.time)}' : ''; return ['${_labelFor(event.level)} $timeStr $messageStr$errorStr']; } diff --git a/test/printers/simple_printer_test.dart b/test/printers/simple_printer_test.dart index f3376f2..04cbe08 100644 --- a/test/printers/simple_printer_test.dart +++ b/test/printers/simple_printer_test.dart @@ -11,7 +11,8 @@ void main() { stackTrace: StackTrace.current, ); - var plainPrinter = SimplePrinter(colors: false, printTime: false); + var plainPrinter = + SimplePrinter(colors: false, dateTimeFormat: DateTimeFormat.none); test('represent event on a single line (ignoring stacktrace)', () { var outputs = plainPrinter.log(event); @@ -37,13 +38,13 @@ void main() { }); test('print time', () { - var printer = SimplePrinter(printTime: true); + var printer = SimplePrinter(dateTimeFormat: DateTimeFormat.iso8601); expect(printer.log(event)[0], contains('TIME')); }); test('does not print time', () { - var printer = SimplePrinter(printTime: false); + var printer = SimplePrinter(); expect(printer.log(event)[0], isNot(contains('TIME'))); }); From 024e6ba486299d5ce9e55a32469f465bbd0b249d Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Wed, 23 Oct 2024 23:49:19 +0200 Subject: [PATCH 14/18] Renamed `addLogListener` to `addGlobalLogListener` --- lib/src/logger.dart | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 15250b7..5b8e13d 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -26,9 +26,9 @@ class Logger { /// The current default implementation of log output. static LogOutput Function() defaultOutput = () => ConsoleOutput(); - static final Set _logCallbacks = {}; + static final Set _globalLogCallbacks = {}; - static final Set _outputCallbacks = {}; + static final Set _globalOutputCallbacks = {}; late final Future _initialization; @@ -188,7 +188,7 @@ class Logger { error: error, stackTrace: stackTrace, ); - for (var callback in _logCallbacks) { + for (var callback in _globalLogCallbacks) { callback(logEvent); } @@ -203,7 +203,7 @@ class Logger { // Issues with log output should NOT influence // the main software behavior. try { - for (var callback in _outputCallbacks) { + for (var callback in _globalOutputCallbacks) { callback(outputEvent); } _output.output(outputEvent); @@ -227,27 +227,27 @@ class Logger { await _output.destroy(); } - /// Register a [LogCallback] which is called for each new [LogEvent]. - static void addLogListener(LogCallback callback) { - _logCallbacks.add(callback); + /// Register a global [LogCallback] which is called for each new [LogEvent] on each logger. + static void addGlobalLogListener(LogCallback callback) { + _globalLogCallbacks.add(callback); } - /// Removes a [LogCallback] which was previously registered. + /// Removes a global [LogCallback] which was previously registered. /// /// Returns whether the callback was successfully removed. - static bool removeLogListener(LogCallback callback) { - return _logCallbacks.remove(callback); + static bool removeGlobalLogListener(LogCallback callback) { + return _globalLogCallbacks.remove(callback); } - /// Register an [OutputCallback] which is called for each new [OutputEvent]. - static void addOutputListener(OutputCallback callback) { - _outputCallbacks.add(callback); + /// Register a global [OutputCallback] which is called for each new [OutputEvent] on each logger. + static void addGlobalOutputListener(OutputCallback callback) { + _globalOutputCallbacks.add(callback); } - /// Removes a [OutputCallback] which was previously registered. + /// Removes a global [OutputCallback] which was previously registered. /// /// Returns whether the callback was successfully removed. - static void removeOutputListener(OutputCallback callback) { - _outputCallbacks.remove(callback); + static bool removeGlobalOutputListener(OutputCallback callback) { + return _globalOutputCallbacks.remove(callback); } } From f78af11f1a9e1bac24a9b9d9403e0f562547b602 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Wed, 23 Oct 2024 23:50:18 +0200 Subject: [PATCH 15/18] Added per-instance `addLogListener`, closes #83 --- lib/src/logger.dart | 39 ++++++++- test/listener_test.dart | 182 ++++++++++++++++++++++++++++++++++++++++ test/logger_test.dart | 22 ++--- 3 files changed, 230 insertions(+), 13 deletions(-) create mode 100644 test/listener_test.dart diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 5b8e13d..16cce23 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -30,6 +30,10 @@ class Logger { static final Set _globalOutputCallbacks = {}; + final Set _logCallbacks = {}; + + final Set _outputCallbacks = {}; + late final Future _initialization; /// All logs with levels below this level will be omitted. @@ -188,7 +192,9 @@ class Logger { error: error, stackTrace: stackTrace, ); - for (var callback in _globalLogCallbacks) { + + var collectedLogCallbacks = [..._logCallbacks, ..._globalLogCallbacks]; + for (var callback in collectedLogCallbacks) { callback(logEvent); } @@ -203,9 +209,14 @@ class Logger { // Issues with log output should NOT influence // the main software behavior. try { - for (var callback in _globalOutputCallbacks) { + var collectedOutputCallbacks = [ + ..._outputCallbacks, + ..._globalOutputCallbacks, + ]; + for (var callback in collectedOutputCallbacks) { callback(outputEvent); } + _output.output(outputEvent); } catch (e, s) { print(e); @@ -227,6 +238,30 @@ class Logger { await _output.destroy(); } + /// Register a [LogCallback] which is called for each new [LogEvent]. + void addLogListener(LogCallback callback) { + _logCallbacks.add(callback); + } + + /// Removes a [LogCallback] which was previously registered. + /// + /// Returns whether the callback was successfully removed. + bool removeLogListener(LogCallback callback) { + return _logCallbacks.remove(callback); + } + + /// Register an [OutputCallback] which is called for each new [OutputEvent]. + void addOutputListener(OutputCallback callback) { + _outputCallbacks.add(callback); + } + + /// Removes a [OutputCallback] which was previously registered. + /// + /// Returns whether the callback was successfully removed. + bool removeOutputListener(OutputCallback callback) { + return _outputCallbacks.remove(callback); + } + /// Register a global [LogCallback] which is called for each new [LogEvent] on each logger. static void addGlobalLogListener(LogCallback callback) { _globalLogCallbacks.add(callback); diff --git a/test/listener_test.dart b/test/listener_test.dart new file mode 100644 index 0000000..194670a --- /dev/null +++ b/test/listener_test.dart @@ -0,0 +1,182 @@ +import 'package:logger/logger.dart'; +import 'package:test/test.dart'; + +import 'logger_test.dart'; + +class NoOutput extends LogOutput { + @override + void output(OutputEvent event) { + // No-op. + } +} + +void main() { + group("Local", () { + LogEvent? loggedLogEvent; + logCallback(LogEvent event) { + loggedLogEvent = event; + } + + OutputEvent? loggedOutputEvent; + outputCallback(OutputEvent event) { + loggedOutputEvent = event; + } + + test('LogListener', () { + var stackTrace = StackTrace.current; + + var logger = Logger(filter: NeverFilter(), output: NoOutput()); + logger.addLogListener(logCallback); + logger.i('Test', error: 'Error', stackTrace: stackTrace); + + expect(loggedLogEvent?.level, Level.info); + expect(loggedLogEvent?.message, 'Test'); + expect(loggedLogEvent?.error, 'Error'); + expect(loggedLogEvent?.stackTrace, stackTrace); + + logger.removeLogListener(logCallback); + logger.i('Test2'); + + // event stays the same + expect(loggedLogEvent?.level, Level.info); + expect(loggedLogEvent?.message, 'Test'); + expect(loggedLogEvent?.error, 'Error'); + expect(loggedLogEvent?.stackTrace, stackTrace); + }); + + test('OutputListener', () { + var stackTrace = StackTrace.current; + + var logger = Logger(filter: AlwaysFilter(), output: NoOutput()); + logger.addOutputListener(outputCallback); + logger.i('Test', error: 'Error', stackTrace: stackTrace); + + expect(loggedOutputEvent?.origin.level, Level.info); + expect(loggedOutputEvent?.origin.message, 'Test'); + expect(loggedOutputEvent?.origin.error, 'Error'); + expect(loggedOutputEvent?.origin.stackTrace, stackTrace); + + logger.removeOutputListener(outputCallback); + logger.i('Test2'); + + // event stays the same + expect(loggedOutputEvent?.origin.level, Level.info); + expect(loggedOutputEvent?.origin.message, 'Test'); + expect(loggedOutputEvent?.origin.error, 'Error'); + expect(loggedOutputEvent?.origin.stackTrace, stackTrace); + }); + + test('OutputListener Filter', () { + var stackTrace = StackTrace.current; + OutputEvent? loggedEvent; + callback(OutputEvent event) { + loggedEvent = event; + } + + var logger = Logger(filter: NeverFilter(), output: NoOutput()); + logger.addOutputListener(callback); + logger.i('Test', error: 'Error', stackTrace: stackTrace); + + expect(loggedEvent, isNull); + + logger.close(); + logger = Logger(filter: AlwaysFilter(), output: NoOutput()); + logger.addOutputListener(callback); + + logger.i('Test', error: 'Error', stackTrace: stackTrace); + + expect(loggedEvent?.origin.level, Level.info); + expect(loggedEvent?.origin.message, 'Test'); + expect(loggedEvent?.origin.error, 'Error'); + expect(loggedEvent?.origin.stackTrace, stackTrace); + + logger.removeOutputListener(callback); + logger.i('Test2'); + + // event stays the same + expect(loggedEvent?.origin.level, Level.info); + expect(loggedEvent?.origin.message, 'Test'); + expect(loggedEvent?.origin.error, 'Error'); + expect(loggedEvent?.origin.stackTrace, stackTrace); + }); + }); + + group("Global", () { + LogEvent? localEvent; + localCallback(LogEvent event) { + localEvent = event; + } + + LogEvent? globalEvent; + globalCallback(LogEvent event) { + globalEvent = event; + } + + OutputEvent? localOutputEvent; + localOutputCallback(OutputEvent event) { + localOutputEvent = event; + } + + OutputEvent? globalOutputEvent; + globalOutputCallback(OutputEvent event) { + globalOutputEvent = event; + } + + setUp(() { + Logger.addGlobalLogListener(globalCallback); + Logger.addGlobalOutputListener(globalOutputCallback); + }); + + tearDown(() { + Logger.removeGlobalLogListener(globalCallback); + localEvent = null; + globalEvent = null; + + Logger.removeGlobalOutputListener(globalOutputCallback); + localOutputEvent = null; + globalOutputEvent = null; + }); + + test(' LogListener', () { + var logger = Logger(filter: NeverFilter(), output: NoOutput()); + var secondLogger = Logger(filter: NeverFilter(), output: NoOutput()); + + secondLogger.addLogListener(localCallback); + + logger.i('Test'); + expect(globalEvent, isNotNull); + expect(localEvent, isNull); + + secondLogger.i('Test2'); + expect(globalEvent?.message, 'Test2'); + expect(localEvent?.message, 'Test2'); + + Logger.removeGlobalLogListener(globalCallback); + logger.i('Test3'); + + // event stays the same + expect(globalEvent?.message, 'Test2'); + }); + + test(' OutputListener', () { + var logger = Logger(filter: AlwaysFilter(), output: NoOutput()); + var secondLogger = Logger(filter: AlwaysFilter(), output: NoOutput()); + + secondLogger.addOutputListener(localOutputCallback); + + logger.i('Test'); + expect(globalOutputEvent, isNotNull); + expect(localOutputEvent, isNull); + + secondLogger.i('Test2'); + expect(globalOutputEvent?.origin.message, 'Test2'); + expect(localOutputEvent?.origin.message, 'Test2'); + + Logger.removeGlobalOutputListener(globalOutputCallback); + logger.i('Test3'); + + // event stays the same + expect(globalOutputEvent?.origin.message, 'Test2'); + }); + }); +} diff --git a/test/logger_test.dart b/test/logger_test.dart index 58ff1df..38bb2aa 100644 --- a/test/logger_test.dart +++ b/test/logger_test.dart @@ -10,12 +10,12 @@ typedef PrinterCallback = List Function( StackTrace? stackTrace, ); -class _AlwaysFilter extends LogFilter { +class AlwaysFilter extends LogFilter { @override bool shouldLog(LogEvent event) => true; } -class _NeverFilter extends LogFilter { +class NeverFilter extends LogFilter { @override bool shouldLog(LogEvent event) => false; } @@ -107,12 +107,12 @@ void main() { }); test('Logger.log', () { - var logger = Logger(filter: _NeverFilter(), printer: callbackPrinter); + var logger = Logger(filter: NeverFilter(), printer: callbackPrinter); logger.log(Level.debug, 'Some message'); expect(printedMessage, null); - logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var levels = [ Level.trace, @@ -170,7 +170,7 @@ void main() { }); test('Logger.t', () { - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var stackTrace = StackTrace.current; logger.t('Test', error: 'Error', stackTrace: stackTrace); expect(printedLevel, Level.trace); @@ -180,7 +180,7 @@ void main() { }); test('Logger.d', () { - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var stackTrace = StackTrace.current; logger.d('Test', error: 'Error', stackTrace: stackTrace); expect(printedLevel, Level.debug); @@ -190,7 +190,7 @@ void main() { }); test('Logger.i', () { - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var stackTrace = StackTrace.current; logger.i('Test', error: 'Error', stackTrace: stackTrace); expect(printedLevel, Level.info); @@ -200,7 +200,7 @@ void main() { }); test('Logger.w', () { - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var stackTrace = StackTrace.current; logger.w('Test', error: 'Error', stackTrace: stackTrace); expect(printedLevel, Level.warning); @@ -210,7 +210,7 @@ void main() { }); test('Logger.e', () { - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var stackTrace = StackTrace.current; logger.e('Test', error: 'Error', stackTrace: stackTrace); expect(printedLevel, Level.error); @@ -220,7 +220,7 @@ void main() { }); test('Logger.f', () { - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); var stackTrace = StackTrace.current; logger.f('Test', error: 'Error', stackTrace: stackTrace); expect(printedLevel, Level.fatal); @@ -232,7 +232,7 @@ void main() { test('Deal with function messages', () { final heavyComputation = 'heavily computed very pretty Message'; - var logger = Logger(filter: _AlwaysFilter(), printer: callbackPrinter); + var logger = Logger(filter: AlwaysFilter(), printer: callbackPrinter); logger.f(() => heavyComputation); expect(printedMessage, heavyComputation); }); From a60481d6a2e5ab0522a77d89b6205e17fc8eaefd Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Sat, 15 Feb 2025 22:03:13 +0100 Subject: [PATCH 16/18] Removed deprecated log-levels --- lib/src/log_level.dart | 6 ----- lib/src/logger.dart | 27 +---------------------- lib/src/outputs/advanced_file_output.dart | 4 +--- lib/src/printers/hybrid_printer.dart | 8 ++----- lib/src/printers/prefix_printer.dart | 6 ++--- 5 files changed, 6 insertions(+), 45 deletions(-) diff --git a/lib/src/log_level.dart b/lib/src/log_level.dart index 1c89c1a..bc5dc15 100644 --- a/lib/src/log_level.dart +++ b/lib/src/log_level.dart @@ -2,18 +2,12 @@ /// levels above certain [Level]. enum Level { all(0), - @Deprecated('[verbose] is being deprecated in favor of [trace].') - verbose(999), trace(1000), debug(2000), info(3000), warning(4000), error(5000), - @Deprecated('[wtf] is being deprecated in favor of [fatal].') - wtf(5999), fatal(6000), - @Deprecated('[nothing] is being deprecated in favor of [off].') - nothing(9999), off(10000), ; diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 16cce23..57ead2e 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -81,18 +81,6 @@ class Logger { LogOutput get output => _output; - /// Log a message at level [Level.verbose]. - @Deprecated( - "[Level.verbose] is being deprecated in favor of [Level.trace], use [t] instead.") - void v( - Object? message, { - DateTime? time, - Object? error, - StackTrace? stackTrace, - }) { - t(message, time: time, error: error, stackTrace: stackTrace); - } - /// Log a message at level [Level.trace]. void t( Object? message, { @@ -144,18 +132,6 @@ class Logger { log(Level.error, message, time: time, error: error, stackTrace: stackTrace); } - /// Log a message at level [Level.wtf]. - @Deprecated( - "[Level.wtf] is being deprecated in favor of [Level.fatal], use [f] instead.") - void wtf( - Object? message, { - DateTime? time, - Object? error, - StackTrace? stackTrace, - }) { - f(message, time: time, error: error, stackTrace: stackTrace); - } - /// Log a message at level [Level.fatal]. void f( Object? message, { @@ -180,8 +156,7 @@ class Logger { throw ArgumentError('Error parameter cannot take a StackTrace!'); } else if (level == Level.all) { throw ArgumentError('Log events cannot have Level.all'); - // ignore: deprecated_member_use_from_same_package - } else if (level == Level.off || level == Level.nothing) { + } else if (level == Level.off) { throw ArgumentError('Log events cannot have Level.off'); } diff --git a/lib/src/outputs/advanced_file_output.dart b/lib/src/outputs/advanced_file_output.dart index 4b8d525..a64768b 100644 --- a/lib/src/outputs/advanced_file_output.dart +++ b/lib/src/outputs/advanced_file_output.dart @@ -88,11 +88,9 @@ class AdvancedFileOutput extends LogOutput { _fileNameFormatter = fileNameFormatter ?? _defaultFileNameFormat, _writeImmediately = writeImmediately ?? [ - Level.error, Level.fatal, + Level.error, Level.warning, - // ignore: deprecated_member_use_from_same_package - Level.wtf, ], _maxRotatedFilesCount = maxRotatedFilesCount, _fileSorter = fileSorter ?? _defaultFileSorter, diff --git a/lib/src/printers/hybrid_printer.dart b/lib/src/printers/hybrid_printer.dart index 9ceac6d..9eb2a3f 100644 --- a/lib/src/printers/hybrid_printer.dart +++ b/lib/src/printers/hybrid_printer.dart @@ -20,18 +20,14 @@ class HybridPrinter extends LogPrinter { LogPrinter realPrinter, { LogPrinter? debug, LogPrinter? trace, - @Deprecated('[verbose] is being deprecated in favor of [trace].') - LogPrinter? verbose, LogPrinter? fatal, - @Deprecated('[wtf] is being deprecated in favor of [fatal].') - LogPrinter? wtf, LogPrinter? info, LogPrinter? warning, LogPrinter? error, }) : _printerMap = { Level.debug: debug ?? realPrinter, - Level.trace: trace ?? verbose ?? realPrinter, - Level.fatal: fatal ?? wtf ?? realPrinter, + Level.trace: trace ?? realPrinter, + Level.fatal: fatal ?? realPrinter, Level.info: info ?? realPrinter, Level.warning: warning ?? realPrinter, Level.error: error ?? realPrinter, diff --git a/lib/src/printers/prefix_printer.dart b/lib/src/printers/prefix_printer.dart index 6778263..e9ce176 100644 --- a/lib/src/printers/prefix_printer.dart +++ b/lib/src/printers/prefix_printer.dart @@ -20,17 +20,15 @@ class PrefixPrinter extends LogPrinter { this._realPrinter, { String? debug, String? trace, - @Deprecated('[verbose] is being deprecated in favor of [trace].') verbose, String? fatal, - @Deprecated('[wtf] is being deprecated in favor of [fatal].') wtf, String? info, String? warning, String? error, }) { _prefixMap = { Level.debug: debug ?? 'DEBUG', - Level.trace: trace ?? verbose ?? 'TRACE', - Level.fatal: fatal ?? wtf ?? 'FATAL', + Level.trace: trace ?? 'TRACE', + Level.fatal: fatal ?? 'FATAL', Level.info: info ?? 'INFO', Level.warning: warning ?? 'WARNING', Level.error: error ?? 'ERROR', From db08a6636928b1b12ed0fce24b4ff1e16df8914d Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Sat, 15 Feb 2025 22:45:17 +0100 Subject: [PATCH 17/18] Adopted sane defaults for printers --- lib/src/log_printer.dart | 4 ++-- lib/src/printers/pretty_printer.dart | 3 ++- lib/src/printers/simple_printer.dart | 2 +- test/printers/simple_printer_test.dart | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/src/log_printer.dart b/lib/src/log_printer.dart index 37bad37..3832c45 100644 --- a/lib/src/log_printer.dart +++ b/lib/src/log_printer.dart @@ -97,8 +97,8 @@ abstract class LogPrinter { this.dateTimeFormat = DateTimeFormat.none, this.stackTraceBeginIndex = 0, this.excludePaths = const [], - this.methodCount = 2, - this.errorMethodCount = 8, + this.methodCount = 0, + this.errorMethodCount = 30, }); Future init() async {} diff --git a/lib/src/printers/pretty_printer.dart b/lib/src/printers/pretty_printer.dart index 852e5c9..50ead0f 100644 --- a/lib/src/printers/pretty_printer.dart +++ b/lib/src/printers/pretty_printer.dart @@ -1,4 +1,5 @@ import '../ansi_color.dart'; +import '../date_time_format.dart'; import '../log_event.dart'; import '../log_level.dart'; import '../log_printer.dart'; @@ -112,7 +113,7 @@ class PrettyPrinter extends LogPrinter { this.lineLength = 120, this.colors = true, this.printEmojis = true, - super.dateTimeFormat, + super.dateTimeFormat = DateTimeFormat.onlyTimeAndSinceStart, this.excludeBox = const {}, this.noBoxingByDefault = false, super.excludePaths, diff --git a/lib/src/printers/simple_printer.dart b/lib/src/printers/simple_printer.dart index 62953f4..90d8f95 100644 --- a/lib/src/printers/simple_printer.dart +++ b/lib/src/printers/simple_printer.dart @@ -32,7 +32,7 @@ class SimplePrinter extends LogPrinter { final bool colors; SimplePrinter({ - super.dateTimeFormat = DateTimeFormat.none, + super.dateTimeFormat = DateTimeFormat.iso8601, this.colors = true, }); diff --git a/test/printers/simple_printer_test.dart b/test/printers/simple_printer_test.dart index 04cbe08..4303e86 100644 --- a/test/printers/simple_printer_test.dart +++ b/test/printers/simple_printer_test.dart @@ -38,13 +38,13 @@ void main() { }); test('print time', () { - var printer = SimplePrinter(dateTimeFormat: DateTimeFormat.iso8601); + var printer = SimplePrinter(); expect(printer.log(event)[0], contains('TIME')); }); test('does not print time', () { - var printer = SimplePrinter(); + var printer = SimplePrinter(dateTimeFormat: DateTimeFormat.none); expect(printer.log(event)[0], isNot(contains('TIME'))); }); From c00a6a128169068aee5de9da32be859087307486 Mon Sep 17 00:00:00 2001 From: Bungeefan Date: Sun, 9 Mar 2025 17:23:39 +0100 Subject: [PATCH 18/18] Improved log methods documentation --- lib/src/logger.dart | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 57ead2e..a867e71 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -81,7 +81,9 @@ class Logger { LogOutput get output => _output; - /// Log a message at level [Level.trace]. + /// Logs a message at level [Level.trace]. + /// + /// {@macro log.parameters} void t( Object? message, { DateTime? time, @@ -91,7 +93,9 @@ class Logger { log(Level.trace, message, time: time, error: error, stackTrace: stackTrace); } - /// Log a message at level [Level.debug]. + /// Logs a message at level [Level.debug]. + /// + /// {@macro log.parameters} void d( Object? message, { DateTime? time, @@ -101,7 +105,9 @@ class Logger { log(Level.debug, message, time: time, error: error, stackTrace: stackTrace); } - /// Log a message at level [Level.info]. + /// Logs a message at level [Level.info]. + /// + /// {@macro log.parameters} void i( Object? message, { DateTime? time, @@ -111,7 +117,9 @@ class Logger { log(Level.info, message, time: time, error: error, stackTrace: stackTrace); } - /// Log a message at level [Level.warning]. + /// Logs a message at level [Level.warning]. + /// + /// {@macro log.parameters} void w( Object? message, { DateTime? time, @@ -122,7 +130,9 @@ class Logger { time: time, error: error, stackTrace: stackTrace); } - /// Log a message at level [Level.error]. + /// Logs a message at level [Level.error]. + /// + /// {@macro log.parameters} void e( Object? message, { DateTime? time, @@ -132,7 +142,9 @@ class Logger { log(Level.error, message, time: time, error: error, stackTrace: stackTrace); } - /// Log a message at level [Level.fatal]. + /// Logs a message at level [Level.fatal]. + /// + /// {@macro log.parameters} void f( Object? message, { DateTime? time, @@ -142,7 +154,14 @@ class Logger { log(Level.fatal, message, time: time, error: error, stackTrace: stackTrace); } - /// Log a message with [level]. + /// Logs a message with [level]. + /// + /// {@template log.parameters} + /// [message] can be a [String], [Iterable], [Map] or even a [Function] + /// to lazily evaluate the log statement. + /// + /// In case no [time] is provided, it defaults to [DateTime.now()]. + /// {@endtemplate} void log( Level level, Object? message, {