将失败的队列作业记录到文件回退

时间:2020-08-20 15:07:42

标签: laravel laravel-6 laravel-7

如果MySQL崩溃,是否有任何备用选项可将失败队列作业记录到文件?

我尝试

namespace App\Providers\AppServiceProvider;
function register()

Queue::failing(function (JobFailed $event)  {
    if($event->exception instanceof \PDOException){ 
        $data = [
            'code'              =>  $event->exception->getCode(),
            'connectionName'    =>  $event->connectionName,
            'getQueue'          =>  $event->job->getQueue(),
            'getRawBody'        =>  $event->job->getRawBody(),
            'exception'         =>  (string)$event->exception,
        ];
        \App\Repositories\FailedJobMysqlDown::set($data);
    }
});

但是这可以检查工作失败的原因, 我想抓到插入failed_jobs异常

[2002] No such file or directory (SQL: insert into `failed_jobs` (`connection`, `queue`, `payload`, `exception`, `failed_at`) values (redis, superhigh, {"ty................

有什么想法吗?

谢谢

1 个答案:

答案 0 :(得分:0)

找到解决方案

创建课程

<?php

namespace App\Override;

use Illuminate\Queue\Failed\FailedJobProviderInterface;
use Illuminate\Queue\Failed\DatabaseFailedJobProvider ;
use Illuminate\Support\Facades\Date;

class FallbackDatabaseFailedJobProvider  extends DatabaseFailedJobProvider  implements FailedJobProviderInterface
{
    public function log($connection, $queue, $payload, $exception)
    {
        try{
            return parent::log(...func_get_args());
        }catch (\Exception $e) {
            $failed_at = Date::now();
            $exception = (string) $exception;
            $data = [
                'connectionName'    =>  $connection,
                'getQueue'          =>  $queue,
                'getRawBody'        =>  $payload,
                'exception'         =>  $exception,
                'failed_at'         =>  $failed_at,
            ];
            \App\Repositories\FailedJobMysqlDown::set($data);
        }
    }
}

并在serviceprovider中注册

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Override\FallbackDatabaseFailedJobProvider;

class FailedLogServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Get a default implementation to trigger a deferred binding
        $_ = $this->app['queue.failer'];

        // Swap the implementation
        $this->app->singleton('queue.failer', function ($app) {
            $config = $this->app['config']['queue.failed'];

            return new FallbackDatabaseFailedJobProvider($this->app['db'], $config['database'], $config['table']);
        });
    }
}

添加到提供商中的condig / app.php

'providers' => [
..............
App\Providers\FailedLogServiceProvider::class,
]

使用当前版本或创建自己的实现日志功能

<?php

namespace App\Repositories;

/**
 * Log failed job to file fallback
 */
class FailedJobMysqlDown
{
    private static $file = '_xlogJobFailedMysqlDown'; //set full path

    public static function get(){
        $x = file(self::$file);
        $data = [];
        foreach($x as $line){
            $data[] = json_decode($line);
        }
        return $data;
    }

    public static function set($message){
        $message = json_encode($message);
        file_put_contents(self::$file,$message.PHP_EOL , FILE_APPEND | LOCK_EX );
    }

}

瞧瞧