<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>debugging Archives - Alexandros Georgiou</title>
	<atom:link href="https://www.alexgeorgiou.gr/tag/debugging/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.alexgeorgiou.gr/tag/debugging/</link>
	<description>Balancing brackets for a living</description>
	<lastBuildDate>Wed, 15 Mar 2023 11:11:59 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.alexgeorgiou.gr/wp-content/uploads/2021/07/cropped-alexgeorgiou-icon-32x32.png</url>
	<title>debugging Archives - Alexandros Georgiou</title>
	<link>https://www.alexgeorgiou.gr/tag/debugging/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>㏒ WordPress production: To log or not to log?</title>
		<link>https://www.alexgeorgiou.gr/wordpress-production-to-log-or-not-to-log/</link>
					<comments>https://www.alexgeorgiou.gr/wordpress-production-to-log-or-not-to-log/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Wed, 15 Mar 2023 11:02:28 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[logrotate]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1254</guid>

					<description><![CDATA[<p>Rant on why I think it's OK to keep logging enabled in live WordPress sites.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/wordpress-production-to-log-or-not-to-log/">㏒ WordPress production: To log or not to log?</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Warning: <a href="https://xkcd.com/2051/" target="_blank" rel="noreferrer noopener">Opinion</a> article ahead!</p>



<p>Like any self-respecting server-side app, WordPress also features logging. While this is usually discouraged, themes and plugins can write to this log with <a href="https://www.php.net/manual/en/function.error-log.php">error_log</a>. Any PHP warnings or errors will also be dumped to the logs. That is, if logging is enabled.</p>



<h1 class="wp-block-heading">How to enable logging: RTFM</h1>



<p>To enable logging, edit the <code>wp-config.php</code> file.</p>



<p>First, add <code>define( 'WP_DEBUG', true );</code>. This will enable &#8220;debug&#8221; logging, as explained in the article <a href="https://wordpress.org/documentation/article/debugging-in-wordpress/" target="_blank" rel="noreferrer noopener">Debugging in WordPress</a>.</p>



<p>Then, add <code>define( 'WP_DEBUG_LOG', true );</code> to make the log be written to a file, <code>/wp-content/debug.log</code>.</p>



<p>Finally, you don&#8217;t want any PHP warnings or errors to spill over into your site&#8217;s markup and cause problems. Add <code>define( 'WP_DEBUG_DISPLAY', false );</code> and <code>@ini_set( 'display_errors', 0 );</code> for good measure.</p>



<p>Great! Now you&#8217;re good to go. Debug logging has been enabled.</p>



<h1 class="wp-block-heading">&#8220;Debug&#8221; logging?</h1>



<p>But I take some issue with that. Why is logging labelled &#8220;debug&#8221; logging? Are there no other legitimate reasons to keep logs? WordPress documentation doesn&#8217;t think so:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>It is not recommended to use WP_DEBUG or the other debug tools on live sites; they are meant for local testing and staging installs.</p>
<cite>from: <a href="https://wordpress.org/documentation/article/debugging-in-wordpress/" target="_blank" rel="noreferrer noopener">Debugging in WordPress</a></cite></blockquote>



<p>Perhaps this is OK for most people. WordPress is meant to be used by non-programmers, and generally by people who wouldn&#8217;t know what to do with a log file. But if you can <a href="https://hackcur.io/can-you-jam-with-the-console-cowboys-in-cyberspace/" target="_blank" rel="noreferrer noopener">jam with the console cowboys in cyberspace</a>, I think you should keep logging on, even in production. Here&#8217;s why:</p>



<h1 class="wp-block-heading">Health status</h1>



<p>The WordPress ecosystem is a beautiful mess. Typically you will run all kinds of plugins of varying quality. I know that I am responsible for dumping some low-effort buggy code on to the WordPress.org repository, and, believe me, I am not the only one. When you put many pieces of software together in the same system, things can break. Yes, you have the PHP error logs which capture most errors, but it&#8217;s helpful to have a record of the errors <em>and</em> any <code>error_log</code> output. If you have live logs, you can address incidents faster. In my mind it&#8217;s a no-brainer.</p>



<h1 class="wp-block-heading">Security</h1>



<p>In case of someone breaking in to your site, and <a href="https://webtribunal.net/blog/hacking-statistics/" target="_blank" rel="noreferrer noopener">yes, this happens a lot</a>, it may be possible to figure out what happened by looking at the logs. You may be able to figure out which plugin the hacker exploited and in what way, by looking at the failed attempts that preceded the successful break-in.</p>



<p>For extra credit, set up a cron job that stores backups off-site to another server. Evenif a hacker manages to clear the logs, you still have data for your forensics investigation.</p>



<h1 class="wp-block-heading">Disk space</h1>



<p>The main arguments against logging are that</p>



<ol class="wp-block-list">
<li>writing logs degrades performance, and</li>



<li>writing logs can fill up disk space</li>
</ol>



<p>Argument #1 is not even worth discussing in the year of our Lord 2023, when SSDs are the norm on server hardware. I can guarantee you that even if you care about performance <em>a lot</em>, the milliseconds wasted on logging are the least of your concerns. I&#8217;d much rather have logs available when I need them, if this is going to save me time and money by avoiding or fixing incidents.</p>



<p>Argument #2 is perhaps less laughable, but still invalid. The disk space argument is only brought up by people who haven&#8217;t heard of <a href="https://linux.die.net/man/8/logrotate" target="_blank" rel="noreferrer noopener">logrotate</a>.</p>



<p>Let me show you my <code>/etc/logrotate.d/wordpress</code> file on this blog&#8217;s server:</p>



<pre class="wp-block-code"><code>/usr/share/nginx/alexg/wp-content/debug.log
{
        su www-data www-data
        rotate 24
        copytruncate
        weekly
        missingok
        notifempty
        compress
}</code></pre>



<p>And now let me show you the log files that this generates:</p>



<pre class="wp-block-code" style="font-size:11px"><code>$ ls -l /usr/share/nginx/alexg/wp-content/debug*
-rw-r--r-- 1 www-data www-data 105705 Mar 12 01:43 /usr/share/nginx/alexg/wp-content/debug.log
-rw-r--r-- 1 www-data www-data   3928 Mar  5 06:34 /usr/share/nginx/alexg/wp-content/debug.log.1.gz
-rw-r--r-- 1 www-data www-data   3181 Jan  2 06:09 /usr/share/nginx/alexg/wp-content/debug.log.10.gz
-rw-r--r-- 1 www-data www-data   2532 Dec 25 06:36 /usr/share/nginx/alexg/wp-content/debug.log.11.gz
-rw-r--r-- 1 www-data www-data   2991 Dec 19 04:44 /usr/share/nginx/alexg/wp-content/debug.log.12.gz
-rw-r--r-- 1 www-data www-data   3256 Dec 11 03:15 /usr/share/nginx/alexg/wp-content/debug.log.13.gz
-rw-r--r-- 1 www-data www-data   4397 Dec  5 05:30 /usr/share/nginx/alexg/wp-content/debug.log.14.gz
-rw-r--r-- 1 www-data www-data   2284 Nov 27 06:15 /usr/share/nginx/alexg/wp-content/debug.log.15.gz
-rw-r--r-- 1 www-data www-data   2866 Nov 20 06:24 /usr/share/nginx/alexg/wp-content/debug.log.16.gz
-rw-r--r-- 1 www-data www-data   3339 Nov 13 04:22 /usr/share/nginx/alexg/wp-content/debug.log.17.gz
-rw-r--r-- 1 www-data www-data  15378 Nov  6 06:20 /usr/share/nginx/alexg/wp-content/debug.log.18.gz
-rw-r--r-- 1 www-data www-data   3194 Oct 30 06:18 /usr/share/nginx/alexg/wp-content/debug.log.19.gz
-rw-r--r-- 1 www-data www-data  38415 Feb 27 06:30 /usr/share/nginx/alexg/wp-content/debug.log.2.gz
-rw-r--r-- 1 www-data www-data   3619 Oct 24 06:24 /usr/share/nginx/alexg/wp-content/debug.log.20.gz
-rw-r--r-- 1 www-data www-data   3827 Oct 16 05:11 /usr/share/nginx/alexg/wp-content/debug.log.21.gz
-rw-r--r-- 1 www-data www-data   2213 Oct  9 05:52 /usr/share/nginx/alexg/wp-content/debug.log.22.gz
-rw-r--r-- 1 www-data www-data   3332 Oct  3 06:05 /usr/share/nginx/alexg/wp-content/debug.log.23.gz
-rw-r--r-- 1 www-data www-data  13983 Sep 25 06:24 /usr/share/nginx/alexg/wp-content/debug.log.24.gz
-rw-r--r-- 1 www-data www-data   2863 Feb 19 05:09 /usr/share/nginx/alexg/wp-content/debug.log.3.gz
-rw-r--r-- 1 www-data www-data   3913 Feb 13 05:45 /usr/share/nginx/alexg/wp-content/debug.log.4.gz
-rw-r--r-- 1 www-data www-data   3276 Feb  5 06:00 /usr/share/nginx/alexg/wp-content/debug.log.5.gz
-rw-r--r-- 1 www-data www-data   3354 Jan 29 05:38 /usr/share/nginx/alexg/wp-content/debug.log.6.gz
-rw-r--r-- 1 www-data www-data   4171 Jan 22 06:12 /usr/share/nginx/alexg/wp-content/debug.log.7.gz
-rw-r--r-- 1 www-data www-data   2835 Jan 15 06:21 /usr/share/nginx/alexg/wp-content/debug.log.8.gz
-rw-r--r-- 1 www-data www-data   2694 Jan  8 05:04 /usr/share/nginx/alexg/wp-content/debug.log.9.gz</code></pre>



<p>If you&#8217;re wondering how much space this takes:</p>



<pre class="wp-block-code" style="font-size:11px"><code>$ du -ch /usr/share/nginx/alexg/wp-content/debug*
108K    /usr/share/nginx/alexg/wp-content/debug.log
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.10.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.11.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.12.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.13.gz
8.0K    /usr/share/nginx/alexg/wp-content/debug.log.14.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.15.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.16.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.17.gz
16K /usr/share/nginx/alexg/wp-content/debug.log.18.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.19.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.1.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.20.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.21.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.22.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.23.gz
16K /usr/share/nginx/alexg/wp-content/debug.log.24.gz
40K /usr/share/nginx/alexg/wp-content/debug.log.2.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.3.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.4.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.5.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.6.gz
8.0K    /usr/share/nginx/alexg/wp-content/debug.log.7.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.8.gz
4.0K    /usr/share/nginx/alexg/wp-content/debug.log.9.gz
272K    total</code></pre>



<p>So, full logs for the last 24 days are taking up 272 kilobytes when compressed. Disk space well spent, if you ask me.</p>



<h1 class="wp-block-heading">wp-console plugin</h1>



<p>Even a console cowboy will agree that sometimes it&#8217;s more convenient to view the logs via the WordPress admin. For these rare occasions, I use <a href="https://wordpress.org/plugins/wp-console/" target="_blank" rel="noreferrer noopener">wp-console</a>. Next to the <em>Console</em> tab, which is very useful by itself, there is the <em>Debug Log</em> tab.</p>



<h1 class="wp-block-heading">Make a habbit out of it</h1>



<p>Let&#8217;s take a step back: WordPress is usually the main engine of a small business. Running a business means executing a set of processes repeatedly, with the hope that these processes will create value.</p>



<p>I like to be proactive: One of the processes that I execute repeatedly as part of my business, is to visit the site logs every 3 months. I have a calendar reminder for this, pointing to a ticket that&#8217;s all about inspecting logs. As I identify problems that I want to fix, I open separate tickets for those as well.</p>



<h1 class="wp-block-heading">Logs are compressed</h1>



<p>First, I look at the logs. Today&#8217;s file is uncompressed (<code>debug.log</code>), while older files are gzipped (<code>debug.*.log.gz</code>). Instead of ungzipping the files, I usually like to inspect them in place via an <code>ssh</code> shell, using the <a href="http://net.cmed.us/Home/unixlinux/ztools" target="_blank" rel="noreferrer noopener">zTools</a>:</p>



<ul class="wp-block-list">
<li>use <code>zcat</code> instead of <code>cat</code></li>



<li>use <code>zless</code> instead of <code>less</code></li>



<li>use <code>zgrep</code> instead of <code>grep</code></li>



<li>use <code>zfgrep</code> instead of <code>fgrep</code></li>



<li>use <code>zegrep</code> instead of <code>egrep</code></li>
</ul>



<h1 class="wp-block-heading">How I inspect logs</h1>



<p>Usually, when you look at such logs, you will see one single type of warning or notice being repeated a lot, possibly because of a plugin or theme.</p>



<p>Let&#8217;s say you see a &#8220;PHP Notice: Undefined variable: foo&#8221; line a lot, coming from some plugin. It&#8217;s not causing any real problems, but it gets written out with every HTTP request. You are not responsible for maintaining this plugin, but this line is obscuring your view of the logs. So, just look at the logs without it:</p>



<pre class="wp-block-code"><code>zfgrep -v 'PHP Notice:  Undefined variable: foo' debug.log.*.gz</code></pre>



<p>Now you will see a listing of all your logs, except for that notice. The next most common notice will become apparent. Let&#8217;s say that this is a &#8220;PHP Notice: Undefined index: bar&#8221; in another plugin, that you are also not the maintainer of. You can filter for that as well. Just daisy-chain your greps using pipes:</p>



<pre class="wp-block-code"><code>zfgrep -v 'PHP Notice:  Undefined variable: foo' debug.log.*.gz | fgrep -v 'PHP Notice:  Undefined index: bar'</code></pre>



<p>You could go into the source code of these files and add a <code>@</code> character in front that line, to suppress the warnings, at least until the plugin in question is updated by the developer. But I don&#8217;t recommend it. Too much effort for too little gain. <code>gzip</code> does an excellent job of compressing similar strings repeated thousands of times. This is literally what huffman trees were built for.</p>



<h1 class="wp-block-heading">Rinse and repeat</h1>



<p>Continue chaining greps, until you get to an error that you care about. Maybe it&#8217;s an error that looks ugly, worries you, or just feels bad. Maybe an include is missing. Maybe you can investigate, or even fix the issue. Or maybe you feel like you have to notify the developer via the plugin&#8217;s support forum. Maybe you&#8217;ll decide that a plugin causes too many errors and is easily replaceable by another similar one.</p>



<h1 class="wp-block-heading">Deprecated code</h1>



<p>Depending on what you are doing, you may want to hide deprecation notices. At the time of this writing, even the latest version of WordPress core writes a lot of deprecation notices if you are running PHP 8. If you&#8217;re not a core developer, it&#8217;s not our job to fix them, so filter them out with: <code>| grep -v 'PHP Deprecated.*/var/www/wordpress/wp-(includes|admin)'</code>. See what I did there? I filtered out only Deprecation warning lines coming from the <code>wp-includes</code> or <code>wp-admin</code> directories, but not Deprecation warnings from other components (plugins or themes). Regular expressions are your friend.</p>



<p>Code that is deprecated in PHP8 will stop running in PHP9 when it arrives sometime this year. Before you upgrade your PHP, you may want to know which plugins are going to have problems. A plugin developer who is proactive will be fixing these.</p>



<p>It&#8217;s always better to be proactive with these things. Also, be mindful of the quality of the code you are running on your servers. A plugin that dumps too many warnings into the server logs (or into the browser&#8217;s console log, for that matter), is a low-quality plugin.</p>



<h1 class="wp-block-heading">Conclusion (and shameless ref link plug)</h1>



<p>If you are proactive in that way, you will catch incidents before they occur.</p>



<p>Of course, you can only do this if you are running your WordPress on a server with shell access. Managed hosting is good for most people, but if you are the hands-on type of person, you will want to have shell access. With <code>ssh</code> access you can harden your server&#8217;s security yourself, and then noone can ruin your server for you. Be an grown-up, ruin it yourself!</p>



<p>This blog runs on a <a href="https://m.do.co/c/44d4d2184573" target="_blank" rel="noreferrer noopener">DigitalOcean</a> droplet. I honestly cannot recommend them enough. I am happy because my droplet is always available, with great up-time, great documentation, great admin screens, never even needed to contact support. They have a good choice of data centers around the world, an API for spinning up new instances programmatically, and if there is ever any downtime or even a network slowdown, they let you know way in advance. Taking snapshots of your droplet is a breeze. Some of the lowest <a href="https://www.digitalocean.com/pricing" target="_blank" rel="noreferrer noopener">prices</a> I&#8217;ve seen, starting from $4 per month for a low traffic site. If you don&#8217;t feel like setting up everything up by yourself, they also have a <a href="https://marketplace.digitalocean.com/apps/wordpress-woocommerce" target="_blank" rel="noreferrer noopener">WordPress-WooCommerce Droplet</a> in their marketplace.</p>



<p>If you sign up with this <a href="https://m.do.co/c/44d4d2184573" target="_blank" rel="noreferrer noopener">referral link</a> you get $200 of credit which you can spend over the first 60 days. And yes, if you spend $25 or more with them, I get $25 for my trouble too, so thank you for that!</p>


<div class="wp-block-image">
<figure class="aligncenter"><a href="https://www.digitalocean.com/?refcode=44d4d2184573&amp;utm_campaign=Referral_Invite&amp;utm_medium=Referral_Program&amp;utm_source=badge"><img decoding="async" src="https://web-platforms.sfo2.digitaloceanspaces.com/WWW/Badge%203.svg" alt="DigitalOcean Referral Badge"/></a></figure>
</div><p>The post <a href="https://www.alexgeorgiou.gr/wordpress-production-to-log-or-not-to-log/">㏒ WordPress production: To log or not to log?</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/wordpress-production-to-log-or-not-to-log/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
