Fix DSM queue names with Kafka Connect IBM MQ connectors by johannbotha · Pull Request #10318 · DataDog/dd-trace-java

Summary

When using Kafka Connect with IBM MQ connectors, DSM was reporting incorrect queue names with schema-derived suffixes like _messagebody_0. For example:

  • Incorrect: trainmgt.dispatch.trnsheet.p30.v1.pub_messagebody_0
  • Expected: trainmgt.dispatch.trnsheet.p30.v1.pub

How IBM MQ and Kafka Connect are linked

Kafka Connect IBM MQ connectors (from Confluent or IBM) bridge IBM MQ and Kafka:

┌─────────────┐    ┌─────────────────────────┐    ┌─────────────┐
│   IBM MQ    │◄──►│  Kafka Connect Worker   │◄──►│    Kafka    │
│   Queue     │    │  (with MQ connector)    │    │    Topic    │
└─────────────┘    └─────────────────────────┘    └─────────────┘
                              │
                              │ Uses JMS API internally
                              │ (com.ibm.mq.jms.*)
                              ▼
                   ┌─────────────────────────┐
                   │  dd-trace-java agent    │
                   │  instruments JMS calls  │
                   └─────────────────────────┘

The connector internally uses JMS to communicate with IBM MQ. When dd-trace-java is attached to the Kafka Connect worker JVM, it instruments these JMS calls and creates DSM checkpoints using Queue.getQueueName().

Hypothesis

When the connector creates JMS Queue objects, somehow the queue name returned by getQueueName() includes schema-derived suffixes. This could happen if:

  1. Dynamic destination routing - connector derives queue name from Kafka record fields
  2. Schema field contamination - Kafka Connect's schema converters add _0 suffixes to union/optional fields like messageBody, and this leaks into the destination name
  3. Connector bug - the connector is constructing Queue objects with incorrect names

Why pure Java apps work

Pure Java apps create queues directly:

Queue queue = session.createQueue("my.actual.queue.name");
// getQueueName() returns "my.actual.queue.name" ✓

With Kafka Connect, the connector creates the Queue internally, and something in that process adds the suffix.

Changes

Added sanitization in JMSDecorator.getDestinationName() to strip these suffixes:

  • _messagebody_N
  • _text_N
  • _bytes_N
  • _map_N
  • _value_N

Uses a string-based approach with lastIndexOf() and regionMatches() for performance (avoids Pattern/Matcher overhead).

Test plan

  • Added unit tests in JMSDecoratorTest.groovy covering:
    • Customer's exact queue name from ticket
    • Various schema suffix patterns
    • Edge cases (no suffix, suffix not at end, unknown suffixes)
  • Verify with customer's environment (if possible)

References

  • Fixes Zendesk ticket #2429181
  • JIRA: DSMS-122

🤖 Generated with Claude Code