How to Write to WordPress Debug Log File

First, why do you need to write a WordPress debug log file?

Software programs have glitches and sooner or later they tend to show up so it’s good to be prepared. In order to fix a glitch you need to know what conditions a glitch shows up.

For this reason logging is very important because you can save debug information that a function has received or the results it generated. That information can be used for more efficient troubleshooting later on, especially on systems where you don't have proper tools to debug the  site. 

Logging is still useful on development machines even though it most likely has debugging tools installed already. You can troubleshoot by adding breakpoints in your code so PHP can stop its processing and let you examine all the variables that the script has received.

The more information you have the better you'll be able to figure out what’s causing the problem.

Logging is very useful in the context of payment gateways to see what kind of data goes back and forth. Your business depends on your cash flow. You don't want to not bill your customers or to bill them twice.

How to Enable Debugging in WordPress

To enable debugging you need to edit the WordPress config file (wp-config.php).

If the same php constant already exists, change its value or you’ll get an error message.

Define( 'WP_DEBUG', true );

Define( 'WP_DEBUG_LOG', true );

This one below is optional. If you are using it on a staging server you can set it to true.

Define( 'WP_DEBUG_DISPLAY', false ); 

If the code is running on a live site, you can check for an IP address and then decide if you   should set it to true or false.

If enabled, WordPress saves the log file in the wp-content folder into /wp-content/debug.log.

This is great for hackers and spammers and would definitely try to locate it.

Usually hosting Companies block the access to that specific file but there could be instances where that file is accessible so you can define a custom error file by adding a value that is different from true or false. Ideally this file should reside outside of your public HTML (htdocs, www, public_html) folder.

if ( empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
	define( 'WP_DEBUG_LOG', '.ht_debug.log' );
} else {
	define( 'WP_DEBUG_LOG', dirname($_SERVER['DOCUMENT_ROOT']) . '/.ht_debug.log' );
}

It would be a good idea to prefix the file with .ht_ text because that would add another layer of security. Web servers are usually configured to block access to files that start with that prefix e.g. .htaccess or .htpasswd etc.

Logging

With the previous work done you need to copy and paste the following code into a custom WordPress plugin or your functions.php file.

/**
 * The blog post can be found here - https://Orbisius.com/7260
 * @author Svetoslav Marinov (Slavi) <slavi@orbisius.com>
 * @link https://orbisius.com
 */
class Orbisius_Debug_Log_Util {
    private static $meta_key_subscr_dl_cnt = 'orb_subscr_dl_cnt';
    private static $meta_key_subscr_dl_limit = 'orb_subscr_max_dl_limit';

    /**
     * this method logs to wp log file
     * Orbisius_Debug_Log_Util::log();
     * requirements (these must be defined in wp-config.php):
     * define( 'WP_DEBUG', true );
     * define( 'WP_DEBUG_LOG', true );
     * optional:
     * define( 'WP_DEBUG_DISPLAY', false );
     *
     * @param mixed $msg
     * @return bool
     */
    public static function log($msg, $title = '') {
        ob_start();

        if (is_scalar($msg)) {
            echo $msg;
        } else {
            var_dump($msg); // avoids issues with circular references when using var_dump with complex structures
        }

        $msg = ob_get_clean();

        $title = empty($title) ? '' : $title . ':';

        $log_msg = '';
        $log_msg .= "[[[$title";
        $log_msg .= $msg;
        $log_msg .= "]]]\n";

        $write = error_log($log_msg);

        return $write;
    }
}

Usage

Orbisius_Debug_Log_Util::log("Some text", __METHOD__ . __LINE__);

or with more complex data as first argument.

Orbisius_Debug_Log_Util::log([ 'complex' => 1, ], __METHOD__ . __LINE__);

The 2nd parameter is a label or a title that goes before the data that is being logged. It is useful to pass the current method and line the line it was logged for even better logging.

We capture the output of the var_dump() php function because var_export() tends to crash with complex objects. The error is something about circular references.

Photo credit: Lavi Perchik (unsplash @laviperchik)


Disclaimer: The content in this post is for educational purposes only. Always remember to take a backup before doing any of the suggested steps just to be on the safe side.
Referral Note: When you purchase through an referral link (if any) on this page, we may earn a commission.