Last updated: September 2024
In a perfect world, there wouldn’t be any errors or bugs in production applications. However, we don’t live in a perfect world, and from experience, you know there is no such thing as a bug-free application. If you are using the Laravel framework, you can leverage its log tracking and error logging to catch bugs early and enhance the performance of your Laravel-based application.
Laravel comes pre-packaged with tools to help you track and monitor events, reducing the effort required to track down bugs. It has a stackable logging system built on top of the popular Monolog library. It also allows you to set up multiple channels based on the severity of the log or event.
These channels include stack (stacked), single, daily, Slack, syslog, monolog, SolarWinds® Papertrail®, and so on.
Single Server Environment
Configuring logging for a single server production environment is simple and straightforward. Since the data is always retained on the server, we do not have to worry about keeping the logs offsite. Laravel handles the log rotation, so you do not have to manually maintain that information either. The following configuration logs debug level errors and exceptions to a log file.
return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => false,
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
]
]
];
Production Environments
Production environments are dynamic and they often scale up and down, which means that the servers will be created or destroyed with increases and decreases in user traffic or load. This means you cannot rely on file-based logging because storage is ephemeral and load balancers make it quite difficult to track down which web server received a request.
In order to aggregate and save the logs for any retention period, you’ll have to set up a dedicated syslog server or use a service like Papertrail, which can store logs and make them accessible in a web browser.
While setting up a logs server is easy, it’s not beneficial for everyone. A decent amount of Linux knowledge and a dedicated server is required, especially if you’re managing more than one production environment.
I like Papertrail for its ease of setup and use. You just have to set up the logging channel to “papertrail” and add two configurations into your environment file (.env).
PAPERTRAIL_URL=logsXXX.papertrailapp.com
PAPERTRAIL_PORT=52204
You should be able to get the values for these settings in your Papertrail account. There is also documentation on the Laravel site about configuring the Papertrail channel.
Once set up you can easily monitor and search your logs.
Common Errors
5XX Server Errors
These are usually server side or hard errors which are thrown on the server side. These errors usually mean something unexpected happened and your program didn’t know how to handle the situation. The error could be caused by many things and we’ll describe a few common ones below.
Code Syntax Errors
These errors are easy to detect if you have debug turned on or if you’re looking at the error log. Errors usually start with syntax error, unexpected…
and will give you the name of the file and line number of the code that caused the error.
PHP version Compatibility
PHP 5.6 and 7.0 hit EOL (end of life) last year and chances are your server isn’t using those versions or won’t be for much longer. I’ve listed a few tools below which you can use to check your code for compatibility.
- php7mar – PHP 7 Migration Assistant Report (MAR) (Recommended)
- phpstan – PHP Static Analysis and compatibility check
- phan – A static analyzer, PHP 7 checker
504 Gateway Time-out
These errors usually happen when you’re running the PHP outside of Apache/Nginx as a separate process (for example, FPM or CGI) and the response isn’t returned to your web server in a timely manner. Performance tracking middleware defined in the Performance issues section later in the article might be helpful for you for tracking these issues.
Database Connection Issues
This can be solved by checking the credentials for DB connection in your environment file and making sure that the credentials are correct, the application communicates with the database server, and the database/tables exist.
The following are a few log messages thrown by this issue:
SQLSTATE[HY000] [1045] Access denied for user [USERNAME]
SQLSTATE[HY000] [2002] Operation timed out
4XX Client Errors
These errors are considered soft errors and are usually thrown when we receive an invalid request from a client.
404 Page Not Found
This error usually means that Laravel was not able to find the controller, controller method or a 404 error was thrown by your custom code. Some common steps to debug these would be to confirm that the route, controller, and method exist. If they all exist, then check to see if your code is throwing a 404 error.
Some common 404 errors are as follows:
Error Message | Possible Reason(s) |
404 | Not Found | 1. Route is not defined 2. No results were found when findOrFail() was called for a model |
Class [CLASS_NAME] does not exist | Controller class does not exist or the path to it is incorrect |
Method [METHOD_NAME] does not exist | Method does not exist or the path to it is incorrect |
Note: findOrFail() callback on a model returns a 404 error if no matching result is found in the database.
419 Page Expired
Laravel comes pre-loaded with a CSRF protection and it requires you to pass that token with all your non-GET requests. This requires a valid session to be maintained on the server side.
If you wish to exclude any requests from CSRF verification, then add those requests to your VerifyCsrfToken
middleware.
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'foo/bar',
'foo/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
422 Unprocessable Entity
This error usually means that the data you posted using AJAX was invalid for this request. This happens when you have a Request Rules setup. Laravel validates each request before it passes onto your controller method. The issue may be in your data or the request rule used for the request.
When an AJAX request is made JSON content type request it will return an error message like following, explaining what the issue is.
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name field is required."],
"email": ["The email field is required."]
}
}
Out of Memory Error
Memory limits on PHP applications exist for a reason. You do not want to allow your application an unlimited amount of memory. This error message exists for that very reason. If you’re receiving an out of memory error it means that there is a memory leak in your application. Maybe you forgot to reset an object, and the size continues to increase until the application doesn’t have any memory left to run.
Allowed memory size of [SIZE] bytes exhausted (tried to allocate [SIZE] bytes)
The following loop will keep running until the program runs out of memory:
$data = [];
$i = 100;
while($i > 100) {
$data[] = time();
$i++;
}
Performance Issues
Slow Queries
A single slow query can slow down your entire application. You did everything you could think of and made sure that all of your queries were using indexes and didn’t do anything; however, maybe you still missed something… How do you monitor for that? It’s simple enough in Laravel. Add the following code to your AppServiceProvider::boot() method:
public function boot()
{
\DB::listen(function($sql) {
if($sql->time > 1000){
\Log::info(“SLOW QUERY DETECTED:”);
\Log::info($sql->sql);
\Log::info($sql->bindings);
\Log::info($sql->time);
}
});
}
This will log every query that takes longer than a second (1000 ms) to execute. You can adjust the time accordingly to fit your needs. Running an explain on your query will provide you with some insights as to why your query is running slow.
Slow Response Time
Tracking slow response time in Laravel is relatively simple. You can define a middleware like the following example and include it in your requests.
<?php
//File Name: app/Middlewares/Performance.php
namespace App\Http\Middleware;
use Closure;
class Performance
{
public function handle($request, Closure $next)
{
return $next($request);
}
public function terminate($request, $response)
{
$execution_time = microtime(true) - LARAVEL_START;
if($execution_time > 1){ // You can change the 1 to a desired amount in seconds
\Log::info("Slow Response[{$execution_time}]: You should log some information here.");
}
}
}
After creating the middleware do not forget to include it in your Kernel.php
like this:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
....
'performance' => \App\Http\Middleware\PerformanceTracker::class,
];
You can also include it in your web or API route groups if you want to include it in all requests on web/API.
Caching
Caching your content is another way to optimize your application. You don’t have to fetch data from your database if it doesn’t change often. Laravel provides drivers for file, db, memcache, and redis backends. By default, Laravel uses a file-based caching system. Configuring caching in Laravel is easy and can be done in minutes.
benefits:
- Enhanced Application Reliability: Identifying and fixing bugs and performance bottlenecks ensures that your application runs smoothly, providing a better user experience.
- Improved Application Performance: By identifying and optimizing slow queries, response times, and caching strategies, you can significantly improve the performance of your Laravel application.
- Cost Reduction: Efficient error handling and performance optimization reduce the resources required to maintain and scale your application, potentially lowering operational costs.
- Better User Experience: Resolving errors and optimizing performance lead to a more stable and responsive application, enhancing user satisfaction and retention.
How to Measure Laravel Performance
Measuring the performance of your Laravel application is crucial for identifying bottlenecks and areas for optimization. Here are some methods for measuring Laravel performance:
- Monitoring Tools: Utilize monitoring tools like SolarWinds Observability SaaS (formerly known as SolarWinds Observability), Blackfire, or Laravel Telescope to monitor application performance, database queries, and request-response cycle times.
- Logging and Error Tracking: Implement comprehensive logging and error tracking using Laravel’s built-in logging system, coupled with services like Papertrail, to monitor application behavior and identify performance issues and errors.
- Database Query Analysis: Analyze database queries using Laravel’s query logging functionality or external database management tools to identify and optimize slow queries.
- Response Time Tracking: Implement middleware to track response times and identify slow-performing routes or actions within your application.
- Caching Strategies: Monitor cache hit rates and utilization to ensure efficient use of caching mechanisms and optimize application performance.
Recap
In this article, you learned how we can use logging to reduce the time and effort spent on debugging your code while improving the performance of your application at the same time.
As you see, you can use logging to reduce the time and effort spent debugging your code while improving the performance of your application at the same time.
Data is your friend and it’s there waiting for you to make use of it! Tools like SolarWinds® Papertrail® make it easier to access logs and debug problems. Check out the Papertrail free trial.