I need to schedule a few tasks on an application built using Laravel and I would like to send a slack notification after those tasks are finished with the output.
Laravel provides an "after" hook (https://laravel.com/docs/5.8/scheduling#task-hooks) so I can do something like this:
$schedule->command('mycommand')
->daily()
->after(function () {
// How can I access the command's name and output from here?
});
I've tried with $this->output
but $this
points to App\Console\Kernel
and it says Undefined property: App\Console\Kernel::$output
. I've also tried to pass a parameter to the closure, but I think I need to specify a type, but I have no idea and the documentation is not very clear.
Anyone has any idea on how to do this?
Thanks in advance!
Assuming you have this in your command
$this->info('hello');
In your kernel, you can send the output to a temporary file and then read the file and send it
/** @var \Illuminate\Console\Scheduling\Event $command */
$command = $schedule->command('mycommand')
->daily()
->sendOutputTo('storage/app/logs.txt');
$command->after(function () use ($command) {
\Log::debug([$command->command, $command->output]);
\Log::debug(file_get_contents($command->output));
});
You will get
[2019-10-11 13:03:38] local.DEBUG: array (
0 => '\'/usr/bin/php7.3\' \'artisan\' command:name',
1 => 'storage/app/logs.txt',
)
[2019-10-11 13:03:38] local.DEBUG: hello
Maybe it would be the time to re-open this proposal https://github.com/laravel/ideas/issues/122#issuecomment-228215251
Define a macro for the console scheduling event in your app service provider:
namespace App\Providers;
use Illuminate\Console\Scheduling\Event;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Event::macro('slackOutput', function (bool $onlyIfOutputExists = false): self {
return $this->thenWithOutput(
function ($output) {
$level = $this->exitCode === 0
? 'info'
: 'error';
Log::channel('slack')
->log(
$level,
$this->getEmailSubject(),
[
'output' => $output,
]
);
},
$onlyIfOutputExists
);
});
}
}
Use it like this if you want slack logs even if there's no output:
$schedule
->command('inspire')
->slackOutput();
Use it like this if you want slack logs only when there is output:
$schedule
->command('inspire')
->slackOutput(true);
I am on Laravel 9. YMMV.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With