Logging and debugging
When a page is empty or behaves unexpectedly, the cause is found in the logs — text files where Magento and modules write messages and errors. Being able to quickly find the right line in a log saves more time than any other skill in this course.
Where the logs live
| File or folder | What is in it |
|---|---|
var/log/system.log | Messages of the info level and above |
var/log/debug.log | Debug messages; written in developer mode |
var/log/exception.log | Exceptions with a full stack trace |
var/report | Reports of errors shown to a visitor in production mode |
A convenient way to watch a log is a command that shows new lines as they appear:
tail -f var/log/system.logWriting to the log
Your code writes to the log through Psr\Log\LoggerInterface from the constructor:
// app/code/Acme/Hello/Model/ReviewService.php
namespace Acme\Hello\Model;
use Psr\Log\LoggerInterface;
class ReviewService
{
public function __construct(private LoggerInterface $logger) {}
public function approve(int $reviewId): void
{
$this->logger->info('Review approved', ['review_id' => $reviewId]);
}
}A line with the date, the INFO level, the text and the data from the array appears in var/log/system.log. The second argument is any information that helps to investigate later.
Message levels
| Method | When to use it |
|---|---|
debug() | Details for the developer |
info() | A normal event: an import finished |
warning() | Something suspicious, but work continues |
error() | An action failed |
critical() | A serious failure that needs attention |
The exception log
A caught exception is passed to the log as a whole:
// app/code/Acme/Hello/Model/ReviewService.php
try {
$this->reviewRepository->save($review);
} catch (\Exception $e) {
$this->logger->critical($e);
}The message and the stack trace go to var/log/exception.log. Do not leave a catch block empty: the error vanishes without a trace.
The virtual types lesson shows how to send a module's messages to a separate var/log/hello.log file.
An error on the page
In developer mode the error text and the stack trace are shown right on the page. In production mode a visitor sees only a report number, and the report itself is in the var/report folder, in a file with that number in its name.
Template hints
To find out which template and block print a part of a page, enable hints:
bin/magento dev:template-hints:enable
bin/magento cache:cleanEvery part of the page gets a frame with the path to the .phtml file and the block class name. When done, turn them off with dev:template-hints:disable.
The database query log
bin/magento dev:query-log:enableAll SQL queries start being written to var/debug/db.log. This is how redundant and slow queries are found. The log grows fast, so turn it off with dev:query-log:disable.
Step debugging
The Xdebug PHP extension lets you stop execution on a chosen line and inspect variable values in the editor. In Magento, where a call passes through plugins and generated classes, this is often the only way to understand what is going on.
Where to look for the cause
| What you see | Where to look |
|---|---|
| An empty page or a 500 error | var/log/exception.log, var/report, the PHP error log |
| A page without styles | The browser console, the pub/static folder |
| An edit is not visible | The cache: bin/magento cache:clean |
| An error about mismatched constructor arguments | The generated folder: delete its contents |
| A grid loading forever in the admin panel | The browser console and var/log/system.log |
Common mistake
var_dump() or echo is used for debugging right in a class. On a cached page the output does not appear, or it is remembered and shown to all visitors, and in API responses it breaks the JSON. Write to the log through LoggerInterface and read the file in var/log.