contextual 1.1.0 copy "contextual: ^1.1.0" to clipboard
contextual: ^1.1.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';
import 'package:contextual/src/types.dart';

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

/// 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.value} [$tag for $driverName]';
    return DriverMiddlewareResult.modify(MapEntry(entry.key, modifiedMessage));
  }
}

/// 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) {
    final enrichedMessage = '${entry.value} | User: $username';
    return DriverMiddlewareResult.modify(MapEntry(entry.key, enrichedMessage));
  }
}

/// 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', path: 'logs/app.log', days: 7),
      'webhook': ChannelConfig(
        driver: 'webhook',
        webhookUrl: Uri.parse(
            '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
150
points
34
downloads

Publisher

verified publisherglenfordwilliams.com

Weekly Downloads

2024.10.08 - 2025.04.22

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

Homepage
Repository (GitHub)
View/report issues

Topics

#logging

Documentation

API reference

License

MIT (license)

Dependencies

ansicolor, intl, universal_io

More

Packages that depend on contextual