SMTP and Email Logs for WordPress
Log every email your site sends, find out exactly why one failed, send mail through your own SMTP server and let old logs clean themselves up.
1. Overview
SMTP and Email Logs for WordPress records every email your site sends, shows you whether each one was accepted or failed and why, and can send all of it through your own SMTP server. Old logs are deleted automatically.
It works with every email that goes through WordPress's wp_mail() function: password resets, new user notices and comment notifications from WordPress itself, WooCommerce order emails, contact form messages and anything else a plugin sends in the standard way. Open any log to read the message, the headers, the attachments and the exact error.
How it works
- An email is sent. The plugin notes the attempt when WordPress calls
wp_mail(), before anything is sent, so even an email that crashes is recorded. - The transport answers. WordPress reports success or failure. The plugin attaches that result to the right log, matching the recipients, the subject and the message, so an outcome is never given to a different email.
- You can read it. The log shows the status, the error in plain language, the server reply (credentials removed), the headers, the attachments' names and a sandboxed preview of the message.
- It sends through your server, if you want. Switch on SMTP, enter your provider's details, and press Send Test Email. With SMTP off, your site's normal mail transport is not touched.
- It cleans up. A daily job deletes logs older than the retention period (90 days by default). It never deletes anything else.
At a glance
Complete email log
Recipients, sender, subject, status, error, transport, the plugin or function that sent it, and the related user and WooCommerce order.
Honest status
Sent means the mail transport accepted the message. Failed means WordPress reported an error. Unknown means it could not be determined. Never a claim of delivery.
Your own SMTP server
Host, port, encryption, login, From name and address, Reply-To, timeout and certificate checks, with a test email and a connection check.
Safe by default
The SMTP password is stored encrypted and never shown. Reset links and one-time codes are hidden before a message is stored. A hostile email cannot run scripts in the preview.
Automatic cleanup
Delete logs older than 7 to 365 days, or a number you choose, once a day, in batches that are safe to interrupt.
Search, export, privacy
Search and filter thousands of logs, export to CSV, and include logs in WordPress's personal data export and erase tools.
What it does not do
- It does not prove delivery. WordPress cannot tell whether an accepted email reached the inbox. Check the spam folder and your provider's own delivery log.
- It cannot log mail that bypasses WordPress. A plugin that talks to a mail service through its own API or mailer never calls
wp_mail()and cannot be recorded. - It does not resend emails, queue mail or track opens and clicks.
- It does not fall back to PHP mail when SMTP is wrong. If SMTP is on but incomplete, emails fail with a clear message, so you notice instead of sending through a route you did not choose.
2. Requirements
| Requirement | Needed |
|---|---|
| WordPress | 6.2 or later (tested up to 7.1) |
| PHP | 7.4 or later (tested on 8.2 to 8.5) |
| WooCommerce | Not required. When it is active, order emails are linked to their order. |
| SMTP | Only if you want to send through your own server: the host, port and login from your email provider. Outgoing connections on that port must be allowed by your host. |
| Scheduler | Action Scheduler (included with WooCommerce) is used for the daily cleanup when present; otherwise WP-Cron. Without either, press Run Cleanup Now or use a server cron job. |
| Access | Only users who can manage options (administrators) can see the logs and settings. |
3. Installation
- Download the plugin zip from your account on wpexpertshub.com.
- In WordPress open Plugins → Add New → Upload Plugin, choose the zip and press Install Now.
- Activate the plugin. It creates one table and adds Tools → Email Logs. Logging starts immediately; SMTP stays off.
- To send through your own server, open Tools → Email Logs → SMTP Settings, enter your provider's details, tick Enable SMTP, save, then press Send Test Email.
- Activate your licence under Plugins → WpExperts Hub Licences to receive updates.
Licence and updates
Open Plugins → WpExperts Hub Licences, enter your licence key and press Activate. The key is in your purchase email and under My Account → Downloads on wpexpertshub.com. The licence is only used for updates: every feature works without it.
The licence and update check contacts wpexpertshub.com with the licence key, your site address and the plugin version. It never sends emails, logs or recipients.
What activation creates
| What | Details |
|---|---|
| One table | {prefix}wphub_smtp_logs, one row per email attempt. |
| Options | wphub_smtp_logs_settings (logging, privacy, retention), wphub_smtp_logs_smtp (SMTP, with the password encrypted), wphub_smtp_logs_state (last test, cleanup history, recent problems), wphub_smtp_logs_db_version and wphub_smtp_logs_schedule. |
| A daily job | wphub_smtp_logs_cleanup in the Action Scheduler group wphub-smtp-logs (or WP-Cron), with one continuation event when a run has more to do. Exactly one is ever scheduled. |
Updating, deactivating and deleting
- Updating keeps your settings and logs.
- Deactivating stops logging, SMTP and the scheduled cleanup, and deletes nothing. When you activate again the schedule is restored.
- Deleting the plugin keeps your logs, table and settings unless Delete all logs, the log table and the plugin settings when the plugin is deleted is ticked under General Settings. Then the table, the options (including the encrypted password) and transients are removed.
Multisite
When the plugin is network-activated the table is created on every site, and on sites created later. Each site has its own logs and settings.
4. Quick start
Logging works as soon as you activate the plugin. To also send mail through your own server:
- Open Tools → Email Logs → SMTP Settings.
- Enter the host, encryption and port from your provider. The usual pair is STARTTLS/TLS with port 587 or SSL with port 465.
- Tick Authentication and enter the username and password. Many providers need an app password or an API key rather than your normal login.
- Enter the From name and From email address. Most providers only accept an address that belongs to your account or a verified domain.
- Tick Enable SMTP and press Save SMTP settings. Saving sends nothing.
- Press Check connection to test the connection and login without sending, then Send Test Email to send a real message to yourself.
- Open Email Logs to see the test and every email after it.
5. Features
Email logging
Every email sent through wp_mail() gets a row. A row stores:
- The date and time (kept in UTC, shown in your site's timezone), recipients (to, cc, bcc, reply-to) and sender.
- The subject, content type and, if you keep it, the message body.
- The headers (sensitive ones masked) and the names, sizes and types of attachments. Attachment contents are never stored.
- The status and, for a failure, the error, the server reply and the conversation with credentials removed.
- The mail transport (for example SMTP smtp.example.com:587), and the source: the plugin, theme, WordPress function or WooCommerce email that sent it.
- The related user (only when the single recipient is a user's address) and the related WooCommerce order (only from the WooCommerce email object).
Logging problems never reach WordPress. If the plugin cannot write a row, the email still goes out and the problem is listed under Diagnostics.
What the statuses mean
| Status | Meaning |
|---|---|
| Sent | The mail transport (your SMTP server, or the server's own mail function) accepted the message. It does not prove the message reached the inbox. |
| Failed | WordPress reported that sending failed. The error and the server reply are in the log. |
| Unknown | The outcome could not be determined, for example because another plugin took over the sending. The plugin does not guess. |
Finding and reading logs
- Search by recipient, subject or log ID, filter by status and date range, sort any column and page through thousands of logs. Set how many rows you want under Screen Options.
- Open a log to see every field, the headers, the attachments and the message as a sandboxed HTML preview, plain text or HTML source.
- Copy error details puts the error, the server reply and the conversation on your clipboard, ready for your host or mail provider.
- Delete one log, many with a bulk action, or all of them.
Sending through your SMTP server
- The plugin uses WordPress's own PHPMailer, so nothing extra is installed. SMTP off leaves your normal mail transport untouched.
- SMTP on but incomplete makes emails fail with a clear message and an admin notice. They are never sent another way.
- A From name or address chosen on purpose by a plugin is kept, unless you tick Force, which sets yours on every email.
- A Reply-To address is added only to emails that have none of their own.
- The timeout also applies to each reply from the server, so a silent server fails after your timeout instead of hanging for minutes.
- Choosing None for encryption really sends without encryption. Use it only on a trusted internal network.
The SMTP password
The saved password is never displayed, logged, exported or included in test results. An empty field keeps it, and a separate box removes it. In the database it is encrypted with a key derived from your site's secret keys. That protects a copied database, but not someone who can read both the database and wp-config.php.
For production sites the safer way is to define the settings as constants in wp-config.php. A constant wins over the database and locks its field. See Constants.
Test email and connection check
- Send Test Email sends a real message through the same path as every other email, records it in the log as a test and reports the outcome with plain-language advice (authentication, TLS, firewall, sender restrictions, limits). With SMTP off it runs a clearly labelled default-mail test.
- Check connection connects, starts encryption and logs in, then disconnects without sending. It separates a connection or login problem from a problem with the message.
- Nothing runs in the background, and saving settings never sends an email.
Automatic cleanup
- On by default, 90 days. Choose 7, 15, 30, 60, 90, 180 or 365 days, or a custom number from 1 to 3650.
- A log expires when its creation time is older than the cutoff. It runs once a day, in batches of 500 inside a time limit. A long run schedules its own continuation and an interrupted run resumes safely.
- It deletes only log rows. Saving settings or opening a page never deletes anything.
- Run Cleanup Now applies the current retention immediately, even with automatic deletion off. Delete All Logs is separate. Both ask for confirmation.
- The status box shows a next run only when one is really scheduled, and the last 20 runs are kept under Diagnostics.
Privacy controls
- Separate switches for logging, storing the message body, logging sent emails and logging failed emails.
- Reset links and one-time codes are hidden before a message is stored (common patterns such as
key=,token=,code=in links and "verification code is 123456"). - Recipients can be masked in the list (
j***@example.com). The log screen, exports and search still use the full address. - Logs are included in WordPress's personal data export and erase requests, and a privacy policy text is suggested.
CSV export
Export the current filter from the Email Logs tab. Message bodies are included only through the separate button, which warns you first. The file is UTF-8 with a byte-order mark for Excel, streamed in chunks, and cells that start with =, +, - or @ are neutralised so a spreadsheet cannot run a formula from an email.
Diagnostics
One screen lists the recent problems the plugin itself found, the latest failed emails, the last test and connection check, the cleanup history, the environment (versions, PHPMailer, encryption support, number and size of logs, scheduler, WP-Cron, timezone) and a troubleshooting checklist. It never shows a password or a token.
6. Admin screens
Everything is under Tools → Email Logs, in four tabs.
| Screen | What it is for |
|---|---|
| Email Logs | The list of every email, with search, filters, bulk actions and export |
| A single log | All the details of one email and a safe preview of the message |
| SMTP Settings | Status, the SMTP form, test email and connection check |
| General Settings | Logging and privacy choices, retention and cleanup |
| Diagnostics | Problems, failures, test results, history and environment |
Email Logs
The counts All, Sent, Failed and Unknown above the list are links. The columns are the ID, the date and time, the recipient, the subject (with a Test label for test emails), the source and the status. View opens the log and Delete removes it. Below the list: Export CSV (current filter), Export CSV with message bodies and Delete all logs.
A single log
The top card has the log ID, date and time (also in UTC), the status in words, the recipients, the sender, the subject, the content type, the transport, the source and the linked WooCommerce order. Message switches between HTML preview, Plain text and HTML source. A failed email adds an Error card with an explanation, the exact error, the server reply and Copy error details.
SMTP Settings
The first card shows the SMTP status: transport mode, whether SMTP is on, host and port, encryption, authentication, sender email, the last test and its outcome, the last successful test and the last reported error. The note under it says what a saved setting does and does not prove. The form, the test email and the connection check follow, then a troubleshooting checklist.
General Settings
See Settings for every option. Under the form, Cleanup status and maintenance holds the status table, Run Cleanup Now and Delete All Logs, and a short note on what is stored and who can see it.
Diagnostics
7. Settings
Open Tools → Email Logs. The defaults work without changes: logging on, SMTP off, 90-day cleanup on.
SMTP Settings
| Setting | What it does | Default |
|---|---|---|
| Enable SMTP | Sends all WordPress email through the server below. Off leaves your normal transport alone. | Off |
| SMTP host | The server name from your provider, for example smtp.example.com. | Empty |
| Encryption | None, SSL or STARTTLS/TLS. Typical: STARTTLS/TLS with port 587, or SSL with port 465. | STARTTLS/TLS |
| SMTP port | The port your provider gives you. | 587 |
| Authentication | Tick when the server needs a username and password. | On |
| SMTP username | The login. Often your email address, or the word apikey or a key name. | Empty |
| SMTP password | Stored encrypted, never shown again. Leave empty to keep the saved one; tick Remove the saved password to delete it. | Empty |
| From name | Replaces WordPress's default sender name. A name chosen on purpose by a plugin is kept, unless Force is ticked. | Empty |
| From email address | Most providers only accept an address that belongs to your account or a verified domain. Force sets it on every email. | Empty |
| Reply-To address | Added only to emails that have no Reply-To of their own. | Empty |
| Connection timeout | Seconds to wait for the server, also applied to each reply. | 15 |
| Server certificate | Check that the server certificate is valid. Switch off only for a server you control that uses a self-signed certificate. | On |
General Settings
| Setting | What it does | Default |
|---|---|---|
| Email logging | Record emails sent through wp_mail(). Switching it off stops new records and never deletes existing logs. | On |
| Log emails the mail transport accepted | Record emails with the status Sent. | On |
| Log emails that failed | Record emails with the status Failed. | On |
| Store the message body | Keep the message so you can preview it. Bodies can contain names, addresses, order details and links, so switch this off if you only need to know that mail was sent. Recipient, subject, status and errors are still recorded. | On |
| Hide reset keys, tokens and one-time codes | Replace the secret part of reset and activation links and codes with [redacted] before saving. It recognises common patterns, not every possible secret. | On |
| Mask recipient addresses in the list | Show j***@example.com in the list. The log screen, exports and search still use the full address. | Off |
| Enable automatic deletion | Delete logs older than the retention period, once a day. Off keeps logs until you delete them. | On |
| Retention period | 7, 15, 30, 60, 90, 180 or 365 days, or a custom number from 1 to 3650. A shorter period removes older logs at the next cleanup. | 90 days |
| Data when the plugin is deleted | Delete all logs, the log table and the plugin settings (including the saved SMTP password) when the plugin is deleted. | Off |
8. For developers
Constants in wp-config.php
Define the SMTP settings in wp-config.php and they override the database and lock their fields on the screen. This keeps credentials out of the database and lets you read them from the server environment.
define( 'WPHUB_SMTP_LOGS_ENABLED', true );
define( 'WPHUB_SMTP_LOGS_HOST', 'smtp.example.com' );
define( 'WPHUB_SMTP_LOGS_PORT', 587 );
define( 'WPHUB_SMTP_LOGS_ENCRYPTION', 'tls' ); // none | ssl | tls
define( 'WPHUB_SMTP_LOGS_AUTH', true );
define( 'WPHUB_SMTP_LOGS_USER', 'username' );
define( 'WPHUB_SMTP_LOGS_PASS', getenv( 'SMTP_PASSWORD' ) );
define( 'WPHUB_SMTP_LOGS_FROM_EMAIL', 'site@example.com' );
define( 'WPHUB_SMTP_LOGS_FROM_NAME', 'My Site' );
The same prefix also accepts _FORCE_FROM_EMAIL, _FORCE_FROM_NAME, _REPLY_TO, _TIMEOUT and _VERIFY_CERT.
Hooks
| Filter | What it does |
|---|---|
wphub_smtp_logs_capability | The capability needed to see the logs and settings (default manage_options). |
wphub_smtp_logs_should_log | Return false to skip logging one email. Receives the wp_mail() arguments. |
wphub_smtp_logs_cleanup_batch_size | Rows deleted per batch (default 500, between 10 and 5000). |
wphub_smtp_logs_use_action_scheduler | Return false to use WP-Cron even when Action Scheduler is available. |
// Do not log newsletters.
add_filter( 'wphub_smtp_logs_should_log', function ( $log, $atts ) {
return false !== strpos( (string) $atts['subject'], 'Newsletter' ) ? false : $log;
}, 10, 2 );
Data model
| Name | What it holds |
|---|---|
{prefix}wphub_smtp_logs | One row per email attempt. Times are stored in UTC. |
wphub_smtp_logs_settings | Logging, privacy, retention and uninstall choice. |
wphub_smtp_logs_smtp | The SMTP settings. The password is stored encrypted (v1:…), never in clear text. |
wphub_smtp_logs_state | Last test and connection check, cleanup history (last 20) and recent problems. |
wphub_smtp_logs_cleanup | The scheduled cleanup event (and wphub_smtp_logs_cleanup_continue for a long run), group wphub-smtp-logs. |
Running the cleanup from a server cron
If WP-Cron is disabled and Action Scheduler is not present, run the cleanup from your server's cron with wp cron event run wphub_smtp_logs_cleanup, or press Run Cleanup Now.
How an email is matched to its result
The plugin writes a row with the status Unknown when wp_mail() is called. The outcome (wp_mail_succeeded or wp_mail_failed) goes to the newest row with the same signature: recipients, subject and a hash of the message. A result with no matching attempt, for example from a replacement wp_mail() that still fires the hooks, gets its own row. If another plugin short-circuits sending, the row stays Unknown (or becomes Failed when it returned false).
9. Privacy and security
- Who can see logs: only users with the
manage_optionscapability. There is no REST API endpoint and nothing is public. - What is stored: time, recipients, sender, subject, optionally the body, headers (sensitive ones masked), attachment names and sizes, errors, transport, source and related user or order. Never stored: the SMTP password in clear text, authentication tokens and attachment contents.
- Outside servers: only the SMTP server you configure, and wpexpertshub.com for the licence and update check when you activate a licence. The licence check sends the key, your site address and the plugin version, and never emails, logs or recipients.
- Personal data requests: logs matching an email address (recipient, cc, bcc, sender or the linked user) are included in WordPress's export and erase tools under Tools → Export Personal Data and Erase Personal Data.
- Retention: logs older than the retention period are deleted every day. Turn off message storage to keep only the facts about each email.
- Safe previews and exports: messages open in a sandbox with no scripts or remote content. Exports need the capability and a nonce, and neutralise spreadsheet formulas.
If your privacy policy lists the data you keep, add that emails sent by the site are logged for a number of days. WordPress suggests wording on Settings → Privacy.
Uninstalling
By default deleting the plugin keeps your logs, table and settings. Tick Delete all logs, the log table and the plugin settings when the plugin is deleted under General Settings first if you want everything removed, including the encrypted SMTP password.
10. Troubleshooting
First, the quick checks
- Open Email Logs → Diagnostics. It lists problems the plugin found and the last test result.
- Press Check connection on the SMTP tab. It separates a connection or login problem from a problem with a message.
- Filter the log by Failed, open the newest one and read the error and the server reply.
SMTP errors
| You see | What to check |
|---|---|
| Could not authenticate / 535 | The username and password. Many providers need an app password or an API key. Re-enter the password: an empty field keeps the old one. |
| Could not connect / connection refused / timed out | The host name, the port and the encryption together (587 with STARTTLS/TLS, 465 with SSL). Ask your host whether outgoing connections on that port are blocked. |
| Certificate or TLS error | The encryption choice matches the port, and the server's certificate matches the host name. Switch the certificate check off only for a server you control. |
| Sender address rejected | Use a From address that belongs to your account or a verified domain. Tick Force if another plugin sets a different one. |
| SMTP is on but nothing is sent and the log says the settings are incomplete | Host, port and, with authentication on, the username and password must all be set. Emails fail on purpose rather than use another route. |
| Rate limit or quota | Your provider limits how many messages you can send. Check its dashboard. |
The test says "accepted" but nothing arrives
Accepted means the server took the message. Check the spam folder and your provider's delivery log, and make sure SPF, DKIM and DMARC are set up for the From domain. Some providers accept a message and still filter or drop it.
An email is missing from the log
- Only emails sent with
wp_mail()are recorded. A plugin that uses a mail service's own API or its own mailer bypasses it. - Check that Email logging and the matching Log emails… switch are on, and that the log was not removed by the retention period.
- A filter on
wphub_smtp_logs_should_login your theme or another plugin may skip it.
Many emails show Unknown
Another plugin handled the sending (for example a queue or a mail service plugin that takes over wp_mail()), so WordPress never reported an outcome. The plugin does not guess. Look at your mail plugin's own log for the result.
Cleanup does not run
Look at Next scheduled cleanup on General Settings. If it says nothing is scheduled, make sure automatic deletion is ticked and save. If WP-Cron is disabled on your site and Action Scheduler is not present, run wp cron event run wphub_smtp_logs_cleanup from a server cron or press Run Cleanup Now.
11. FAQ
Does “Sent” mean the email arrived?
No. It means the mail transport (your SMTP server, or the server’s own mail function) accepted the message. Delivery to the inbox can still fail or end up in spam.
Which emails are logged?
Everything sent with wp_mail(): WordPress core (password resets, new users, comment notices), WooCommerce order and customer emails, contact form plugins and any plugin that uses the standard function. The source column shows which plugin or function sent each one.
Can it log emails that another mail plugin sends?
Yes, as long as that plugin sends through wp_mail(). A plugin that calls a mail service directly never reaches WordPress and cannot be logged. If another plugin takes over sending, the log shows Unknown rather than guessing.
Do I have to use the SMTP part?
No. SMTP is off by default and logging works on its own. With SMTP off your site keeps using its normal mail transport.
What happens if SMTP is on but the settings are wrong?
Emails fail and the log says why, and an admin notice tells you what to fix. They are never quietly sent another way.
Is my SMTP password safe?
It is never displayed, logged, exported or included in test results. In the database it is encrypted with your site’s secret keys. For production sites define the credentials as constants in wp-config.php so they are not in the database at all.
Are message bodies stored? Is that safe?
Optionally, and on by default. Bodies can contain personal data, so switch storage off if you only need to know that mail was sent. Reset links and one-time codes are hidden before saving, logs are visible only to administrators and they are deleted after the retention period.
Can a malicious email harm my admin?
No. Messages are shown in a sandboxed frame without scripts, forms, remote images or remote styles, and exports neutralise spreadsheet formulas.
How long are logs kept?
90 days by default. Choose 7, 15, 30, 60, 90, 180 or 365 days, or a custom number, or turn automatic deletion off. Cleanup runs once a day.
Will cleanup delete anything else?
No. It deletes only log rows created before the cutoff. Saving settings or opening a page never deletes logs.
Does it work without WooCommerce?
Yes. WooCommerce is not required. When it is active, order emails are linked to their order.
Does it slow my site down?
Logging adds one small database write per email. Nothing runs for visitors, and the admin assets load only on the Email Logs screen.
Can I export the logs?
Yes. Export the current filter to CSV from the Email Logs tab, with message bodies only if you choose that button.
Does it work on multisite?
Network activation creates the table on every site, and each site has its own logs and settings. The plugin has not been tested on a large network.
Does the plugin contact any outside server?
Only the SMTP server you configure, when you enable SMTP, and wpexpertshub.com for the licence and update check if you activate a licence. That check sends the key, your site address and the plugin version, never any email, log or recipient.
Does it work without a licence?
Yes. The licence is only for updates.
How do I get support?
Email support@wpexpertshub.com with your order ID, the plugin version and what you see on the Diagnostics tab.
12. Changelog
1.0.0 · 2026-10-10
- First release.
- Email logging with an honest Sent, Failed or Unknown status, the sending plugin or function, and the related user and WooCommerce order.
- Log viewer with search, filters, sorting, a sandboxed HTML preview, plain text and source views, bulk delete and CSV export.
- SMTP settings with encryption options, an encrypted password, wp-config.php constants, a test email and a connection check.
- Automatic and manual log cleanup with history, Diagnostics, and privacy tools including personal data export and erase.
13. Support
Email support@wpexpertshub.com and a person will help. Please include:
- Your order ID (from your purchase email or My Account on wpexpertshub.com).
- The plugin version (shown on Plugins) and your WordPress and PHP versions.
- What you expected, what happened and what you already tried.
- The error text from the failed log and the result of Check connection. Do not send your SMTP password.
- Which email provider or SMTP service you use.
Please do not send passwords or customer data. Support never needs them.