Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send a slack notification every time Log::error is triggered

Using Laravel 5, I want to be notified (on slack but it does not matter) every time Log::error (or similar) is triggered, by a direct call to this method or by the default ExceptionHandler calling report method. I think I have to extends default Laravel's Log system but I'm not sure. What's the (best) "laravel way" to do this ? (without changing every Log::error calls in my whole code).

First, I thought I only have to change Log Facade to one other but it will not handle the ExceptionHandler (i.e. on 500 errors due to uncaught Exception). One other solution could be add some code directly in the ExceptionHandler, but it will not be triggered if I report an error by Log::error() or some other way (app('logger')->error(), logger()->error(), etc.).

like image 313
rap-2-h Avatar asked Sep 02 '15 13:09

rap-2-h


People also ask

How do I force Slack notifications?

Click the channel or member names in the conversation header. Below the conversation name, click the notifications drop-down menu. Choose your notification preference. Click the close icon in the top right when you're done.

How does Slack decides to send a notification?

Mobile-specific notification preferences Assuming that the notification candidate has made it so far (and so have you!), Slack checks for mobile-specific notification preference for this channel. If none has been set up, they check if you have a preference globally.

Why are my Slack notifications not popping up?

The first thing you should do (again, this is done per workspace) is open Slack and go to File > Preferences. In the Preferences window, click Notifications and make sure it's set to All new messages (Figure 3).


3 Answers

Edit: Broken as of Laravel 5.6

The Log facade is really just a wrapper for an underlying instance of Monolog. The good news is Monolog comes with support for Slack. You just need to tell Monolog to use it.

With that said, everything can be setup in 3 lines of code.

$monolog = \Log::getMonolog();
$slackHandler = new \Monolog\Handler\SlackHandler('your-token', '#your-channel', 'Monolog', true, null, \Monolog\Logger::ERROR);
$monolog->pushHandler($slackHandler);

Then to get this running, you can either create your own service provider for it or just drop it in AppServiceProvider's boot method.

You may want to look at the source code for SlackHandler just in case there are more options the constructor takes which you would need to use.

Now whenever you \Log::error('some error');, that error's message will be sent to the Slack channel you have setup. Please note this "bubbles up" which means it will be sent to the Slack channel for any logging done error and up, error, critical, alert, and emergency. Set the bubble parameter to false if you only want it to log errors.

like image 84
user1669496 Avatar answered Oct 24 '22 02:10

user1669496


For Laravel 5.6 and above:

Laravel suppports slack driver for logging beginning with 5.6. Configure your slack channel in config/logging.php like so:

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

Now all the log messages which have an importance critical or above will automatically logged to slack channel.

You can also log to slack channel specifically:

Log::channel('slack')->info('Something happened!');

More info in Laravel logging and Slack incoming webhooks.

like image 21
Sapnesh Naik Avatar answered Oct 24 '22 02:10

Sapnesh Naik


You can listen to illuminate.log [String $level, String $message, Array $context] event. If $level equals error, you will send notification.

Define event listener in your EventServiceProvider

protected $listen = [
    'illuminate.log' => [
        'App\Listeners\LogEventListener'
    ]
];

This will tell Laravel to fire LogEventListener when illuminate.log event is fired.

Then create this listener:

namespace App\Listeners;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class LogEventListener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  DeployDisabledEvent  $event
     * @return void
     */
    public function handle($event)
    {
        if ($event->type == 'error') {
            $this->notifyViaSlack($event->message, $event->context);
        }
    }

    /**
     * Send Slack notification.
     *
     * @param  string  $message
     * @param  string  $context
     * @return void
     */
    protected function notifyViaSlack($message, $context)
    {
        /*
         * Slack notification logic
         */
    }
}
like image 6
Maxim Lanin Avatar answered Oct 24 '22 03:10

Maxim Lanin