Logging with Laravel 5.6 and Loggly

When creating a website, it’s important to know what’s working and (even more importantly) what isn’t. That’s where logging comes in. Yes, logging, that oft-forgotten art. But, as Guillaume at Logmatic quite rightly points out, “PHP logs in particular are NOT JUST ABOUT ERRORS”. That’s his capitalisation there. He’s stressing the point, and for good reason. Logs can be useful for knowing what IS working too. I took inspiration from this post and got Laravel 5.6 integrated with another log monitoring platform (sorry Logmatic, not you) called Loggly.


  • Use Laravel 5.6 and don’t mess with the core code.
  • Use Laravel’s built-in logging functionality.
  • Capture errors and information logs and store them locally in a file.
  • Also send all logs to a free monitoring service for better interrogation.
  • Ensure local log files are cleared out routinely.
  • Ensure the app can make me a cup of tea.

I don’t think that last objective will be satisfied, but hopefully we’ll do okay on the rest.

Why Loggly?

First and foremost, it’s free. At least for the amount of usage I’m anticipating for this app. There are other platforms out there, and some might even be better. Sentry looked very good too, although that’s geared up more errors rather than general logging. Loggly has a pretty simple interface for seeing what errors and logs are coming in from your app, and there is already a driver for Loggly baked into the Monolog package, which is what Laravel uses. So all smiles here.

Why Laravel 5.6?

Because it’s awesome. More specifically, though, I’m writing this up because the other tutorials I’ve found (including the documentation on Loggly’s own site, at the time of writing) only apply to Laravel 5.5 and below. I used their code and my app spat out an error at me. And no, Loggly did not log that error. So if you’re using Laravel 5.6 and you’re getting an error with the configureMonologUsing()  function, you need to take note of Laravel 5.6’s upgrade guide, and follow my instructions below.


First, let’s make sure we’re using the most up to date version of Monolog.

composer require monolog/monolog

There, that was easy.

Integrating Loggly

Now let’s open up /config/services.php, and add the following to the bottom of the array:


return [
  // ...

  'loggly' => [
    'key' => env('LOGGLY_KEY'),
    'tag' => str_replace(' ', '_', env('APP_NAME') . '_' . env('APP_ENV')),

We’re replacing any spaces with underscores so that Loggly accepts it properly. You’ll also notice there are a couple of environment parameters there, so let’s add those to our .env file:


Obviously you’ll need your own key. If you haven’t done so already, register for your free Loggly account, log in, go to Source Setup > Customer Tokens, and grab your customer token (create a new one if there isn’t one already there). That’s your key, so pop it in your .env file.

The ‘tag’ in the array above is how Loggly will identify your app. You can include various different sources in the same account if you want to, and the tag is what identifies where the log has come from. We’re including a reference to the environment to differentiate my local tests from production.

Next we need to tell Laravel how it’s going to get the logs into Loggly, and this is where the process differs compared to Laravel 5.5. Rather than calling $app->configureMonologUsing() , we need to set up a custom logger class. To be honest, while it looks like more work, I prefer the design pattern going on here. We need to create a new PHP class at /app/Logging/LogglyLogger.php, which will look like this:


namespace AppLogging;

use MonologHandlerLogglyHandler;
use MonologLogger;

class LogglyLogger {

    public function __invoke($config) {
        $logger = new Logger(env('APP_NAME'));
        $logger->pushHandler(new LogglyHandler(env('LOGGLY_KEY') . '/tag/' . config('services.loggly.tag'), Logger::INFO ));
        return $logger;


This tells Laravel that logs with a level higher than INFO (which is basically everything) need to be handled by Loggly. Note that we’re also setting a tag using the settings we defined in config/services.php. Now all we need to do is tell Laravel to use it. Let’s open up /config/logging.php, and add the following to the array:


return [
  'default' => env('LOG_CHANNEL', 'stack'),

  'channels' => [
    'stack' => [
      'driver' => 'stack',
      'channels' => ['custom', 'daily'],

    // ...
    'custom' => [
      'driver' => 'custom',
      'via' => AppLoggingLogglyLogger::class,

The ‘stack’ channel is useful because it means we can route our logs to more than one channel, which is exactly what we want in this case because we want them saved locally as well as sent to Loggly. I’ve used ‘channels’ => [‘custom’, ‘daily’] . You’ll see I’ve also linked up that custom class we just created.

All being well, that should be all you need to do. Fire up your app and generate an error, and it should appear in Loggly. You should also find a log file in /storage/logs/ with exactly the same error.

Moar logs

As I said (or did I quote?) at the beginning, logs are for more than just errors. So remember that you can (and should) include logging of useful information elsewhere in your app. For example, you might want to log successful user logins, failed logins, or indeed any other interaction. Think about it this way – if someone came to you and described a problem they were having and you needed to trace it back, what information would you need? Log it.

Log::info('User login successful', ['user_id' => $user->id]);


An important consideration is that logs may contain Personally Identifiable Information. As per the GDPR regulations coming into force in May 2018, it’s worth making sure we treat these logs with respect and care.

One tenet of GDPR is ‘don’t store PII unless you need it’. So don’t log absolutely everything. Anonymise the log if you can. You’ll see in my example above I’m including the user ID but not the actual login details. Never store passwords. A good rule of thumb is to think about how embarrassing or costly it would be if someone else got hold of your logs.

Another piece of advice is ‘don’t keep PII longer than absolutely necessary’. How you define ‘absolutely necessary’ is up for debate, and probably depends on your app and the contents and context of the log itself. I’ve set up my app to store each day’s logs in its own local file, rather than dumping them all in one massive file. The Monolog library comes with its own log retention mechanism, so we can simply add the following line into our /config/app.php file and logs will only be kept for 5 days:

'log_max_files' => 5,

Loggly themselves are also keen to reassure us that GDPR is important to them too. They currently have a statement on their privacy policy about their commitment to GDPR. It doesn’t really give us much detail, but be assured that your data should be safe, and handled properly, and if you need to ask them specific questions about how and where your data is stored they’ll be happy to help.


Laravel is awesome. Loggly is awesome. Integrating the two is relatively straightforward. You can (and should) log user events as well as errors. You can keep the GDPR people happy by only logging what you need, and deleting it once it’s no longer useful.

Give it a go, and let me know how you get on, either in the comments below or on Twitter.

One thought on “Logging with Laravel 5.6 and Loggly

  1. Hey! Nice article. Helped my a bunch. A could achieve the same with just:

    ‘loggly’ => [
    ‘driver’ => ‘monolog’,
    ‘handler’ => LogglyHandler::class,
    ‘with’ => [
    ‘token’ => env(‘LOGGLY_TOKEN’),


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.