Quick start
This guide covers the minimum flow: create the logger, register sinks, and emit an event.
1. Create the logger
final logger = StructureLogger();
2. Register sinks
Sinks define where logs go. For local development, combine readable terminal output with the Dart developer log:
logger.addSink(SimpleLineSink());
logger.addSink(DefaultSink());
3. Emit a log
await logger.log(
'Welcome {name}, your level is {level}',
level: LogLevel.info,
data: {'name': 'John Doe', 'level': 12},
);
What happens
StructureLoggerbuilds aLogModelwith an ISO-8601 timestamp, template, level, anddata.- Each registered sink receives the same event via
write(LogModel). SimpleLineSinkinterpolates placeholders and prints a readable line.DefaultSinkserializes the CLEF map and sends it todart:developer.
Expected output
Welcome John Doe, your level is 12
[log] {@t: 2026-06-25T10:00:00.000, @mt: Welcome {name}, your level is {level}, @l: info, data: {name: John Doe, level: 12}}
Full example
import 'package:flutter/widgets.dart';
import 'package:structured_logger/structured_logger.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final logger = StructureLogger();
logger.addSink(SimpleLineSink());
logger.addSink(DefaultSink());
await logger.log(
'Welcome {name}, your level is {level}',
level: LogLevel.info,
data: {'name': 'John Doe', 'level': 12},
);
}
Next step
- Sinks — understand each destination
- Seq integration — send logs to production