diff --git a/CHANGELOG.md b/CHANGELOG.md index 489b0eb..46f1d32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -## 1.1.2-wip +## 1.2.0-wip +* Add notification when the log level is changed. Logger `onLevelChanged` broadcasts a stream of level values. * Require Dart 2.19. ## 1.1.1 diff --git a/README.md b/README.md index 51b1ae1..5b96de1 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,14 @@ First, set the root `Level`. All messages at or above the current level are sent Then, listen on the `onRecord` stream for `LogRecord` events. The `LogRecord` class has various properties for the message, error, logger name, and more. +To listen for changed level notitfications use: + +```dart +Logger.root.onLevelChanged.listen((level) { + print('The new log level is $level'); +}); +``` + ## Logging messages Create a `Logger` with a unique name to easily identify the source of the log diff --git a/lib/src/logger.dart b/lib/src/logger.dart index f90fd06..bf27f50 100644 --- a/lib/src/logger.dart +++ b/lib/src/logger.dart @@ -55,6 +55,9 @@ class Logger { /// root [Logger]. StreamController? _controller; + /// Controller used to notify when the log level of this logger is changed. + StreamController? _levelChangedController; + /// Create or find a Logger by name. /// /// Calling `Logger(name)` will return the same instance whenever it is called @@ -139,7 +142,26 @@ class Logger { throw UnsupportedError( 'Cannot set the level to `null` on a logger with no parent.'); } + final isLevelChanged = _level != value; _level = value; + if (isLevelChanged) { + _levelChangedController?.add(value); + } + } + + /// Returns a stream of level values set to this [Logger]. + /// + /// You can listen for set levels using the standard stream APIs, + /// for instance: + /// + /// ```dart + /// logger.onLevelChanged.listen((level) { ... }); + /// ``` + /// A state error will be thrown if the level is changed + /// inside the callback. + Stream get onLevelChanged { + _levelChangedController ??= StreamController.broadcast(sync: true); + return _levelChangedController!.stream; } /// Returns a stream of messages added to this [Logger]. diff --git a/pubspec.yaml b/pubspec.yaml index 089a114..d75e5b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: logging -version: 1.1.2-wip +version: 1.2.0-wip description: >- Provides APIs for debugging and error logging, similar to loggers in other languages, such as the Closure JS Logger and java.util.logging.Logger. diff --git a/test/logging_test.dart b/test/logging_test.dart index f41723e..0c9bd66 100644 --- a/test/logging_test.dart +++ b/test/logging_test.dart @@ -714,5 +714,32 @@ void main() { expect(records[1].error, isNotNull); expect(records[2].error, isNull); }); + + test('listen for level changed', () { + final levels = []; + root.level = Level.ALL; + root.onLevelChanged.listen(levels.add); + root.level = Level.SEVERE; + root.level = Level.WARNING; + expect(levels, hasLength(2)); + }); + + test('onLevelChanged is not emited if set the level to the same value', () { + final levels = []; + root.level = Level.ALL; + root.onLevelChanged.listen(levels.add); + root.level = Level.ALL; + expect(levels, hasLength(0)); + }); + + test('setting level in a loop throws state error', () { + root.level = Level.ALL; + root.onLevelChanged.listen((event) { + // Cannot fire new event. Controller is already firing an event + expect(() => root.level = Level.SEVERE, throwsStateError); + }); + root.level = Level.WARNING; + expect(root.level, Level.SEVERE); + }); }); }