Skip to content
CH SCShop classgeneral · beginner · ~30 min · 6 steps

How to find and read your website's error logs

Locate the PHP, server, and CMS logs for your site and read a stack trace well enough to know what broke and where.

August 10, 2026 · by Dane Petersen

When a site misbehaves, the logs already know why. Most people skip them because a wall of timestamps looks unfriendly — but a log line has the same three parts every time, and once you can pick them out, “the site is broken” becomes “line 214 of one specific file is broken.” You’ll need SSH access to your server (here’s how to set that up) and a problem you can reproduce, even a small one.

Find where your logs live

The locations vary by server, but the usual suspects cover almost everyone:

ls -la /var/log/nginx/ /var/log/apache2/ /var/log/httpd/ ~/logs/ 2>/dev/null

Nginx keeps errors in /var/log/nginx/error.log, Apache in /var/log/apache2/error.log (Debian/Ubuntu) or /var/log/httpd/error_log (RHEL flavors), and cPanel hosts usually drop a per-account error_log in your home directory or ~/logs/. If PHP logs somewhere separate, PHP itself will tell you:

php -i | grep error_log

On managed hosting (Pantheon, WP Engine, Kinsta), skip the hunt — the dashboard has a Logs section, and that’s the same file with a nicer door.

Tail a log while you reproduce the problem

Don’t read logs like a book; watch them like a river. Open a live view, then go trigger the problem in your browser:

tail -f /var/log/nginx/error.log

Whatever scrolls past at the moment you click is your error. Everything else in the file is history. Press Ctrl+C to stop watching.

Read a PHP error line by line

A PHP error has three parts: the what, the where, and the trail.

PHP Fatal error: Uncaught TypeError: array_map(): Argument #2 must be
of type array, null given in /var/www/html/modules/custom/hello/hello.module:214

The what is the sentence (“expected an array, got null”). The where is the file and line after in — that colon-214 is the line number, and it’s the single most useful character on the screen. Below a fatal you’ll often see a numbered “stack trace”: the chain of functions that led there, newest first. You rarely need the whole chain — the top line plus the first file you recognize as yours is usually the answer.

Tell a warning from a fatal

Severity words matter. A notice or deprecated is the code muttering to itself — worth cleaning up someday, not why you’re here. A warning means something went sideways but the page carried on. A fatal error means PHP stopped dead, which is what a white screen is. When a log is noisy, filter for the ones that stop the show:

grep -i "fatal" /var/log/nginx/error.log | tail -n 20

Check the CMS’s own log

PHP sees crashes; your CMS sees intent — failed logins, missing pages, module complaints. In Drupal:

drush watchdog:show --count=30

(or Reports → Recent log messages in the admin.) In WordPress, enable WP_DEBUG_LOG in wp-config.php and read wp-content/debug.log. When the server log and the CMS log point at the same file, you’ve found your answer twice, which is the good kind of redundant.

Verify by causing a harmless error

Prove you can catch a fish before you need dinner. Create a throwaway file in your docroot:

echo '<?php error_log("deadnorth log test"); echo "ok";' > logtest.php

Visit /logtest.php in your browser, then check the log:

grep "deadnorth log test" /var/log/nginx/error.log ~/logs/error_log 2>/dev/null

If your message shows up, you know exactly which file catches errors and that you can read it. Delete logtest.php, and next time something breaks for real, you’ll already know where the river is.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.