any_logger_email 1.0.5 copy "any_logger_email: ^1.0.5" to clipboard
any_logger_email: ^1.0.5 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.

Any Logger Email #

An email appender extension for Any Logger that enables sending log notifications via SMTP to any email address. Perfect for critical error alerts, daily digests, system monitoring, and production incident notifications.

Features #

  • Universal SMTP Support - Works with any SMTP server including Gmail, Office 365, SendGrid, and more
  • Smart Batching - Automatically batches logs to reduce email volume
  • Rate Limiting - Prevents email flooding with configurable limits
  • HTML & Plain Text - Beautiful HTML emails with fallback to plain text
  • Priority Alerts - Immediate sending for critical errors
  • Multiple Recipients - Support for TO, CC, and BCC recipients
  • Flexible Templates - Customizable email templates or use built-in formats
  • Service Presets - Pre-configured settings for popular email services

Installation #

dependencies:
  any_logger: ^x.y.z
  any_logger_email: ^x.y.z  // See Installing

To register the EMAIL appender you have to import the library

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

and call:

AnyLoggerEmailExtension.register();

Quick Start #

Simple Setup with Gmail #

await LoggerFactory.builder()
    .console(level: Level.INFO)
    .gmail(
      username: '[email protected]',
      appPassword: 'your-app-password', // Use App Password, not regular password
      toEmails: ['[email protected]'],
      level: Level.ERROR,
    )
    .build();

Logger.info('This only goes to console');
Logger.error('This triggers an email alert!');

Custom SMTP Server #

await LoggerFactory.builder()
    .email(
      smtpHost: 'smtp.company.com',
      smtpPort: 587,
      fromEmail: '[email protected]',
      toEmails: ['[email protected]'],
      username: '[email protected]',
      password: 'secure_password',
      level: Level.ERROR,
      sendAsHtml: true,
    )
    .build();

Email Service Configuration #

Gmail #

final appender = await emailAppenderBuilder()
    .withGmailPreset('[email protected]', 'app-password')
    .withTo(['[email protected]'])
    .withLevel(Level.ERROR)
    .build();

Important: Use an App Password for Gmail, not your regular password.

Office 365 / Outlook #

final appender = await emailAppenderBuilder()
    .withOffice365Preset('[email protected]', 'password')
    .withTo(['[email protected]'])
    .withLevel(Level.ERROR)
    .build();

SendGrid #

final appender = await emailAppenderBuilder()
    .withSendGridPreset('your-sendgrid-api-key')
    .withFrom('[email protected]')
    .withTo(['[email protected]'])
    .build();

Custom SMTP #

final appender = await emailAppenderBuilder()
    .withSmtp('mail.server.com', 465, ssl: true)
    .withCredentials('username', 'password')
    .withFrom('[email protected]', 'System Logger')
    .withTo(['[email protected]'])
    .build();

Configuration Options #

Using Builder Pattern #

final appender = await emailAppenderBuilder()
    .withSmtp('smtp.example.com', 587)
    .withCredentials('user', 'pass')
    .withFrom('[email protected]', 'My App')
    .withTo(['[email protected]', '[email protected]'])
    .withCc(['[email protected]'])
    .withBcc(['[email protected]'])
    .withReplyTo('[email protected]')
    .withSubjectPrefix('[PRODUCTION]')
    .withLevel(Level.ERROR)
    .withBatchSize(10)
    .withBatchIntervalMinutes(5)
    .withRateLimit(20) // Max 20 emails per hour
    .withHtmlFormat(true)
    .withStackTraces(true)
    .withMetadata(true)
    .withGroupByLevel(true)
    .withImmediateErrors(true)
    .withErrorThreshold(3)
    .build();

Using Configuration Map #

final config = {
  'appenders': [
    {
      'type': 'EMAIL',
      'smtpHost': 'smtp.example.com',
      'smtpPort': 587,
      'ssl': false,
      'fromEmail': '[email protected]',
      'fromName': 'App Logger',
      'toEmails': ['[email protected]', '[email protected]'],
      'ccEmails': ['[email protected]'],
      'username': '[email protected]',
      'password': 'secure_password',
      'level': 'ERROR',
      'subjectPrefix': '[APP ERROR]',
      'batchSize': 25,
      'batchIntervalMinutes': 10,
      'maxEmailsPerHour': 30,
      'sendAsHtml': true,
      'includeStackTrace': true,
      'includeMetadata': true,
      'groupByLevel': true,
      'sendImmediatelyOnError': true,
      'immediateErrorThreshold': 5,
    }
  ]
};

await LoggerFactory.init(config);

Configuration Parameters #

Parameter Type Default Description
smtpHost String Required SMTP server hostname
smtpPort int Required SMTP server port (25, 465, 587, etc.)
ssl bool false Use SSL/TLS encryption
allowInsecure bool false Allow insecure connections
ignoreBadCertificate bool false Ignore certificate errors
fromEmail String Required Sender email address
fromName String null Sender display name
toEmails List/String Required Recipient email(s)
ccEmails List/String [] CC recipients
bccEmails List/String [] BCC recipients
replyTo String null Reply-to address
username String null SMTP username
password String null SMTP password
level Level ERROR Minimum log level to email
subjectPrefix String '[LOG]' Email subject prefix
includeHostname bool true Include hostname in emails
includeAppInfo bool true Include app version/device ID
batchSize int 50 Logs per batch
batchIntervalMinutes int 5 Minutes before sending partial batch
maxEmailsPerHour int 20 Rate limit per hour
sendAsHtml bool true Send HTML formatted emails
includeStackTrace bool true Include stack traces
includeMetadata bool true Include metadata
groupByLevel bool true Group logs by level in email
sendImmediatelyOnError bool true Send immediately on errors
immediateErrorThreshold int 10 Error count to trigger immediate send

Email Format Examples #

HTML Email (Default) #

The appender sends beautifully formatted HTML emails with:

  • Color-coded log levels
  • Grouped sections by severity
  • Syntax-highlighted stack traces
  • Metadata header with system info
  • Responsive design for mobile

Plain Text Email #

For systems that require plain text:

.withHtmlFormat(false)

Produces clean, readable plain text emails with proper formatting.

Presets #

Critical Alert Preset #

final appender = await emailAppenderBuilder()
    .withSmtp('smtp.example.com', 587)
    .withFrom('[email protected]')
    .withTo(['[email protected]'])
    .withCriticalAlertPreset()
    .build();

// Configures:
// - Level: ERROR
// - Batch size: 5
// - Interval: 1 minute
// - Immediate sending on first error
// - Include full stack traces
// - Subject: [CRITICAL ALERT]

Daily Digest Preset #

final appender = await emailAppenderBuilder()
    .withSmtp('smtp.example.com', 587)
    .withFrom('[email protected]')
    .withTo(['[email protected]'])
    .withDailyDigestPreset()
    .build();

// Configures:
// - Level: INFO
// - Batch size: 1000
// - Interval: 24 hours
// - No immediate sending
// - Group by level
// - No stack traces (summary only)

Development Preset #

final appender = await emailAppenderBuilder()
    .withSmtp('smtp.example.com', 587)
    .withFrom('[email protected]')
    .withTo(['[email protected]'])
    .withDevelopmentPreset()
    .build();

// Configures:
// - Level: DEBUG
// - Batch size: 20
// - Interval: 5 minutes
// - Include everything for debugging

Use Cases #

Production Error Monitoring #

await LoggerFactory.builder()
    .file(filePattern: 'app', level: Level.INFO) // Log everything to file
    .email(
      smtpHost: 'smtp.sendgrid.net',
      smtpPort: 587,
      fromEmail: '[email protected]',
      toEmails: ['[email protected]'],
      username: 'apikey',
      password: process.env['SENDGRID_API_KEY'],
      level: Level.ERROR,
      subjectPrefix: '[PROD ERROR]',
      batchSize: 5,
      sendImmediatelyOnError: true,
    )
    .build();

Daily Summary Reports #

await LoggerFactory.builder()
    .console(level: Level.INFO)
    .email(
      smtpHost: 'smtp.gmail.com',
      smtpPort: 587,
      fromEmail: '[email protected]',
      toEmails: ['[email protected]'],
      username: '[email protected]',
      password: 'app-password',
      level: Level.INFO,
      subjectPrefix: '[Daily Report]',
      batchSize: 1000,
      batchIntervalMinutes: 1440, // 24 hours
      sendImmediatelyOnError: false,
      groupByLevel: true,
      includeStackTrace: false,
    )
    .build();

Critical System Alerts #

// Send to multiple channels for critical issues
await LoggerFactory.builder()
    .email(
      smtpHost: 'smtp.example.com',
      smtpPort: 587,
      fromEmail: '[email protected]',
      toEmails: [
        '[email protected]',
        '[email protected]', // SMS via email gateway
      ],
      level: Level.ERROR,
      subjectPrefix: '🚨 CRITICAL',
      batchSize: 1, // Send immediately
      maxEmailsPerHour: 100, // Allow more for critical
    )
    .build();

Development Debugging #

await LoggerFactory.builder()
    .console(level: Level.DEBUG)
    .gmail(
      username: '[email protected]',
      appPassword: 'app-password',
      toEmails: ['[email protected]'],
      level: Level.ERROR,
      subjectPrefix: '[DEV ERROR]',
      sendAsHtml: true,
      includeStackTrace: true,
    )
    .build();

Best Practices #

1. Use App Passwords #

For Gmail and other services with 2FA, always use app-specific passwords:

2. Configure Rate Limits #

Prevent email flooding:

.withRateLimit(20) // Max 20 emails per hour
.withBatchSize(50) // Batch up to 50 logs
.withBatchIntervalMinutes(10) // Send every 10 minutes

3. Set Appropriate Thresholds #

// For critical systems
.withLevel(Level.ERROR)
.withImmediateErrors(true)
.withErrorThreshold(1) // Send on first error

// For development
.withLevel(Level.WARN)
.withErrorThreshold(10) // Batch warnings

4. Use Different Recipients for Different Levels #

// Critical errors to on-call
await LoggerFactory.builder()
    .email(
      // ... config
      toEmails: ['[email protected]'],
      level: Level.ERROR,
      subjectPrefix: '[CRITICAL]',
    )
    // Daily digest to management
    .email(
      // ... config
      toEmails: ['[email protected]'],
      level: Level.INFO,
      subjectPrefix: '[DAILY]',
      batchIntervalMinutes: 1440,
    )
    .build();

5. Include Context in Subject #

final hostname = Platform.localHostname;
.withSubjectPrefix('[$hostname ERROR]')

Troubleshooting #

Emails Not Being Sent #

  1. Check SMTP credentials: Verify username/password are correct
  2. Check firewall: Ensure SMTP ports (25, 465, 587) are open
  3. Enable less secure apps: Some providers require this setting
  4. Use app passwords: For accounts with 2FA enabled
  5. Check rate limits: You may have hit the hourly limit
  6. Enable self-debugging:
await LoggerFactory.builder()
    .email(/* config */)
    .withSelfDebug(Level.DEBUG)
    .build();

Gmail Specific Issues #

  • Enable "Less secure app access" or use App Passwords
  • Use port 587 (not 465) for TLS
  • Ensure 2-factor authentication is properly configured

SSL/TLS Issues #

// For self-signed certificates
.withSmtp('smtp.internal.com', 465, 
    ssl: true, 
    ignoreBadCertificate: true)

High Memory Usage #

  • Reduce batchSize to limit memory usage
  • Increase batchIntervalMinutes for less frequent sends
  • Disable includeStackTrace for large volumes

Testing #

For unit tests, use test mode to avoid sending actual emails:

final appender = await emailAppenderBuilder()
    .withSmtp('smtp.test.com', 587)
    .withFrom('[email protected]')
    .withTo(['[email protected]'])
    .build(test: true); // No emails will be sent

Security Considerations #

  1. Never commit credentials: Use environment variables or secure vaults
  2. Use encrypted connections: Enable SSL/TLS when possible
  3. Rotate passwords regularly: Especially for production systems
  4. Limit recipient lists: Avoid exposing email addresses unnecessarily
  5. Sanitize log content: Be careful with sensitive data in logs

License #

MIT License - see LICENSE file for details.

Support #


Part of the Any Logger ecosystem.

💚 Funding #


Happy Logging! 🎉

0
likes
0
points
20
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

Funding

Consider supporting this project:

github.com
www.buymeacoffee.com

License

unknown (license)

Dependencies

any_logger, mailer

More

Packages that depend on any_logger_email