sink_logger 0.1.0
sink_logger: ^0.1.0 copied to clipboard
One log() call fans out to the developer console, a bounded exportable buffer and a broadcast event stream, each with its own message.
example/sink_logger_example.dart
import 'dart:io';
import 'package:sink_logger/sink_logger.dart';
Future<void> main() async {
// The whole setup, once per isolate entry point. The console sink keeps its
// default — dart:developer's log, which a Flutter app or an attached
// DevTools surfaces and a plain `dart run` stays quiet about.
configureLogger(const LoggerConfig(tagPrefix: 'App'));
// Stands in for a crash reporter. It may ship publishableMessage and
// nothing else; an empty one means the entry never leaves the device.
final forwarder = LogBuffer.instance.events.listen((event) {
final text = event.publishableMessage;
if (text.isEmpty) return;
stdout.writeln('off-device: $text');
});
log('starting up', name: 'Boot');
// One call, three different texts: the console gets the raw token, the
// buffer keeps a trimmed line, the forwarder publishes only the outcome.
log(
'auth token=super-secret-value',
name: 'AuthRepo',
bufferedMessage: 'auth token=<redacted>',
sanitizedMessage: 'auth token acquired',
);
// An empty sanitizedMessage keeps the body off the wire, while the export
// still has it for a bug report.
log('response body: {"id":1}', name: 'Http', sanitizedMessage: '');
// Subscribers are notified in a later microtask, so let them run before
// tearing the subscription down.
await Future<void>.delayed(Duration.zero);
await forwarder.cancel();
stdout
..writeln('\nwhat export() hands to a bug report:')
..writeln(LogBuffer.instance.export(header: 'sink_logger example'));
}