Logging and error pages
A log is a file where the site records what happened to it: errors, warnings, important events. On the live server a visitor sees only a generic error page, while the developer reads the details in the log. Log files live in the writable/logs folder, error page templates in app/Views/errors/html.
Writing to the log
// app/Controllers/Home.php
public function index(): string
{
log_message('error', 'Log check');
return 'Entry added';
}Open the home page, then the writable/logs folder: the file with today's date, for example log-2026-03-02.log, gets a line with the ERROR level, the time and the text. A separate file is created for each day.
Levels
The first argument of log_message() is the severity level:
| Number | Level | When to use |
|---|---|---|
| 1 | emergency | The site is down |
| 2 | alert | Immediate action is needed |
| 3 | critical | An important part has failed |
| 4 | error | An error in one request |
| 5 | warning | Something suspicious |
| 6 | notice | A notable but normal event |
| 7 | info | Ordinary events: a login, an order |
| 8 | debug | Details for debugging |
Data in a message
Values are inserted in place of placeholders in curly braces:
log_message('info', 'Post {id} published by user {user}', [
'id' => $post['id'],
'user' => session('user_id'),
]);The log gets a line like "Post 5 published by user 1".
The threshold
Which levels reach the file is set by the $threshold property in app/Config/Logger.php:
// app/Config/Logger.php
public $threshold = (ENVIRONMENT === 'production') ? 4 : 9;The number 4 means "record levels 1 to 4", that is errors and everything more serious. So on the live server info and debug messages do not reach the log until the threshold is raised.
Error pages
When an error happens, CodeIgniter writes it to the log itself and outputs one of the templates from the app/Views/errors/html folder:
| File | When it is shown |
|---|---|
error_404.php | Page not found |
error_exception.php | Any error in development mode: text, file, line |
production.php | Any error in production mode: a generic phrase without details |
These files are ordinary views. Open error_404.php and replace the markup with your own:
<!-- app/Views/errors/html/error_404.php -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Page not found</title>
</head>
<body>
<h1>There is no such page</h1>
<p><a href="/">Back to the home page</a></p>
</body>
</html>Open a non-existent address, for example /nothing, and your page appears. A visitor sees the same page when a controller throws PageNotFoundException.
The debug toolbar
In development mode every page has a debug toolbar at the bottom. It shows database queries, timing, the views used and the log entries of the current request — no need to open the file.
Common mistake
The writable folder must be writable by the web server. Without the permission no log is created and nobody learns about errors on the server. After moving the project, open writable/logs and make sure files appear there. The folder itself must not be reachable from a browser — the log contains addresses and request data.