Skip to content

Commit c25deb4

Browse files
jamesderlinjakemac53
authored andcommitted
Make detached Loggers work regardless of hierarchicalLoggingEnabled (flutter#71)
Previously detached Loggers could log messages only if hierarchicalLoggingEnabled was true. This makes no sense to me since detached Loggers aren't part of a Logger hierarchy. Fixes https://github.com/dart-lang/logging/issues/34.
1 parent abc1207 commit c25deb4

File tree

3 files changed

+91
-19
lines changed

3 files changed

+91
-19
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Add top level `defaultLevel`.
44
* Require Dart `>=2.0.0`.
5+
* Make detached loggers work regardless of `hierarchicalLoggingEnabled`.
56

67
## 0.11.3+2
78

@@ -21,7 +22,7 @@
2122

2223
## 0.11.2
2324

24-
* Added Logger.detached - a convenience factory to obtain a logger that is not
25+
* Added `Logger.detached` - a convenience factory to obtain a logger that is not
2526
attached to this library's logger hierarchy.
2627

2728
## 0.11.1+1

lib/src/logger.dart

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,33 +80,40 @@ class Logger {
8080
Logger._internal(this.name, this.parent, Map<String, Logger> children)
8181
: _children = children,
8282
children = UnmodifiableMapView(children) {
83-
if (parent != null) {
83+
if (parent == null) {
84+
_level = defaultLevel;
85+
} else {
8486
parent._children[name] = this;
8587
}
8688
}
8789

8890
/// Effective level considering the levels established in this logger's
8991
/// parents (when [hierarchicalLoggingEnabled] is true).
9092
Level get level {
91-
if (hierarchicalLoggingEnabled) {
92-
if (_level != null) return _level;
93-
if (parent != null) return parent.level;
93+
Level effectiveLevel;
94+
95+
if (parent == null) {
96+
// We're either the root logger or a detached logger. Return our own
97+
// level.
98+
effectiveLevel = _level;
99+
} else if (!hierarchicalLoggingEnabled) {
100+
effectiveLevel = root._level;
101+
} else {
102+
effectiveLevel = _level ?? parent.level;
94103
}
95-
return root._level;
104+
105+
assert(effectiveLevel != null);
106+
return effectiveLevel;
96107
}
97108

98109
/// Override the level for this particular [Logger] and its children.
99110
set level(Level value) {
100-
if (hierarchicalLoggingEnabled && parent != null) {
101-
_level = value;
102-
} else {
103-
if (parent != null) {
104-
throw UnsupportedError(
105-
'Please set "hierarchicalLoggingEnabled" to true if you want to '
106-
'change the level on a non-root logger.');
107-
}
108-
root._level = value;
111+
if (!hierarchicalLoggingEnabled && parent != null) {
112+
throw UnsupportedError(
113+
'Please set "hierarchicalLoggingEnabled" to true if you want to '
114+
'change the level on a non-root logger.');
109115
}
116+
_level = value;
110117
}
111118

112119
/// Returns a stream of messages added to this [Logger].
@@ -174,14 +181,16 @@ class Logger {
174181
var record =
175182
LogRecord(logLevel, msg, fullName, error, stackTrace, zone, object);
176183

177-
if (hierarchicalLoggingEnabled) {
184+
if (parent == null) {
185+
_publish(record);
186+
} else if (!hierarchicalLoggingEnabled) {
187+
root._publish(record);
188+
} else {
178189
var target = this;
179190
while (target != null) {
180191
target._publish(record);
181192
target = target.parent;
182193
}
183-
} else {
184-
root._publish(record);
185194
}
186195
}
187196
}
@@ -234,7 +243,7 @@ class Logger {
234243
}
235244

236245
/// Top-level root [Logger].
237-
static final Logger root = Logger('').._level = defaultLevel;
246+
static final Logger root = Logger('');
238247

239248
/// All [Logger]s in the system.
240249
static final Map<String, Logger> _loggers = <String, Logger>{};

test/logging_test.dart

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import 'package:logging/logging.dart';
1010
import 'package:test/test.dart';
1111

1212
void main() {
13+
final hierarchicalLoggingEnabledDefault = hierarchicalLoggingEnabled;
14+
1315
test('level comparison is a valid comparator', () {
1416
var level1 = const Level('NOT_REAL1', 253);
1517
expect(level1 == level1, isTrue);
@@ -213,6 +215,11 @@ void main() {
213215
});
214216

215217
group('detached loggers', () {
218+
tearDown(() {
219+
hierarchicalLoggingEnabled = hierarchicalLoggingEnabledDefault;
220+
Logger.root.level = defaultLevel;
221+
});
222+
216223
test('create new instances of Logger', () {
217224
var a1 = Logger.detached('a');
218225
var a2 = Logger.detached('a');
@@ -232,6 +239,51 @@ void main() {
232239
var a = Logger.detached('a');
233240
expect(a.children, {});
234241
});
242+
243+
test('have levels independent of the root level', () {
244+
void testDetachedLoggerLevel(bool withHierarchy) {
245+
hierarchicalLoggingEnabled = withHierarchy;
246+
247+
const newRootLevel = Level.ALL;
248+
const newDetachedLevel = Level.OFF;
249+
250+
Logger.root.level = newRootLevel;
251+
252+
final detached = Logger.detached('a');
253+
expect(detached.level, defaultLevel);
254+
expect(Logger.root.level, newRootLevel);
255+
256+
detached.level = newDetachedLevel;
257+
expect(detached.level, newDetachedLevel);
258+
expect(Logger.root.level, newRootLevel);
259+
}
260+
261+
testDetachedLoggerLevel(false);
262+
testDetachedLoggerLevel(true);
263+
});
264+
265+
test('log messages regardless of hierarchy', () {
266+
void testDetachedLoggerOnRecord(bool withHierarchy) {
267+
var calls = 0;
268+
void handler(_) => calls += 1;
269+
270+
hierarchicalLoggingEnabled = withHierarchy;
271+
272+
final detached = Logger.detached('a');
273+
detached.level = Level.ALL;
274+
detached.onRecord.listen(handler);
275+
276+
Logger.root.info('foo');
277+
expect(calls, 0);
278+
279+
detached.info('foo');
280+
detached.info('foo');
281+
expect(calls, 2);
282+
}
283+
284+
testDetachedLoggerOnRecord(false);
285+
testDetachedLoggerOnRecord(true);
286+
});
235287
});
236288

237289
group('mutating levels', () {
@@ -294,6 +346,16 @@ void main() {
294346
expect(c.level, equals(Level.FINE));
295347
});
296348

349+
test('loggers effective level - with changing hierarchy', () {
350+
hierarchicalLoggingEnabled = true;
351+
d.level = Level.SHOUT;
352+
hierarchicalLoggingEnabled = false;
353+
354+
expect(root.level, Level.INFO);
355+
expect(d.level, root.level);
356+
expect(e.level, root.level);
357+
});
358+
297359
test('isLoggable is appropriate', () {
298360
hierarchicalLoggingEnabled = true;
299361
root.level = Level.SEVERE;

0 commit comments

Comments
 (0)