structured_log 0.2.0-dev.0+1 copy "structured_log: ^0.2.0-dev.0+1" to clipboard
structured_log: ^0.2.0-dev.0+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';

Future<void> main() async {
  // 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

  // trace() sits below the default minLevel (debug), so a sink needs to
  // opt in explicitly to receive it -- no category tagging required.
  StructlogConfiguration.configure(sinks: [
    LogSink(name: 'console', output: coloredConsoleOutput),
    LogSink(
      name: 'trace',
      output: fileOutput('logs/trace.log'),
      minLevel: LogLevel.trace,
    ),
  ]);

  final traceLog = getLogger();
  traceLog.info('handled_request'); // console + trace.log
  traceLog.trace('raw_frame', context: {'bytes': 128}); // trace.log only

  // Async file output: does not block the calling isolate. Keep a
  // reference to the instance so you can await flushed before exit.
  final asyncOutput = AsyncFileOutput('logs/async.log');
  StructlogConfiguration.configure(output: asyncOutput);

  final asyncLog = getLogger();
  asyncLog.info('async_event_1');
  asyncLog.info('async_event_2');
  await asyncOutput.flushed;

  print('logs/async.log after flush:');
  print(File('logs/async.log').readAsStringSync());
}
0
likes
0
points
273
downloads

Publisher

unverified uploader

Weekly Downloads

Structured logging for Dart, inspired by Python's structlog. Log JSON with context binding.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

meta

More

Packages that depend on structured_log