APM transactions with Spring Integration

Hi,

I'd like to ask if it's possible to monitor Spring Integration transactions in APM.

Adding javaagent to our Spring Boot app works flawlessly and the transactions related to REST API invocation show up very nicely in the UI, however, our app also uses Spring Integration framework to listen to JMS messages and process them (storing them in DB, potentially publishing further updates via JMS).

Is it somehow possible to configure the agent to capture those transactions too (i.e. to see how long it took to process a particular message and how many messages were processed)?

Hi @Yaneek , welcome to our forum !

I am not familiar with Spring Integration at all, but JMS messaging should be supported out of the box. Do you have a code sample of how the messages are received in your application ?

A transaction should be created when receiving a message with JMS, and all the downstream spans (store in DB, send other JMS messages) should be supported as well. If the transaction is missing then no span is captured, which is likely why you don't see anything captured outside of REST endpoints on your application.

Could you try first by explicitly creating a transaction when a message is received ?
For example, using startTransaction with our Public API, alternatively you could also use the OpenTelemetry API if you want.

Hi,

I've played with the APM for a while and I've got a bit further, however, the state is still not ideal.

This seems to work only partially. Or, to be precise, the transaction is indeed created when receiving a JMS message (even using Spring Integration), however, the transaction naming seems to rely on JMS headers of the message object itself (as opposed to the actual JMS consumer).

The practical effect is that e.g. when reading messages from MQ where the publisher does not necessarily populate JMS headers (and does not send messages in MQHRF2 format) the all transactions are called just "JMS RECEIVE" and it's impossible to see from which queue the message has been received. That is problematic in a situation where a service reads from multiple queues and we'd like to separate the transactions by queue/type.

Similarly e.g. with Solace, imagine the following scenario. Publishers publish messages to topics. Solace contains (persistent) queues subscribed to particular topics (potentially multiple). Receiver reads messages from queues. In this case, the captured transactions say "JMS RECEIVE from topic A/B/C" even though the receiver actually received a message from a queue (with a particular name), not a topic directly.

I'm using Spring Ingration Java DSL so the receiving/processing code looks something like this

@Bean
public IntegrationFlow myFlow() {
  return IntegrationFlows
          .from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory)
                 .destination(queueName))
          .transform(someTransformer)
          .transform(anotherTransformer)
          .handle(someHandler)
          .get()
}

However, the flow in general does not need to include messaging at all, so according to Java DSL you can create a flow (that keeps printing Hello ...) like this

@Configuration
@EnableIntegration
public class MyConfiguration {

    @Bean
    public AtomicInteger integerSource() {
        return new AtomicInteger();
    }

    @Bean
    public IntegrationFlow myFlow() {
        return IntegrationFlow.fromSupplier(integerSource()::getAndIncrement,
                                         c -> c.poller(Pollers.fixedRate(100)))
                    .filter((Integer p) -> p > 0)
                    .transform(Object::toString)
                    .transform("Hello "::concat)
                    .handle(System.out::println)
                    .get();
    }
}

Ideally I'd like to be able to capture myFlow as a transaction in APM so that I can see how many times a particular flow has executed and how long it took.

The "JMS RECEIVE" should just be the beginning if the name, it should provide further details, eg queue or topic, and more context. I will try to look at this when I get some time

Got some time to look at this. For the topic, the current implementation does as you say, JMS RECEIVE from topic A/B/C" with no further info about the queue. I'll add an enhancement request for queue info here, but I don't know when that would get prioritized. The queue name takes priority if available, so I suspect we'll need a more thorough example of what you are describing (bear in mind we're agent dev not spring dev, so a project that can run would be ideal rather than just a short description and a code fragment). I think having naming depending on the consumer rather than the message header seems odd, but you're right that there should be a fall back when the header doesn't hold the data. This seems like a niche case, so I'm not sure we'd get the time to prioritize it at all. The codebase is fully open source, we'd definitely look at a PR for that since you seem to have a good handle on what you want and a nice working example!