# Email Log Under Tools

> Keeps a list of the last 100 emails the site tried to send (date, recipient, subject and whether it failed) and shows it under Tools > Email Log.

- Type: PHP
- Runs: Run everywhere
- Category: [Email](https://wpide.com/library/category/email/)
- Tags: email, logging, debugging, admin
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/email-activity-log/

## Code

```php
$wpide_email_log_max = 100; // Entries to keep.

add_filter( 'wp_mail', function ( $atts ) use ( $wpide_email_log_max ) {
    $log = get_option( 'wpide_email_log', array() );
    $log = is_array( $log ) ? $log : array();

    array_unshift( $log, array(
        'time'    => time(),
        'to'      => implode( ', ', (array) $atts['to'] ),
        'subject' => wp_strip_all_tags( (string) $atts['subject'] ),
        'status'  => 'sent',
    ) );

    update_option( 'wpide_email_log', array_slice( $log, 0, $wpide_email_log_max ), false );

    return $atts;
}, 999 );

add_action( 'wp_mail_failed', function ( $error ) {
    $log = get_option( 'wpide_email_log', array() );

    if ( is_array( $log ) && isset( $log[0] ) ) {
        $log[0]['status'] = 'failed: ' . $error->get_error_message();
        update_option( 'wpide_email_log', $log, false );
    }
} );

add_action( 'admin_menu', function () {
    add_management_page( 'Email Log', 'Email Log', 'manage_options', 'wpide-email-log', function () {
        $log = get_option( 'wpide_email_log', array() );

        echo '<div class="wrap"><h1>Email Log</h1>';
        echo '<table class="widefat striped"><thead><tr><th>Date</th><th>To</th><th>Subject</th><th>Status</th></tr></thead><tbody>';

        if ( empty( $log ) ) {
            echo '<tr><td colspan="4">No emails logged yet.</td></tr>';
        }

        foreach ( (array) $log as $row ) {
            printf(
                '<tr><td>%1$s</td><td>%2$s</td><td>%3$s</td><td>%4$s</td></tr>',
                esc_html( wp_date( 'Y-m-d H:i:s', (int) $row['time'] ) ),
                esc_html( $row['to'] ),
                esc_html( $row['subject'] ),
                esc_html( $row['status'] )
            );
        }

        echo '</tbody></table></div>';
    } );
} );
```

## Notes

Message bodies are not stored. The log lives in the wpide_email_log option and is capped at $max_entries.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Email Log Under Tools" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
