33import static datadog .trace .bootstrap .instrumentation .api .InstrumentationTags .RECORD_QUEUE_TIME_MS ;
44
55import datadog .trace .api .DDSpanTypes ;
6+ import datadog .trace .api .Function ;
7+ import datadog .trace .api .Functions .Join ;
8+ import datadog .trace .api .Functions .PrefixJoin ;
9+ import datadog .trace .api .cache .DDCache ;
10+ import datadog .trace .api .cache .DDCaches ;
611import datadog .trace .bootstrap .instrumentation .api .AgentSpan ;
712import datadog .trace .bootstrap .instrumentation .api .Tags ;
813import datadog .trace .bootstrap .instrumentation .api .UTF8BytesString ;
@@ -21,15 +26,38 @@ public final class JMSDecorator extends ClientDecorator {
2126 public static final CharSequence JMS_CONSUME = UTF8BytesString .create ("jms.consume" );
2227 public static final CharSequence JMS_PRODUCE = UTF8BytesString .create ("jms.produce" );
2328
29+ private static final Join QUEUE_JOINER = PrefixJoin .of ("Queue " );
30+ private static final Join TOPIC_JOINER = PrefixJoin .of ("Topic " );
31+
32+ private final DDCache <CharSequence , CharSequence > resourceNameCache =
33+ DDCaches .newFixedSizeCache (32 );
34+
35+ private final String resourcePrefix ;
36+
37+ private final UTF8BytesString queueTempResourceName ;
38+ private final UTF8BytesString topicTempResourceName ;
39+
40+ private final Function <CharSequence , CharSequence > queueResourceJoiner ;
41+ private final Function <CharSequence , CharSequence > topicResourceJoiner ;
42+
2443 private final String spanKind ;
2544 private final String spanType ;
45+
2646 public static final JMSDecorator PRODUCER_DECORATE =
27- new JMSDecorator (Tags .SPAN_KIND_PRODUCER , DDSpanTypes .MESSAGE_PRODUCER );
47+ new JMSDecorator ("Produced for " , Tags .SPAN_KIND_PRODUCER , DDSpanTypes .MESSAGE_PRODUCER );
2848
2949 public static final JMSDecorator CONSUMER_DECORATE =
30- new JMSDecorator (Tags .SPAN_KIND_CONSUMER , DDSpanTypes .MESSAGE_CONSUMER );
50+ new JMSDecorator ("Consumed from " , Tags .SPAN_KIND_CONSUMER , DDSpanTypes .MESSAGE_CONSUMER );
51+
52+ public JMSDecorator (String resourcePrefix , String spanKind , String spanType ) {
53+ this .resourcePrefix = resourcePrefix ;
54+
55+ this .queueTempResourceName = UTF8BytesString .create (resourcePrefix + "Temporary Queue" );
56+ this .topicTempResourceName = UTF8BytesString .create (resourcePrefix + "Temporary Topic" );
57+
58+ this .queueResourceJoiner = QUEUE_JOINER .curry (resourcePrefix );
59+ this .topicResourceJoiner = TOPIC_JOINER .curry (resourcePrefix );
3160
32- public JMSDecorator (String spanKind , String spanType ) {
3361 this .spanKind = spanKind ;
3462 this .spanType = spanType ;
3563 }
@@ -59,7 +87,7 @@ protected String spanKind() {
5987 return spanKind ;
6088 }
6189
62- public void onConsume (final AgentSpan span , final Message message , UTF8BytesString resourceName ) {
90+ public void onConsume (AgentSpan span , Message message , CharSequence resourceName ) {
6391 if (null != resourceName ) {
6492 span .setResourceName (resourceName );
6593 }
@@ -74,41 +102,45 @@ public void onConsume(final AgentSpan span, final Message message, UTF8BytesStri
74102 }
75103 }
76104
77- public void onProduce (
78- final AgentSpan span , final Message message , final Destination destination ) {
79- span .setResourceName ("Produced for " + toResourceName (message , destination ));
105+ public void onProduce (AgentSpan span , CharSequence resourceName ) {
106+ if (null != resourceName ) {
107+ span .setResourceName (resourceName );
108+ }
80109 }
81110
82111 private static final String TIBCO_TMP_PREFIX = "$TMP$" ;
83112
84- public static String toResourceName (final Message message , final Destination destination ) {
85- Destination jmsDestination = null ;
86- try {
87- jmsDestination = message .getJMSDestination ();
88- } catch (Exception ignored ) {
113+ public CharSequence toResourceName (String destinationName , boolean isQueue ) {
114+ if (null == destinationName ) {
115+ return isQueue ? queueTempResourceName : topicTempResourceName ;
89116 }
90- if (jmsDestination == null ) {
91- jmsDestination = destination ;
117+ Function <CharSequence , CharSequence > joiner =
118+ isQueue ? queueResourceJoiner : topicResourceJoiner ;
119+ // some systems may have queues and topics with the same name - since we won't know which was
120+ // cached first we check the character after the initial prefix to see if it's Q (for Queue) -
121+ // if that's what we expect we can use the cached value, otherwise generate the correct name
122+ CharSequence resourceName = resourceNameCache .computeIfAbsent (destinationName , joiner );
123+ if ((resourceName .charAt (resourcePrefix .length ()) == 'Q' ) == isQueue ) {
124+ return resourceName ;
92125 }
126+ return joiner .apply (destinationName );
127+ }
128+
129+ public String getDestinationName (Destination destination ) {
130+ String name = null ;
93131 try {
94- if (jmsDestination instanceof Queue ) {
95- final String queueName = ((Queue ) jmsDestination ).getQueueName ();
96- if (jmsDestination instanceof TemporaryQueue || queueName .startsWith (TIBCO_TMP_PREFIX )) {
97- return "Temporary Queue" ;
98- } else {
99- return "Queue " + queueName ;
132+ if (destination instanceof Queue ) {
133+ if (!(destination instanceof TemporaryQueue )) {
134+ name = ((Queue ) destination ).getQueueName ();
100135 }
101136 }
102- if (jmsDestination instanceof Topic ) {
103- final String topicName = ((Topic ) jmsDestination ).getTopicName ();
104- if (jmsDestination instanceof TemporaryTopic || topicName .startsWith (TIBCO_TMP_PREFIX )) {
105- return "Temporary Topic" ;
106- } else {
107- return "Topic " + topicName ;
137+ if (destination instanceof Topic ) {
138+ if (!(destination instanceof TemporaryTopic )) {
139+ name = ((Topic ) destination ).getTopicName ();
108140 }
109141 }
110142 } catch (Exception ignored ) {
111143 }
112- return "Destination" ;
144+ return null != name && ! name . startsWith ( TIBCO_TMP_PREFIX ) ? name : null ;
113145 }
114146}
0 commit comments