Skip to content

Commit 2599bc4

Browse files
joseclJose Rodrigueztaylorotwell
authored
[11.x] Add --json flag to queue:work command for structured logging (#52887)
* feat(worker): Adds json sopport to queue:work command * feat: duration job time in seconds to be friendly with tools like Grafana * feat: add 'level' key with: 'info' or 'warning' * chore: Reorganization of initial log * lint * lint * formatting --------- Co-authored-by: Jose Rodriguez <[email protected]> Co-authored-by: Taylor Otwell <[email protected]>
1 parent b273941 commit 2599bc4

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

src/Illuminate/Queue/Console/WorkCommand.php

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Illuminate\Support\InteractsWithTime;
1616
use Symfony\Component\Console\Attribute\AsCommand;
1717
use Symfony\Component\Console\Terminal;
18+
use Throwable;
1819

1920
use function Termwind\terminal;
2021

@@ -44,7 +45,8 @@ class WorkCommand extends Command
4445
{--sleep=3 : Number of seconds to sleep when no job is available}
4546
{--rest=0 : Number of seconds to rest between jobs}
4647
{--timeout=60 : The number of seconds a child process can run}
47-
{--tries=1 : Number of times to attempt a job before logging it failed}';
48+
{--tries=1 : Number of times to attempt a job before logging it failed}
49+
{--json : Output the queue worker information as JSON}';
4850

4951
/**
5052
* The console command description.
@@ -113,7 +115,7 @@ public function handle()
113115
// connection being run for the queue operation currently being executed.
114116
$queue = $this->getQueue($connection);
115117

116-
if (Terminal::hasSttyAvailable()) {
118+
if (! $this->option('json') && Terminal::hasSttyAvailable()) {
117119
$this->components->info(
118120
sprintf('Processing jobs from the [%s] %s.', $queue, str('queue')->plural(explode(',', $queue)))
119121
);
@@ -183,20 +185,35 @@ protected function listenForEvents()
183185
});
184186

185187
$this->laravel['events']->listen(JobFailed::class, function ($event) {
186-
$this->writeOutput($event->job, 'failed');
188+
$this->writeOutput($event->job, 'failed', $event->exception);
187189

188190
$this->logFailedJob($event);
189191
});
190192
}
191193

194+
/**
195+
* Write the status output for the queue worker for JSON or TTY.
196+
*
197+
* @param Job $job
198+
* @param string $status
199+
* @param Throwable|null $exception
200+
* @return void
201+
*/
202+
protected function writeOutput(Job $job, $status, Throwable $exception = null)
203+
{
204+
$this->option('json')
205+
? $this->writeOutputAsJson($job, $status, $exception)
206+
: $this->writeOutputForCli($job, $status);
207+
}
208+
192209
/**
193210
* Write the status output for the queue worker.
194211
*
195212
* @param \Illuminate\Contracts\Queue\Job $job
196213
* @param string $status
197214
* @return void
198215
*/
199-
protected function writeOutput(Job $job, $status)
216+
protected function writeOutputForCli(Job $job, $status)
200217
{
201218
$this->output->write(sprintf(
202219
' <fg=gray>%s</> %s%s',
@@ -235,6 +252,45 @@ protected function writeOutput(Job $job, $status)
235252
});
236253
}
237254

255+
/**
256+
* Write the status output for the queue worker in JSON format.
257+
*
258+
* @param \Illuminate\Contracts\Queue\Job $job
259+
* @param string $status
260+
* @param Throwable|null $exception
261+
* @return void
262+
*/
263+
protected function writeOutputAsJson(Job $job, $status, Throwable $exception = null)
264+
{
265+
$log = array_filter([
266+
'level' => $status === 'starting' || $status === 'success' ? 'info' : 'warning',
267+
'id' => $job->getJobId(),
268+
'uuid' => $job->uuid(),
269+
'connection' => $job->getConnectionName(),
270+
'queue' => $job->getQueue(),
271+
'job' => $job->resolveName(),
272+
'status' => $status,
273+
'result' => match (true) {
274+
$job->isDeleted() => 'deleted',
275+
$job->isReleased() => 'released',
276+
$job->hasFailed() => 'failed',
277+
default => '',
278+
},
279+
'attempts' => $job->attempts(),
280+
'exception' => $exception ? $exception::class : '',
281+
'message' => $exception?->getMessage(),
282+
'timestamp' => $this->now()->format('Y-m-d\TH:i:s.uP'),
283+
]);
284+
285+
if ($status === 'starting') {
286+
$this->latestStartedAt = microtime(true);
287+
} else {
288+
$log['duration'] = round(microtime(true) - $this->latestStartedAt, 6);
289+
}
290+
291+
$this->output->writeln(json_encode($log));
292+
}
293+
238294
/**
239295
* Get the current date / time.
240296
*

0 commit comments

Comments
 (0)