Realtime logging in Laravel using Slack
Tags: laravel, php, slack, logging
Published: 2023-09-11 08:00:00

To help developers know what is going on within their application, Laravel provides robust logging services that allow you to log messages to files, the system error log, and various other destinations.

In this tutorial, I will cover the following:
1. Introduction to logging
2. Overview of the Laravel log configuration file
3. Setting up slack for real-time logging.

#### Introduction to logging
Logging in Laravel is channel-based, and each channel defines a specific way of writing log messages. For example, the `single` channel writes log files to a single log file, while the `daily` channel writes log to file based on date e.g. `laravel-2023-01-09.log`, and the `slack` channel sends log messages to Slack.

There are several cool packages that help to visualize our logs like [ARCANEDEV/LogViewer](https://github.com/ARCANEDEV/LogViewer), [rap2hpoutre/laravel-log-viewer](https://github.com/rap2hpoutre/laravel-log-viewer), and [opcodesio/log-viewer](https://github.com/opcodesio/log-viewer)

Also, you can check my previous article [send logs to telegram](https://dev.to/dotmarn/how-to-send-application-logs-to-telegram-in-laravel-1l12) where I covered how to set up a telegram bot to handle our application log.

#### Overview of Laravel Log Configuration file

Laravel provides you with great configuration flexibility which is housed in the `config/logging.php` file. This file allows you to configure your application's log channels, so let's take a look at the default file below:

```php
<?php

use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;

return [

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

    'deprecations' => [
        'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
        'trace' => false,
    ],

    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['single'],
            'ignore_exceptions' => false,
        ],

        'single' => [
            'driver' => 'single',
            'path' => storage_path('logs/laravel.log'),
            'level' => env('LOG_LEVEL', 'debug'),
        ],

        'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/laravel.log'),
            'level' => env('LOG_LEVEL', 'debug'),
            'days' => 14,
        ],

        'slack' => [
            'driver' => 'slack',
            'url' => env('LOG_SLACK_WEBHOOK_URL'),
            'username' => 'Laravel Log',
            'emoji' => ':boom:',
            'level' => env('LOG_LEVEL', 'critical'),
        ],

        'papertrail' => [
            'driver' => 'monolog',
            'level' => env('LOG_LEVEL', 'debug'),
            'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
            'handler_with' => [
                'host' => env('PAPERTRAIL_URL'),
                'port' => env('PAPERTRAIL_PORT'),
                'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
            ],
        ],

        'stderr' => [
            'driver' => 'monolog',
            'level' => env('LOG_LEVEL', 'debug'),
            'handler' => StreamHandler::class,
            'formatter' => env('LOG_STDERR_FORMATTER'),
            'with' => [
                'stream' => 'php://stderr',
            ],
        ],

        'syslog' => [
            'driver' => 'syslog',
            'level' => env('LOG_LEVEL', 'debug'),
        ],

        'errorlog' => [
            'driver' => 'errorlog',
            'level' => env('LOG_LEVEL', 'debug'),
        ],

        'null' => [
            'driver' => 'monolog',
            'handler' => NullHandler::class,
        ],

        'emergency' => [
            'path' => storage_path('logs/laravel.log'),
        ],
    ],

];
```
From the config file, you can see different options available for use. Let's review a few of these options and what they do. We will use the `daily` option.

```php
'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/laravel.log'),
            'level' => env('LOG_LEVEL', 'debug'),
            'days' => 14,
        ],
```
`driver`: This tells laravel the driver to use.
`path`: This tells Laravel where to write the logs to.
`level`: This tells Laravel the type of log to be handled by this channel. It can be `debug`, `critical`, `warning` etc.
`days`: The `days` option tells Laravel how long the log should be retained before deleting.
You can read more about logging from the [official documentation](https://laravel.com/docs/9.x/logging#main-content).

#### Setting up Slack for Logging
Let's proceed by creating an app on [Slack](https://api.slack.com/apps/). Click on the **Create New App** button and select the first option as seen in the image below.

![slack dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j2iecwrb7cgmz93h5n6y.png)

Fill in the app name, select a workspace for the app and click the **create app** button to save the form.

![App setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ihkcrabeowwoxjpuhite.png)
Now that our app has been created, select the `incoming webhooks` option and activate the toggle on the next screen shown to you.

![Webhook Setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1a4z7bo3fnwfxzu5m9g.png)

Scroll down to the bottom of the page and click on **Add New Webhook to Workspace**. On the next screen shown to you, select a channel and click on **Allow**

![Webhook Access grant](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3as6e8aztedss4opc7r6.png)

Slack will now generate a webhook URL for us. Copy it, head over to your `.env` file and add it to your app like below.

```php
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxxxxxxxxx
```
Open up the `logging.php` file then under **channels** array, since the default is set to stack, let's change the channels to `slack` from `single` and save the file.

```php
'stack' => [
            'driver' => 'stack',
            'channels' => ['slack'],
            'ignore_exceptions' => false,
],
```
Let's test it out by opening up [Tinker](https://laravel.com/docs/9.x/artisan#tinker) and run the command below:

```php
info("This is just a tutorial demo logging");
```

![Slack channel logging test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9sjgomizwo3x2d3oe5l.png)

Voila!!!

#### Wrapping up
In this article, you have learned about logging in to Laravel and how to set up Slack to receive your application logs in real time.

Don't forget to give me a shoutout on [LinkedIn](https://www.linkedin.com/in/kasim-ridwan/) & [Twitter](https://twitter.com/oluwalosheyii)