A trace that ends when a job is enqueued covers the fast half of the work and none of the half that fails.
// on dispatch
dispatch(new SyncOrder($order))->withContext([
'correlation_id' => $request->correlationId(),
]);
// in the worker, before anything else
Log::withContext(['correlation_id' => $this->correlationId]);
// and it must propagate again from the job to any
// HTTP call the job makes. one gap breaks the chain.
The identifier has to be carried explicitly on the message, because a queue is a process boundary and nothing is ambient across it. Every hop that drops it produces two disconnected traces that look like unrelated events, and the drop is usually at the boundary somebody wrote in a hurry. A middleware that reads it on the way in and attaches it on the way out is the only version that survives, since a convention applied by hand will be forgotten.