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.
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
.
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.
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.
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.
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.
Looking for answers?
Start a new discussion or ask for help in our Q&A forum.
Go to forum