diff --git a/lib/src/logger.dart b/lib/src/logger.dart index 1bd56b8b..bcfc0b38 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -32,6 +32,7 @@ class Logger { static final Set _outputCallbacks = {}; + late final Future _initialization; final LogFilter _filter; final LogPrinter _printer; final LogOutput _output; @@ -50,14 +51,22 @@ class Logger { }) : _filter = filter ?? defaultFilter(), _printer = printer ?? defaultPrinter(), _output = output ?? defaultOutput() { - _filter.init(); + var filterInit = _filter.init(); if (level != null) { _filter.level = level; } - _printer.init(); - _output.init(); + var printerInit = _printer.init(); + var outputInit = _output.init(); + _initialization = Future.wait([filterInit, printerInit, outputInit]); } + /// Future indicating if the initialization of the + /// logger components (filter, printer and output) has been finished. + /// + /// This is only necessary if your [LogFilter]/[LogPrinter]/[LogOutput] + /// uses `async` in their `init` method. + Future get init => _initialization; + /// Log a message at level [Level.verbose]. @Deprecated( "[Level.verbose] is being deprecated in favor of [Level.trace], use [t] instead.") diff --git a/test/logger_test.dart b/test/logger_test.dart index 349abc76..f2d5768a 100644 --- a/test/logger_test.dart +++ b/test/logger_test.dart @@ -36,6 +36,56 @@ class _CallbackPrinter extends LogPrinter { } } +class _AsyncFilter extends LogFilter { + final Duration delay; + bool initialized = false; + + _AsyncFilter(this.delay); + + @override + Future init() async { + await Future.delayed(delay); + initialized = true; + } + + @override + bool shouldLog(LogEvent event) => false; +} + +class _AsyncPrinter extends LogPrinter { + final Duration delay; + bool initialized = false; + + _AsyncPrinter(this.delay); + + @override + Future init() async { + await Future.delayed(delay); + initialized = true; + } + + @override + List log(LogEvent event) => [event.message.toString()]; +} + +class _AsyncOutput extends LogOutput { + final Duration delay; + bool initialized = false; + + _AsyncOutput(this.delay); + + @override + Future init() async { + await Future.delayed(delay); + initialized = true; + } + + @override + void output(OutputEvent event) { + // No-op. + } +} + /// Test class for the lazy-initialization of variables. class LazyLogger { static bool? printed; @@ -235,4 +285,43 @@ void main() { 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( + filter: comp, + ); + + expect(comp.initialized, false); + await Future.delayed(const Duration(milliseconds: 50)); + expect(comp.initialized, false); + await logger.init; + expect(comp.initialized, true); + }); + + test('Async Printer Initialization', () async { + var comp = _AsyncPrinter(const Duration(milliseconds: 100)); + var logger = Logger( + printer: comp, + ); + + expect(comp.initialized, false); + await Future.delayed(const Duration(milliseconds: 50)); + expect(comp.initialized, false); + await logger.init; + expect(comp.initialized, true); + }); + + test('Async Output Initialization', () async { + var comp = _AsyncOutput(const Duration(milliseconds: 100)); + var logger = Logger( + output: comp, + ); + + expect(comp.initialized, false); + await Future.delayed(const Duration(milliseconds: 50)); + expect(comp.initialized, false); + await logger.init; + expect(comp.initialized, true); + }); }