Instrument Queues

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

Sentry comes with automatic instrumentation for the most common messaging queue systems. In case yours isn't supported, you can still instrument custom spans and transactions around your queue producers and consumers to ensure that you have performance data about your messaging queues.

To start capturing performance metrics, use the StartSpan() function to wrap your queue producer events. Your span op must be set to queue.publish. Include the following span data to enrich your producer spans with queue 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

Your queue.publish span must exist inside a transaction in order to be recognized as a producer span. If you are using a supported framework, the transaction is created by the integration. If you are using plain Go, you can start a new one using sentry.StartTransaction().

You must also include trace headers in your message so that your consumers can continue your trace once your message is picked up.

Copied
connection := my_custom_queue.Connect()

// The message you want to send to the queue
queue := "messages"
message := "Hello World!"
messageId := "abc123"

// Create transaction
transaction := sentry.StartTransaction(
    ctx,
    "queue_producer_transaction,
    options...,
)
defer transaction.Finish()

// Create the span
span := transaction.StartSpan(ctx, "queue.publish")
span.Description = "queue_producer";
defer span.Finish()

// Set span data
span.SetData("messaging.message.id", messageId)
span.SetData("messaging.destination.name", queue)
span.SetData("messaging.message.body.size", utf8.RuneCountInString(message))

// Publish the message to the queue (including current time stamp)
now := time.Now().Unix()
connection.Publish(queue, message, now)

To start capturing performance metrics, use the startChild() function to wrap your queue consumers. Your span op must be set to queue.process. Include the following span data to enrich your consumer spans with queue 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

Your queue.process span must exist inside a transaction in order to be recognized as a consumer span. If you are using a supported framework, the transaction is created by the integration. If you are using plain Go, you can start a new one using sentry.StartTransaction().

Use Sentry.StartTransaction() to connect your consumer spans to their associated producer spans, and set the span Status to mark the trace of your message as success or failed.

Copied
connection := my_custom_queue.Connect()

// Pick up message from queues
queue := "messages"
message := connection.Consume(queue)

// Calculate latency (optional, but valuable)
now := time.Now()
messageTime := time.Unix(message["timestamp"].(int64), 0)
latency := now.Sub(messageTime)

// Create transaction
transaction := sentry.StartTransaction(
    ctx, // Continue the trace from the message
    "queue_consumer_transaction",
    options...,
)
defer transaction.Finish()

// Create the span
span := transaction.StartSpan(ctx, "queue.process")
span.Description = "queue_consumer";
defer span.Finish()

// Set span data
span.SetData("messaging.message.id", message["message_id"])
span.SetData("messaging.destination.name", queue)
span.SetData("messaging.message.body.size", len(message["body"].(string)))
span.SetData("messaging.message.receive.latency", latency)
span.SetData("messaging.message.retry.count", 0)

// Process the message
err = processMessage(message)
if err != nil {
    // In case of an error set the status to "internal_error"
    span.Status = sentry.SpanStatusInternalError
}
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").