binarybuilds/filament-failed-jobs
Installation:
composer require binarybuilds/filament-failed-jobs
Publish the config (optional):
php artisan vendor:publish --provider="BinaryBuilds\FilamentFailedJobs\FilamentFailedJobsServiceProvider"
Register the Plugin:
In your PanelServiceProvider (e.g., app/Providers/Filament/AdminPanelProvider.php):
use BinaryBuilds\FilamentFailedJobs\FilamentFailedJobsPlugin;
$panel->plugin(FilamentFailedJobsPlugin::make());
First Use Case:
Access the Failed Jobs resource via the Filament admin panel sidebar. The table will display all failed jobs from your failed_jobs database table, with columns for:
Monitoring Failed Jobs:
queue, connection, or failed_at range.attempts or failed_at to prioritize troubleshooting.high_priority queue jobs with >3 attempts:
// Customize the query in config/filament-failed-jobs.php
'query' => function ($query) {
return $query->where('queue', 'high_priority')
->where('attempts', '>', 3);
},
Retrying Jobs:
RetryFailedJob action:
use BinaryBuilds\FilamentFailedJobs\Actions\RetryFailedJob;
class CustomRetryAction extends RetryFailedJob {
protected function handle(): void {
// Custom logic before retrying (e.g., log, modify payload)
parent::handle();
}
}
Pruning Jobs:
schedule:
// app/Console/Kernel.php
$schedule->command(\BinaryBuilds\FilamentFailedJobs\Console\PruneFailedJobs::class)
->dailyAt('03:00');
Integration with Job Events:
failed_job events to log context (e.g., user ID, request data):
// app/Providers/EventServiceProvider.php
protected $listen = [
\Illuminate\Queue\Events\JobFailed::class => [
\App\Listeners\LogFailedJob::class,
],
];
Custom Columns:
Add a column to display the job’s class or extract payload data (e.g., user ID):
use Filament\Tables\Columns\TextColumn;
TextColumn::make('job_class')
->getStateUsing(fn ($record) => class_basename($record->payload['data']['command']))
->sortable(),
Job-Specific Actions: Add a custom action (e.g., "Requeue with Delay") by extending the resource:
use Filament\Tables\Actions\Action;
Action::make('requeue_with_delay')
->action(function (FailedJob $record) {
$record->release(60); // Delay by 60 seconds
}),
Soft Deletes:
Enable soft deletes in config/filament-failed-jobs.php:
'uses_soft_deletes' => true,
Then use the Restore action to recover purged jobs.
Payload Size Limits:
payload column truncates data for readability. For large payloads, use a details modal or custom column:
TextColumn::make('payload_preview')
->limit(100)
->toggleable(isToggledHiddenByDefault: true),
Queue Connection Mismatches:
connection column matches your queue configuration. If jobs appear with null, verify your queue driver (e.g., sync, database, redis) is correctly set in config/queue.php.Permission Issues:
view filament-failed-jobs permission. Add to your policy:
public function viewFailedJobs(User $user): bool {
return $user->isAdmin(); // Example
}
Database Locking:
// In a custom action
FailedJob::whereIn('id', $ids)->chunk(50, function ($jobs) {
foreach ($jobs as $job) {
$job->release();
}
});
Log Failed Job Payloads: Add a listener to log payloads for debugging:
public function handle(JobFailed $event) {
\Log::debug('Failed job payload:', [
'payload' => $event->job->payload,
'exception' => $event->exception,
]);
}
Test Retry Logic:
Use Laravel’s fake queue to test retry behavior:
$this->queue->fake();
$job = new MyJob();
$job->fail();
$this->assertDatabaseHas('failed_jobs', ['id' => $job->getJobId()]);
Clear Failed Jobs:
Reset the failed_jobs table for testing:
php artisan queue:flush
php artisan migrate:fresh --env=testing
Customize the Resource:
Extend the FailedJobsResource class to add fields or actions:
namespace App\Filament\Resources;
use BinaryBuilds\FilamentFailedJobs\Resources\FailedJobsResource as BaseResource;
class FailedJobsResource extends BaseResource {
public static function form(Form $form): Form {
return $form->schema([
// Add custom fields
]);
}
}
Override the Plugin:
Replace the default plugin registration in your PanelServiceProvider:
$panel->plugin(
FilamentFailedJobsPlugin::make()
->navigationIcon('heroicon-o-exclamation-circle')
->navigationLabel('Failed Jobs Monitor')
);
Add Metadata to Jobs: Extend your job class to include custom metadata in the payload:
class MyJob implements ShouldQueue {
public function handle() {
// Job logic
}
public function metadata(): array {
return [
'user_id' => auth()->id(),
'source' => 'admin_panel',
];
}
}
Then display it in the table:
TextColumn::make('metadata.user_id'),
How can I help you explore Laravel packages today?