any_logger_email 1.1.2 copy "any_logger_email: ^1.1.2" to clipboard
any_logger_email: ^1.1.2 copied to clipboard

Email appender for any_logger with SMTP support, batching, HTML formatting, and rate limiting. Works with Gmail, Office 365, SendGrid, and more.

example/any_logger_email_example.dart

import 'package:any_logger/any_logger.dart';
import 'package:any_logger_email/any_logger_email.dart';

/// Example configurations for Email appender
///
/// These examples demonstrate various configuration options
/// without actually sending emails.
void main() async {
  // Ensure the EMAIL appender is registered
  AnyLoggerEmailExtension.register();

  print('Email Appender Configuration Examples\n');
  print('=' * 50);

  // Example 1: Basic configuration
  example1_basicConfig();

  // Example 2: Popular email services
  example2_emailServices();

  // Example 3: Advanced configuration
  example3_advanced();

  // Example 4: Using the builder pattern
  await example4_builder();

  // Example 5: Integration with LoggerFactory
  await example5_loggerFactory();

  print('\n' + '=' * 50);
  print('Examples completed (no actual emails sent)');
}

/// Example 1: Basic Email configuration
void example1_basicConfig() {
  print('\n### Example 1: Basic Configuration ###\n');

  final config = {
    'type': 'EMAIL',
    'smtpHost': 'smtp.example.com',
    'smtpPort': 587,
    'fromEmail': 'logger@example.com',
    'toEmails': ['admin@example.com', 'dev@example.com'],
    'username': 'logger@example.com',
    'password': 'secure_password',
    'level': 'ERROR',
    'batchSize': 50,
    'batchIntervalMinutes': 5,
  };

  print('Basic config:');
  config.forEach((key, value) {
    if (key == 'password') {
      print('  $key: ******');
    } else if (value is List) {
      print('  $key: ${(value).join(", ")}');
    } else {
      print('  $key: $value');
    }
  });

  // With SSL/TLS
  final sslConfig = {
    'type': 'EMAIL',
    'smtpHost': 'secure.mailserver.com',
    'smtpPort': 465,
    'ssl': true,
    'fromEmail': 'noreply@example.com',
    'fromName': 'App Logger',
    'toEmails': 'support@example.com', // Can be string or list
    'level': 'WARN',
  };

  print('\nSSL/TLS config:');
  sslConfig.forEach((key, value) => print('  $key: $value'));
}

/// Example 2: Popular email service configurations
void example2_emailServices() {
  print('\n### Example 2: Popular Email Services ###\n');

  // Gmail configuration
  final gmailConfig = {
    'type': 'EMAIL',
    'smtpHost': 'smtp.gmail.com',
    'smtpPort': 587,
    'ssl': false,
    'fromEmail': 'your.app@gmail.com',
    'toEmails': ['admin@example.com'],
    'username': 'your.app@gmail.com',
    'password': 'app-specific-password',
    // Use app password, not regular password
    'level': 'ERROR',
    'subjectPrefix': '[MyApp Error]',
  };

  print('Gmail config:');
  gmailConfig.forEach((key, value) {
    if (key == 'password') {
      print('  $key: ${value.toString().substring(0, 3)}...');
    } else {
      print('  $key: $value');
    }
  });

  // Office 365 configuration
  final office365Config = {
    'type': 'EMAIL',
    'smtpHost': 'smtp.office365.com',
    'smtpPort': 587,
    'ssl': false,
    'fromEmail': 'logger@company.com',
    'toEmails': ['it-team@company.com'],
    'username': 'logger@company.com',
    'password': 'secure_password',
    'level': 'ERROR',
  };

  print('\nOffice 365 config:');
  office365Config.forEach((key, value) {
    if (key == 'password') {
      print('  $key: ******');
    } else {
      print('  $key: $value');
    }
  });

  // SendGrid configuration
  final sendGridConfig = {
    'type': 'EMAIL',
    'smtpHost': 'smtp.sendgrid.net',
    'smtpPort': 587,
    'fromEmail': 'alerts@myapp.com',
    'toEmails': ['ops@myapp.com'],
    'username': 'apikey', // Always 'apikey' for SendGrid
    'password': 'SG.actual_api_key_here',
    'level': 'ERROR',
  };

  print('\nSendGrid config:');
  sendGridConfig.forEach((key, value) {
    if (key == 'password') {
      print('  $key: SG.***');
    } else {
      print('  $key: $value');
    }
  });
}

/// Example 3: Advanced configuration with all options
void example3_advanced() {
  print('\n### Example 3: Advanced Configuration ###\n');

  final advancedConfig = {
    'type': 'EMAIL',
    'smtpHost': 'mail.enterprise.com',
    'smtpPort': 587,
    'ssl': false,
    'allowInsecure': false,
    'ignoreBadCertificate': false,
    'fromEmail': 'monitoring@enterprise.com',
    'fromName': 'System Monitor',
    'toEmails': ['devops@enterprise.com', 'cto@enterprise.com'],
    'ccEmails': ['manager@enterprise.com'],
    'bccEmails': ['archive@enterprise.com'],
    'replyTo': 'support@enterprise.com',
    'username': 'monitoring@enterprise.com',
    'password': 'secure_password',
    'level': 'WARN',
    'subjectPrefix': '[PROD-ALERT]',
    'includeHostname': true,
    'includeAppInfo': true,
    'batchSize': 25,
    'batchIntervalMinutes': 10,
    'maxEmailsPerHour': 30,
    'sendAsHtml': true,
    'includeStackTrace': true,
    'includeMetadata': true,
    'groupByLevel': true,
    'sendImmediatelyOnError': true,
    'immediateErrorThreshold': 5,
  };

  print('Advanced configuration:');
  advancedConfig.forEach((key, value) {
    if (key == 'password') {
      print('  $key: ******');
    } else if (value is List) {
      print('  $key: ${(value).join(", ")}');
    } else {
      print('  $key: $value');
    }
  });

  // Configuration for daily digest
  final digestConfig = {
    'type': 'EMAIL',
    'smtpHost': 'smtp.example.com',
    'smtpPort': 587,
    'fromEmail': 'reports@example.com',
    'toEmails': ['management@example.com'],
    'level': 'INFO',
    'subjectPrefix': '[Daily Log Digest]',
    'batchSize': 1000,
    'batchIntervalMinutes': 1440, // 24 hours
    'sendImmediatelyOnError': false, // Collect all logs for digest
    'groupByLevel': true,
    'includeStackTrace': false, // Reduce size for digest
    'sendAsHtml': true,
  };

  print('\nDaily digest configuration:');
  digestConfig.forEach((key, value) {
    if (value is List) {
      print('  $key: ${(value).join(", ")}');
    } else {
      print('  $key: $value');
    }
  });
}

/// Example 4: Using the builder pattern
Future<void> example4_builder() async {
  print('\n### Example 4: Builder Pattern ###\n');

  // Create appender using builder (in test mode)
  final appender = await emailAppenderBuilder()
      .withSmtp('smtp.gmail.com', 587)
      .withCredentials('app@gmail.com', 'app-password')
      .withFrom('app@gmail.com', 'My App')
      .withTo(['admin@example.com', 'dev@example.com'])
      .withCc(['manager@example.com'])
      .withLevel(Level.ERROR)
      .withSubjectPrefix('[APP ERROR]')
      .withHtmlFormat(true)
      .withStackTraces(true)
      .withMetadata(true)
      .withGroupByLevel(true)
      .withImmediateErrors(true)
      .withErrorThreshold(3)
      .build(test: true);

  print('Built appender with:');
  print('  SMTP: ${appender.smtpHost}:${appender.smtpPort}');
  print('  From: ${appender.fromEmail}');
  print('  To: ${appender.toEmails.join(", ")}');
  print('  Level: ${appender.level}');
  print('  Batch interval: ${appender.batchInterval}');
  print('  HTML format: ${appender.sendAsHtml}');

  // Using presets
  final gmailAppender = await emailAppenderBuilder()
      .withGmailAppPassword('user@gmail.com', 'app-password')
      .withTo(['alerts@example.com'])
      .withCriticalAlertPreset()
      .build(test: true);

  print('\nGmail with critical alert preset:');
  print('  SMTP: ${gmailAppender.smtpHost}:${gmailAppender.smtpPort}');
  print('  Subject prefix: ${gmailAppender.subjectPrefix}');
  print('  Send immediately on error: ${gmailAppender.sendImmediatelyOnError}');

  await appender.dispose();
  await gmailAppender.dispose();
}

/// Example 5: Integration with LoggerFactory
Future<void> example5_loggerFactory() async {
  print('\n### Example 5: LoggerFactory Integration ###\n');

  // Configuration-based setup
  final config = {
    'appenders': [
      {
        'type': 'CONSOLE',
        'level': 'INFO',
        'format': '[%l] %m',
      },
      {
        'type': 'EMAIL',
        'smtpHost': 'smtp.example.com',
        'smtpPort': 587,
        'fromEmail': 'logger@example.com',
        'toEmails': ['admin@example.com'],
        'username': 'logger@example.com',
        'password': 'password',
        'level': 'ERROR',
        'batchSize': 10,
        'batchIntervalMinutes': 5,
        'sendAsHtml': true,
      }
    ]
  };

  print('LoggerFactory configuration:');
  final appenders = config['appenders'] as List<Map<String, dynamic>>;
  print('  Appenders: ${appenders.length}');
  for (var i = 0; i < appenders.length; i++) {
    final appender = appenders[i];
    print(
        '    ${i + 1}. Type: ${appender['type']}, Level: ${appender['level']}');
  }

  // Initialize in test mode to avoid actual email connections
  await LoggerFactory.init(config, test: true);

  // Get the logger and check appenders
  final logger = LoggerFactory.getRootLogger();
  print('\nLogger configured with ${logger.appenders.length} appenders:');
  for (var appender in logger.appenders) {
    print('  - ${appender.getType()} (Level: ${appender.level})');
  }

  // Clean up
  await LoggerFactory.dispose();

  // Builder-based setup with Gmail
  print('\nUsing LoggerBuilder with Gmail:');
  await LoggerFactory.builder()
      .replaceAll()
      .console(level: Level.INFO)
      .gmailWithAppPassword(
        fromEmail: 'app@gmail.com',
        appPassword: 'app-password',
        toEmails: ['alerts@example.com'],
        level: Level.WARN,
        subjectPrefix: '[MyApp]',
        rotationCycle: RotationCycle.HOURLY,
      )
      .build(test: true);

  final logger2 = LoggerFactory.getRootLogger();
  print('Builder created ${logger2.appenders.length} appenders');

  await LoggerFactory.dispose();

  // Using presets
  print('\nUsing production preset with email:');
  final prodConfig = EmailPresets.productionWithEmail(
    smtpHost: 'smtp.example.com',
    smtpPort: 587,
    fromEmail: 'prod@example.com',
    toEmails: ['ops@example.com'],
    username: 'prod@example.com',
    password: 'secure_password',
  );

  await LoggerFactory.init(prodConfig, test: true);
  final logger3 = LoggerFactory.getRootLogger();
  print('Production preset created ${logger3.appenders.length} appenders');

  await LoggerFactory.dispose();
}
0
likes
160
points
308
downloads

Publisher

verified publisherraoulsson.com

Weekly Downloads

Email appender for any_logger with SMTP support, batching, HTML formatting, and rate limiting. Works with Gmail, Office 365, SendGrid, and more.

Repository (GitHub)
View/report issues

Topics

#logging #email #smtp #alerts #monitoring

Documentation

API reference

Funding

Consider supporting this project:

github.com
www.buymeacoffee.com

License

MIT (license)

Dependencies

any_logger, mailer

More

Packages that depend on any_logger_email