More Effective PHP Logging with Loggly
This article was sponsored by Loggly. Thank you for supporting the sponsors who make SitePoint possible.
Server overloaded, library throwing an exception, error while sending email: these errors are unfortunately part of every system. If you’re in charge of making a system function well, that’s still cold comfort. What’s more, I bet you already have all the data you need to solve them sitting in your log files.
But having access to that data doesn’t really help unless you have a way to store, process, and analyse that data. In this article I’ll explain how to use this data more effectively by using a PHP logging library with a proper log management solution (in this case, Loggly). I’ll also show an example of how to use a log management service to store and analyze them easier.
When logging with PHP, we tend to use the error_log and trigger_error functions, or we can use an error handler to make the logging process more generic. If you choose to do it this way, you’ll need to wrap your functions inside some kind of object to make things cleaner and flexible. You can also forward your logs directly to your system to handle them, using the syslog function.
openlog('php', LOG\_CONS | LOG\_NDELAY | LOG\_PID, LOG\_USER | LOG\_PERROR); syslog(LOG\_ERR, 'Error!'); syslog(LOG\_INFO, 'Hello World!'); closelog();
But what would you do if you had to log to multiple places at the same time, or you were sending logs to a given service depending on the error level? Rather than using built-in tools, it’s often easier to use logging libraries.
Why I Use Monolog
- It’s PSR-3 compliant
- Includes handlers for a variety of services, including Loggly.
- Support for formatters to customise your logs output.
- Helpers for development logging like the BrowserConsoleHandler for logging to the browser console.
Make sure to check the documentation for more details about the package. Most popular frameworks include Monolog out of the box, so check the full list on the documentation. If you don’t have Monolog installed, you can add it to a project using Composer.
composer require monolog/monolog
The Problems of Logging at Scale
Since logging requires writing to the disk, doing backups and searching files, some companies create a separate service to handle the job (usually a set of scripts or apps to grep files searching for info when some kind of error occurs). As your company or service scales up, this can quickly become a nightmare for your developers and analysts. Another, better, alternative is a cloud based service for their log storage and analysis and this has a lot of benefits, as we’ll discuss further in this article.
What Is Loggly?
There are several log management services that will make storing and analyzing your logs easier. Loggly is the most popular one and it has several ways to integrate with PHP. Once Loggly receives your logs, you’ll be able to search, group and visualize your data in a really impressive way. You can try it for free. You only pay if you have sizable traffic on your site. Let’s start first by looking on how to install it on your server to track your system logs.
Using Loggly with Monolog
If you decided to go with the Monolog package library for your logging process, it’s very easy to get it integrated with any log management service, including Loggly.
By default, it comes with a LogglyHandler for Loggly.
$logger = new \Monolog\Logger('local_test_app'); $logger->pushHandler(new \Monolog\Handler\LogglyHandler('YOUR_TOKEN/tag/monolog'));
After creating a Monolog instance, we’ll push our handler to the list of registered handlers, and you’ll need to provide your token as previously mentioned. The tag part is optional, but it’s always a good idea to separate your log entries by tagging them accordingly. Now we’re ready to start logging to our service using Monolog.
$logger->addInfo("Info test from monolog"); //$logger->addWarning("Warning test from monolog");
Loggly with Laravel
Since Laravel is using Monolog for the logging process, we can easily bind our handler to it.
$handler = new \Monolog\Handler\LogglyHandler('YOUR_TOKEN/tag/monolog'); $logger = Log::getMonolog(); $logger->pushHandler($handler); // using the Log facade Log::info("Test from Laravel"); Log::warning("Test from Laravel");
Configuring Loggly on Heroku
When you move your application to production, you want to make sure that your logs tracking is working properly. In this section we are going to attach Loggly to our Heroku application. Heroku uses Log Drains to help you forward your logs to an external logging service. You can check the documentation for more details about the installation process.
heroku drains:add https://logs-01.loggly.com/bulk/TOKEN/tag/heroku --app HEROKU_APP_NAME
You need to update the
TOKEN with your actual token that you can find on the Source setup > Customer Tokens page. The
HEROKU_APP_NAME can be omitted if you’re already logged into your Heroku instance, otherwise you need to specify your Heroku application name.
The drain URL ends with
tag/heroku, this will help us filter our logs using the defined tag, we will talk more about this later.
Analyzing Logs with Loggly
Now that we’ve discussed how to send your logs to Loggly, we can start analysing and working with our data. The search page provides a set of tools to filter, analyze and visualise our logs.
The dashboard shows a timeline of your events along with a list of logs at the bottom. The top of the page contain a search box and a date range to filter events, you can select the last 30 minutes or specify a custom date range for example and click search to validate.
You can use the search input to filter data using a specific term like “email” or “event_*”. Loggly will search inside the body of your log entries and display the result at the bottom of the page. You can also use fields for searching, like “tag:monolog” to filter the events sent previously from Monolog. The left side menu is called the Dynamic Field Explorer and it can help you identify the available field filters.
Let’s take the following examples to better understand how to analyze logs.
Internal Server Errors
An internal server error is thrown when your server was unable to process a valid request from the user. In PHP, details about this error can be found inside your Apache logs, if you register an error handler using PHP you can group your own log files so you can analyze them and fix errors according to the log message.
You can use the Field Explorer widget on the left side of the page to filter down logs using the
apache 5XX status code. The search can be specific like “apache.status:500” or you can make it more generic like “apache.status:[500 TO 599]”.
In PHP, when a fatal error is thrown, the program will stop the execution and log the error to your system. Because fatal errors are not supposed to happen on production, Loggly provides an easy way to track errors’ severity from different sources. The “syslog.appName:php” term will only show PHP logs, now we need to show errors from a specific severity using the syslog.severity:Error term, we can also specify a range like “syslog.severity:[Warning TO Error]”. You can read more about the list of available fields on the documentation.
syslog.appName:php AND syslog.severity:Error
Most of the time we’re displaying results as a list, but you may want to use another graph from the list of charts at the bottom of the page.
One of my favorite features on Loggly is the alerts tool. You can configure Loggly to send notifications to your email or another service whenever an action occurs on your application. Lets go through the process in detail.
First you need to create a new search and save it. Lets take this search for example: “syslog.appName:php AND php.level:”Fatal Error””
This will show us the list of PHP fatal errors on our system. Next, we need to save this search criteria. Click on the little star on the top right of the dashboard page, select the “Save this search as…” item and name the search.
Now we can go to the list of alerts and click Add new to create a new one. After giving a name and a description to your alert, you can select a saved search from the list and a condition (Alert if count is >= 1 within 5 minutes). For my example I will send an email notification, but if you have a service that automatically passes the error to your team for verification, you can configure it to post it to your endpoint. You can read more about alerts on the documentation.
Loggly can change the way you deal with your logs, from regexp search to archiving. The service also has great UX, and the documentation is very straightforward, covering the majority of the possibilities. You can start with a free trial to test all the features. If you have any questions, feel free to post them below and I will do my best to answer them.
How do you make PHP logging easier?