Instrument Queues

Learn how to manually instrument your code to use Sentry's Queues module.

Sentry comes with a queue-monitoring dashboard that can be auto-instrumented by our Laravel SDK.

If you're using something else, you can manually instrument your queue producers and consumers to ensure that you have performance data about your messaging queues.

Wrap your queue producer code into a span. Your span op must be set to queue.publish. Include the following span data to enrich your producer spans with additional metrics:

Data AttributeTypeDescription
messaging.message.idstringThe message identifier
messaging.destination.namestringThe queue or topic name
messaging.message.body.sizeintSize of the message body in bytes

Make sure that there's a transaction running when you create the spans. See Tracing for more information.

You must also include Sentry's trace headers (sentry-trace and baggage) in your queue job's payload so that your consumers can continue your trace once your job is picked up.

Copied
$parentSpan = \Sentry\SentrySdk::getCurrentHub()->getSpan();

if ($parentSpan !== null) {
    $context = \Sentry\Tracing\SpanContext::make()
        ->setOp('queue.publish')
        ->setDescription('App\Jobs\MyJob');

    $span = $parentSpan->startChild($context);

    \Sentry\SentrySdk::getCurrentHub()->setSpan($span);

    // Publish your job to the queue
    Queue::push($job, [
        'publish_time' => microtime(true),
        'sentry_trace' => \Sentry\getTraceparent(),
        'baggage' => \Sentry\getBaggage(),
    ]);
    
    $span
        ->setData([
            'messaging.message.id' => $job->getId(),
            'messaging.destination.name' => $job->getQueue(),
            'messaging.message.body.size' => $job->getSize(),
        ])
        ->finish();

    \Sentry\SentrySdk::getCurrentHub()->setSpan($parentSpan);
}

Wrap your queue consumer code into a span. Your span op must be set to queue.process. Include the following span data to enrich your consumer spans with additional metrics:

Data AttributeTypeDescription
messaging.message.idstringThe message identifier
messaging.destination.namestringThe queue or topic name
messaging.message.body.sizenumberSize of the message body in bytes
messaging.message.retry.countnumberThe number of times a message was attempted to be processed
messaging.message.receive.latencynumberThe time in milliseconds that a message awaited processing in queue

Make sure that there's a transaction running when you create the spans. See Tracing for more information.

Use \Sentry\continueTrace() to connect your consumer transaction to their associated producer spans, and $transaction->setStatus() to mark the trace of your message as success or failed.

Copied
$context = \Sentry\continueTrace(
    $job->getMetadata('sentry_trace'),
    $job->getMetadata('baggage')
)
    ->setOp('queue.process')
    ->setName('App\Jobs\MyJob');

$transaction = \Sentry\startTransaction($context);

\Sentry\SentrySdk::getCurrentHub()->setSpan($transaction);

$job = Queue::pop();

try {
    // Continue job processing...
} catch (\Throwable $e) {
    $transaction->setStatus(\Sentry\Tracing\SpanStatus::internalError());
}

$transaction
    ->setData([
        'messaging.message.id' => $job->getId(),
        'messaging.destination.name' => $job->getQueue(),
        'messaging.message.body.size' => $job->getSize(),
        'messaging.message.receive.latency' =>  microtime(true) - $job->getMetadata('publish_time'),
        'messaging.message.retry.count' => $job->getRetryCount(),
    ])
    ->finish();
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").