structured_log 0.2.0-dev.1
structured_log: ^0.2.0-dev.1 copied to clipboard
Structured logging for Dart, inspired by Python's structlog. Log JSON with context binding.
example/main.dart
import 'dart:io';
import 'package:structured_log/structured_log.dart';
void main() {
// Basic usage
final log = getLogger();
log.info('user_login', context: {'user_id': 42, 'ip': '127.0.0.1'});
// With bound context
final boundLog = getLogger().bind({'request_id': 'abc-123'});
boundLog.info('processing_request');
boundLog.warning('slow_query', context: {'duration_ms': 1500});
// Chaining bind
final userLog = boundLog.bind({'user_id': 42});
userLog.info('user_action', context: {'action': 'purchase'});
userLog.error('payment_failed', context: {'error': 'timeout'});
// File output
StructlogConfiguration.configure(
output: fileOutput('logs/app.log'),
);
final fileLog = getLogger();
fileLog.info('logged to file');
fileLog.error('error in file');
print('Logs written to logs/app.log');
print(File('logs/app.log').readAsStringSync());
// Rotating file output
StructlogConfiguration.configure(
output: rotatingFileOutput('logs/rotating.log', maxSizeBytes: 1024),
);
final rotatingLog = getLogger();
for (var i = 0; i < 100; i++) {
rotatingLog.info('iteration', context: {'i': i});
}
print('Rotating logs:');
print('logs/rotating.log exists: ${File('logs/rotating.log').existsSync()}');
print(
'logs/rotating.log.0 exists: ${File('logs/rotating.log.0').existsSync()}');
// Typed correlation fields
StructlogConfiguration.reset();
final correlatedLog = getLogger().withCorrelation(
sessionId: 's-14',
requestId: 'r-42',
connectionGeneration: 8,
);
correlatedLog.info('processing_request');
// Child scope: inherits sessionId/requestId, adds toolCallId
final toolLog = correlatedLog.withCorrelation(toolCallId: 'tc-3');
toolLog.info('tool_invoked');
// Multi-sink routing: console gets everything, a dedicated file only
// gets entries tagged with the 'protocol' category.
StructlogConfiguration.configure(sinks: [
LogSink(name: 'console', output: coloredConsoleOutput),
LogSink(
name: 'protocol',
output: fileOutput('logs/protocol.log'),
categories: {'protocol'},
),
]);
final routedLog = getLogger();
routedLog.info('app_event'); // console only
routedLog.debug('raw_frame',
context: {'category': 'protocol'}); // console + protocol.log
// Toggle the protocol sink off at runtime without rebuilding the logger.
StructlogConfiguration.setSinkEnabled('protocol', enabled: false);
routedLog
.debug('raw_frame_2', context: {'category': 'protocol'}); // console only
}