Header background

End-to-end tracing now available for batch style queue programs

We recently announced the availability of end-to-end request tracing across JMS and RabbitMQ queues. Such request tracing works perfectly as long as you use the recommended approaches to consuming messages: the JMS Message Listener or, in case of RabbitMQ, the Message Consumer. This is not always the case however. Consider the following example:
while (true)
{
GetResponse resp = channel.basicGet(QUEUE_NAME, true);
if (resp != null)
{
processMessage(resp);
}else
Thread.sleep(500);
}

This example program dequeues messages from a Rabbit MQ queue and processes them. While this isn’t the recommended approach, in many cases applications are written this way for one reason or another. In particular, batch processes often work this way. Not to worry. This approach is supported by Dynatrace and results in the following Service flow. As you can see, the message is traced from the Sender custom service via the hello queue and it’s consumed by the Queue Listener on another process.

request tracing

What’s missing, however, is the service on the consuming side that processes the message. Looking at the single PurePath things are clearer. As you can see, the message is published by the Sender custom service and it’s consumed by the RabbitMQ Queue Listener.

request tracing

In the code level view below you can see the basicGet method from our code snippet, but this is where it stops. Any processing or further action triggered by the message processing isn’t captured and therefore your visibility is reduced.

request tracing

Looking at the code snippet again, it may be perfectly clear to you that the processMessage method processes the message and takes further action. However, looking at this from a more abstract point of view, how can OneAgent know this? In fact, the code block following the basicGet method could be far more complicated.
while (true)
{
GetResponse resp = channel.basicGet(QUEUE_NAME, true);
if (resp != null)
{
processMessage(resp);
}else
Thread.sleep(500);
}

To understand how this message is processed, you must first define a custom service for the processMessage method and create a new monitored service based on this method (Settings  > Server-side service monitoring > Custom service detection). This tells Dynatrace that you consider this message-processing method to be an important service that needs to be monitored. Secondly, instruct Dynatrace that this method is used to process a message by enabling the This service is used inside a busy loop to process dequeued messages of a queue setting (see example below).

This simple action makes all the difference. The same Serviceflow view now shows that the new Custom Messaging service is called by the Queue Listener, as we would expect based on the sample code snippet.

request tracing

Viewing the same PurePath we can now see that the processing was added beneath the basicGet method as an asynchronous action. Importantly, note that this only happens if the code does indeed receive a message. Null results and the subsequent sleep aren’t recorded.

request tracing

The result is end-to-end request tracing visibility for scenarios that include a busy loop or batch approach instead of the more vanilla consumer approach. In many cases, this makes a big difference.

Attention: This feature requires OneAgent v1.129 or higher.