Skip to content

WordPress

WordPress debug.log: enable WP_DEBUG_LOG safely

Turn on WP_DEBUG_LOG for background debugging in WordPress 6.x - with production safety, quieter logs, WP-CLI tips, and when Query Monitor is better.

· Updated · 4 min read·
  • WordPress
  • debugging
  • WP_DEBUG
  • security
PHP code open in the Sublime Text editor

When developing WordPress sites, you sometimes need to see what is happening in the background without dumping debug output on the screen. debug.log is still my go-to for that - but turn it off on production unless you have a very good reason and tight file permissions.

This post covers enabling WP_DEBUG_LOG safely in WordPress 6.x, reducing plugin noise, logging your own values, and choosing between debug.log, Query Monitor, and the host’s error log.

Enable logging in wp-config.php

In WordPress 6.x the constants follow the same pattern:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

Errors and your own error_log() calls go to wp-content/debug.log. Keeping WP_DEBUG_DISPLAY false stops visitors from seeing PHP notices.

Optional refinements:

// Only log (do not redefine if already set by the host)
if ( ! defined( 'WP_DEBUG_LOG' ) ) {
  define( 'WP_DEBUG_LOG', true );
}

Some hosts route PHP errors to their own panel. If debug.log stays empty, check the hosting error log first before assuming WordPress is silent.

Production warning: A writable debug.log in a web-accessible directory can leak paths, usernames, queries, and plugin internals. On live sites I prefer staging-only debugging, or logging via the host’s error log. After a hack investigation, delete old debug logs - they are a common place to leave sensitive traces. See WordPress security cleanup after a hack for the full recovery workflow.

Staging workflow that does not bite you

A sane pattern:

  1. Reproduce the bug on staging with the same PHP version and plugins.
  2. Enable WP_DEBUG + WP_DEBUG_LOG only there.
  3. Reproduce once, capture the log, then disable debugging.
  4. Fix on staging, deploy the fix - not the debug settings - to production.

If you must debug production:

  • Enable logging briefly
  • Restrict access to wp-content/debug.log at the server level if possible
  • Download and delete the log when finished
  • Confirm WP_DEBUG is false again

Filter out plugin noise

Third-party plugins and themes often flood the log with deprecations and notices. That makes real errors hard to find.

A small must-use plugin in wp-content/mu-plugins/ can narrow what gets logged:

<?php
/**
 * Plugin Name: Quieter error reporting for investigations
 */
error_reporting( E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED & ~E_USER_NOTICE & ~E_STRICT & ~E_NOTICE );

MU-plugins load automatically - WordPress must-use plugins documentation replaces the old Codex page.

Do not leave a “silence everything” MU-plugin in production forever. It can hide the exact fatals you need later.

Log your own variables

Use error_log() for values you care about:

error_log( '---- my_function ----' );
error_log( print_r( $dataarray, true ) );

Tips that save time:

  • Prefix lines with a unique token so you can grep the log
  • Log the request URI or a correlation ID when possible
  • Pair logging with a reproducible URL, admin action, or WP-CLI command so you are not tailing a 50MB file blind

Example with WP-CLI (on hosts that support it):

wp eval 'error_log("cli probe ok");'
tail -n 50 wp-content/debug.log

debug.log vs Query Monitor vs host logs

ToolBest for
debug.logCron, background jobs, fatals that kill output, CLI
Query MonitorLogged-in browsing: queries, hooks, HTTP API, template parts
Host error logPHP fatals when WordPress never bootstraps cleanly

I often start with Query Monitor for “this admin page is broken,” and reach for debug.log when the failure is intermittent, cron-related, or invisible in the browser.

Log rotation and size

Left alone, debug.log grows forever. Large logs:

  • Waste disk
  • Slow simple tail / FTP downloads
  • Sometimes get truncated awkwardly by hosts

Rotate or delete regularly during investigations. Never commit debug.log to git. Add it to .gitignore on every project.

When debug.log is the wrong tool

  • Front-end JavaScript - browser DevTools or console.log in a local build
  • REST API issues - Network tab, or log inside rest_request_after_callbacks
  • Performance - Query Monitor, New Relic / host APM, or slow query logs - not error_log() in hot paths
  • Email / SMTP - transaction logs or a mail logger plugin, not PHP notices

Remember to switch off

Before deploy (or after the investigation):

  1. Set WP_DEBUG (and usually WP_DEBUG_LOG) to false
  2. Remove temporary MU-plugins that change error reporting
  3. Delete debug.log from production
  4. Confirm file permissions are back to normal

Debugging left on by accident is both a performance and security footgun.

Need help chasing a stubborn WordPress bug or hardening a site after messy debugging? Contact me or see WordPress & WooCommerce development.

Frequently asked questions

Should I leave WP_DEBUG on in production?

No. Leave debugging off on live sites unless you are actively investigating a critical issue, with tight file permissions and a plan to turn it off again the same day.

Where is WordPress debug.log stored?

By default at wp-content/debug.log when WP_DEBUG_LOG is true. Confirm the path with your host if they customize logging.

When should I use Query Monitor instead of debug.log?

Use Query Monitor for request-level PHP notices, queries, hooks, and HTTP calls while you are logged in. Use debug.log for background jobs, cron, CLI, and issues that do not show in a normal page load.

Need help with your site?

If this is the kind of work you need done, tell me about your project or book a call.

Denmark
Roots
Barcelona
Where it grew
Miami
Current HQ
Global
Clients