contextual 1.2.0 copy "contextual: ^1.2.0" to clipboard
contextual: ^1.2.0 copied to clipboard

A structured logging library for Dart with support for multiple output channels, customizable formatting, context management, and middleware processing.

example/contextual_example.dart

import 'dart:convert';

import 'package:contextual/contextual.dart';

/// Middleware that blocks sensitive logs containing passwords
class BlockSensitiveLogsMiddleware implements DriverMiddleware {
  @override
  DriverMiddlewareResult handle(String driverName, LogEntry entry) {
    if (entry.message.contains('password')) {
      print('[Middleware] Sensitive log detected. Blocking log.');
      return DriverMiddlewareResult.stop();
    }
    return DriverMiddlewareResult.proceed();
  }
}

/// Middleware that adds a specific tag for driver-targeted messages
class AddTagMiddleware implements DriverMiddleware {
  final String tag;

  AddTagMiddleware(this.tag);

  @override
  DriverMiddlewareResult handle(String driverName, LogEntry entry) {
    final modifiedMessage = '${entry.message} [$tag for $driverName]';

    // Create a new LogEntry with the modified message
    final modifiedEntry = entry.copyWith(message: modifiedMessage);

    return DriverMiddlewareResult.modify(modifiedEntry);
  }
}

/// Middleware to dynamically enrich logs with user information
class AddUserMiddleware implements DriverMiddleware {
  final String username;

  AddUserMiddleware(this.username);

  @override
  DriverMiddlewareResult handle(String driverName, LogEntry entry) {
    return DriverMiddlewareResult.modify(
        entry.copyWith(message: '${entry.message} | User: $username'));
  }
}

/// Formatter for structured data (JSON-style)
class StructuredMapFormatter extends LogTypeFormatter<Map<String, dynamic>> {
  @override
  String format(Level level, Map<String, dynamic> message, Context context) {
    final logData = {
      'level': level.toUpperCase(),
      'data': message,
      'context': context.all(),
      'timestamp': DateTime.now().toIso8601String(),
    };
    return jsonEncode(logData);
  }
}

/// Formatter for exceptions
class ExceptionLogFormatter extends LogTypeFormatter<Exception> {
  @override
  String format(Level level, Exception exception, Context context) {
    return '[${level.toUpperCase()}] Exception: ${exception.toString()} at ${DateTime.now()} | Context: ${context.all()}';
  }
}

void main() async {
  // Configuration for multiple logging channels
  final logConfig = LogConfig(
    defaults: {'env': 'production'},
    channels: {
      'console': ChannelConfig(driver: 'console'),
      'file': ChannelConfig(
        driver: 'daily',
        config: {
          'path': 'logs/app.log',
          'days': 7,
        },
      ),
      'webhook': ChannelConfig(
        driver: 'webhook',
        config: {
          'webhookUrl':
              'https://webhook-test.com/b61f3ee766b6354bb67881df60708333',
          'username': 'LoggerBot',
          'emoji': ':robot:',
        },
      ),
    },
  );

  // Initialize LogManager with fluent configuration
  final logManager = Logger()
      .config(logConfig)
      .environment('production')
      .formatter(PrettyLogFormatter()) // JSON format for logs
      .addMiddleware(() =>
          {'app': 'MyApp', 'version': '1.2.0'}) // Global context middleware
      .addLogMiddleware(
          BlockSensitiveLogsMiddleware()) // Global sensitive log blocker
      .addLogMiddleware(AddUserMiddleware('john_doe')) // Enrich logs with user
      .addDriverMiddleware('console',
          AddTagMiddleware('DEBUG-CONSOLE')) // Add console-specific tags
      .addTypeFormatter<Map<String, dynamic>>(
          StructuredMapFormatter()) // JSON structure formatter
      .addTypeFormatter<Exception>(
          ExceptionLogFormatter()); // Exception formatter

  // Example 1: Logging simple messages
  logManager.info('Application started successfully.');
  // logManager.error('An unexpected error occurred during execution.');

  // // Example 2: Structured data logging
  logManager.info({
    'event': 'login',
    'user': 'john_doe',
    'status': 'success',
  });

  // Example 3: Logging an exception
  try {
    throw Exception('Database connection failed');
  } catch (e) {
    logManager.error(e);
  }

  // Example 4: Logging to specific channels (console and file)
  logManager
      .to(['console', 'file']).critical('Critical system failure detected!');

  // Example 5: Dynamic on-demand channel configuration
  final customChannel = logManager.buildChannel({
    'driver': 'daily',
    'path': 'logs/custom.log',
    'days': 5,
  });

  logManager.addChannel('custom', customChannel);
  logManager.to(['custom']).warning('Custom log channel warning.');

  // Example 6: Adding shared context and logging
  logManager
      .withContext({'requestId': 'abcd1234', 'operation': 'user-update'}).info(
          'User details updated successfully.');

  // Example 7: Logging stack configuration (console + webhook)
  logManager.to(['console', 'webhook']).alert('System is under heavy load.');

  // Shutdown to flush logs
  await logManager.shutdown();
  print("something");
}
copied to clipboard
7
likes
160
points
44
downloads

Publisher

verified publisherglenfordwilliams.com

Weekly Downloads

2024.09.26 - 2025.04.10

A structured logging library for Dart with support for multiple output channels, customizable formatting, context management, and middleware processing.

Repository (GitHub)
View/report issues

Topics

#logging

Documentation

API reference

Funding

Consider supporting this project:

www.buymeacoffee.com

License

MIT (license)

Dependencies

ansicolor, gato, intl, universal_io

More

Packages that depend on contextual