Skip to content

Commit b123cf1

Browse files
tkutcherhaarts
authored andcommitted
Add PrefixPrinter and HybridPrinter decorators.
1 parent 0958b53 commit b123cf1

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed

lib/logger.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export 'src/outputs/memory_output.dart';
1313
export 'src/printers/pretty_printer.dart';
1414
export 'src/printers/logfmt_printer.dart';
1515
export 'src/printers/simple_printer.dart';
16+
export 'src/printers/hybrid_printer.dart';
17+
export 'src/printers/prefix_printer.dart';
1618

1719
export 'src/log_output.dart'
1820
if (dart.library.io) 'src/outputs/file_output.dart';
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import 'package:logger/logger.dart';
2+
import 'package:logger/src/logger.dart';
3+
import 'package:logger/src/log_printer.dart';
4+
5+
/// A decorator for a [LogPrinter] that allows for the composition of
6+
/// different printers to handle different log messages. Provide it's
7+
/// constructor with a base printer, but include named parameters for
8+
/// any levels that have a different printer:
9+
///
10+
/// ```
11+
/// HybridPrinter(PrettyPrinter(), debug: SimplePrinter());
12+
/// ```
13+
///
14+
/// Will use the pretty printer for all logs except Level.debug
15+
/// logs, which will use SimplePrinter().
16+
class HybridPrinter extends LogPrinter {
17+
final LogPrinter _realPrinter;
18+
var _printerMap;
19+
20+
HybridPrinter(this._realPrinter,
21+
{debug, verbose, wtf, info, warning, error}) {
22+
_printerMap = {
23+
Level.debug: debug ?? _realPrinter,
24+
Level.verbose: verbose ?? _realPrinter,
25+
Level.wtf: wtf ?? _realPrinter,
26+
Level.info: info ?? _realPrinter,
27+
Level.warning: warning ?? _realPrinter,
28+
Level.error: error ?? _realPrinter,
29+
};
30+
}
31+
32+
@override
33+
List<String> log(LogEvent event) => _printerMap[event.level].log(event);
34+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import 'package:logger/src/logger.dart';
2+
import 'package:logger/src/log_printer.dart';
3+
4+
/// A decorator for a [LogPrinter] that allows for the prepending of every
5+
/// line in the log output with a string for the level of that log. For
6+
/// example:
7+
///
8+
/// ```
9+
/// PrefixPrinter(PrettyPrinter());
10+
/// ```
11+
///
12+
/// Would prepend "DEBUG" to every line in a debug log. You can supply
13+
/// parameters for a custom message for a specific log level.
14+
class PrefixPrinter extends LogPrinter {
15+
final LogPrinter _realPrinter;
16+
Map<Level, String> _prefixMap;
17+
18+
PrefixPrinter(this._realPrinter,
19+
{debug, verbose, wtf, info, warning, error}) {
20+
_prefixMap = {
21+
Level.debug: debug ?? 'DEBUG',
22+
Level.verbose: verbose ?? 'VERBOSE',
23+
Level.wtf: wtf ?? 'WTF',
24+
Level.info: info ?? 'INFO',
25+
Level.warning: warning ?? 'WARNING',
26+
Level.error: error ?? 'ERROR',
27+
};
28+
29+
var len = _longestPrefixLength();
30+
_prefixMap.forEach((k, v) => _prefixMap[k] = '${v.padLeft(len)} ');
31+
}
32+
33+
@override
34+
List<String> log(LogEvent event) {
35+
var realLogs = _realPrinter.log(event);
36+
return realLogs.map((s) => '${_prefixMap[event.level]}$s').toList();
37+
}
38+
39+
int _longestPrefixLength() {
40+
var compFunc = (String a, String b) => a.length > b.length ? a : b;
41+
return _prefixMap.values.reduce(compFunc).length;
42+
}
43+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import 'package:test/test.dart';
2+
3+
import 'package:logger/src/printers/hybrid_printer.dart';
4+
import 'package:logger/logger.dart';
5+
6+
final realPrinter = SimplePrinter();
7+
8+
class TestLogPrinter extends LogPrinter {
9+
LogEvent latestEvent;
10+
@override
11+
List<String> log(LogEvent event) {
12+
latestEvent = event;
13+
return realPrinter.log(event);
14+
}
15+
}
16+
17+
void main() {
18+
var printerA = TestLogPrinter();
19+
var printerB = TestLogPrinter();
20+
var printerC = TestLogPrinter();
21+
22+
var debugEvent = LogEvent(Level.debug, 'debug', 'blah', StackTrace.current);
23+
var infoEvent = LogEvent(Level.info, 'info', 'blah', StackTrace.current);
24+
var warningEvent =
25+
LogEvent(Level.warning, 'warning', 'blah', StackTrace.current);
26+
var errorEvent = LogEvent(Level.error, 'error', 'blah', StackTrace.current);
27+
28+
var hybridPrinter = HybridPrinter(printerA, debug: printerB, error: printerC);
29+
test('uses wrapped printer by default', () {
30+
hybridPrinter.log(infoEvent);
31+
expect(printerA.latestEvent, equals(infoEvent));
32+
});
33+
34+
test('forwards logs to correct logger', () {
35+
hybridPrinter.log(debugEvent);
36+
hybridPrinter.log(errorEvent);
37+
hybridPrinter.log(warningEvent);
38+
expect(printerA.latestEvent, equals(warningEvent));
39+
expect(printerB.latestEvent, equals(debugEvent));
40+
expect(printerC.latestEvent, equals(errorEvent));
41+
});
42+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import 'package:logger/src/printers/prefix_printer.dart';
2+
import 'package:test/test.dart';
3+
4+
import 'package:logger/logger.dart';
5+
6+
void main() {
7+
var debugEvent = LogEvent(Level.debug, 'debug', 'blah', StackTrace.current);
8+
var infoEvent = LogEvent(Level.info, 'info', 'blah', StackTrace.current);
9+
var warningEvent =
10+
LogEvent(Level.warning, 'warning', 'blah', StackTrace.current);
11+
var errorEvent = LogEvent(Level.error, 'debug', 'blah', StackTrace.current);
12+
var verboseEvent =
13+
LogEvent(Level.verbose, 'debug', 'blah', StackTrace.current);
14+
var wtfEvent = LogEvent(Level.wtf, 'debug', 'blah', StackTrace.current);
15+
16+
var allEvents = [
17+
debugEvent,
18+
warningEvent,
19+
errorEvent,
20+
verboseEvent,
21+
wtfEvent
22+
];
23+
24+
test('prefixes logs', () {
25+
var printer = PrefixPrinter(PrettyPrinter());
26+
var actualLog = printer.log(infoEvent);
27+
actualLog.forEach((logString) {
28+
expect(logString, contains('INFO'));
29+
});
30+
31+
var debugLog = printer.log(debugEvent);
32+
debugLog.forEach((logString) {
33+
expect(logString, contains('DEBUG'));
34+
});
35+
});
36+
37+
test('can supply own prefixes', () {
38+
var printer = PrefixPrinter(PrettyPrinter(), debug: 'BLAH');
39+
var actualLog = printer.log(debugEvent);
40+
actualLog.forEach((logString) {
41+
expect(logString, contains('BLAH'));
42+
});
43+
});
44+
45+
test('pads to same length', () {
46+
const longPrefix = 'EXTRALONGPREFIX';
47+
const len = longPrefix.length;
48+
var printer = PrefixPrinter(SimplePrinter(), debug: longPrefix);
49+
for (var event in allEvents) {
50+
var l1 = printer.log(event);
51+
l1.forEach((logString) {
52+
expect(logString.substring(0, len), isNot(contains('[')));
53+
});
54+
}
55+
});
56+
}

0 commit comments

Comments
 (0)