Skip to content

Commit eb52808

Browse files
Cortana7JonasKunz
andauthored
Add ability to change Naming Mode for spring-rabbit-plugin (#3424)
* #3421 extend spring rabbit transactions to use either queue or exchange in the name * #3421 tests for naming mode queue * #3421 updated CHANGELOG.asciidoc * #3421 added tag Co-authored-by: Jonas Kunz <[email protected]> * #3421 improved config-option documentation Co-authored-by: Jonas Kunz <[email protected]> * #3421 generated documentation * Regenerate docs --------- Co-authored-by: Jonas Kunz <[email protected]> Co-authored-by: Jonas Kunz <[email protected]>
1 parent a20a0ac commit eb52808

File tree

6 files changed

+98
-10
lines changed

6 files changed

+98
-10
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Use subheadings with the "=====" level for adding notes for unreleased changes:
4343
4444
[float]
4545
===== Features
46+
* Added a configuration option to use queues in names of spring-rabbit transactions - {pull}3424[#3424]
4647
* Added support for OpenTelementry Attributes db.statement and db.user - {pull}3475[#3475]
4748
4849
[float]

apm-agent-plugins/apm-rabbitmq/apm-rabbitmq-plugin/src/main/java/co/elastic/apm/agent/rabbitmq/AbstractBaseInstrumentation.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ protected static boolean captureHeaderKey(String key) {
5252
return !WildcardMatcher.isAnyMatch(coreConfiguration.getSanitizeFieldNames(), key);
5353
}
5454

55+
protected static MessagingConfiguration.RabbitMQNamingMode getRabbitMQNamingMode() {
56+
return messagingConfiguration.getRabbitMQNamingMode();
57+
}
58+
5559
/**
5660
* Captures queue name and optional timestamp
5761
*

apm-agent-plugins/apm-rabbitmq/apm-rabbitmq-spring/src/main/java/co/elastic/apm/agent/rabbitmq/SpringAmqpTransactionHelper.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import co.elastic.apm.agent.tracer.Transaction;
2323
import co.elastic.apm.agent.rabbitmq.header.SpringRabbitMQTextHeaderGetter;
2424
import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils;
25+
import co.elastic.apm.agent.tracer.configuration.MessagingConfiguration;
2526
import org.springframework.amqp.core.Message;
2627
import org.springframework.amqp.core.MessageProperties;
2728

@@ -37,12 +38,12 @@ public SpringAmqpTransactionHelper(Tracer tracer) {
3738

3839
@Nullable
3940
public Transaction<?> createTransaction(Message message, String transactionNamePrefix) {
40-
String exchange = null;
41+
String exchangeOrQueue = null;
4142
MessageProperties messageProperties = message.getMessageProperties();
4243
if (messageProperties != null) {
43-
exchange = messageProperties.getReceivedExchange();
44+
exchangeOrQueue = getExchangeOrQueue(messageProperties);
4445
}
45-
if (exchange != null && AbstractBaseInstrumentation.isIgnored(exchange)) {
46+
if (exchangeOrQueue != null && AbstractBaseInstrumentation.isIgnored(exchangeOrQueue)) {
4647
return null;
4748
}
4849

@@ -58,7 +59,7 @@ public Transaction<?> createTransaction(Message message, String transactionNameP
5859
transaction.withType("messaging")
5960
.withName(transactionNamePrefix)
6061
.appendToName(" RECEIVE from ")
61-
.appendToName(AbstractBaseInstrumentation.normalizeExchangeName(exchange));
62+
.appendToName(AbstractBaseInstrumentation.normalizeExchangeName(exchangeOrQueue));
6263

6364
transaction.setFrameworkName("Spring AMQP");
6465

@@ -67,12 +68,20 @@ public Transaction<?> createTransaction(Message message, String transactionNameP
6768
String receivedRoutingKey = messageProperties.getReceivedRoutingKey();
6869
transaction.getContext().getMessage().withAge(timestamp).withRoutingKey(receivedRoutingKey);
6970
}
70-
if (exchange != null) {
71-
transaction.getContext().getMessage().withQueue(exchange);
71+
if (exchangeOrQueue != null) {
72+
transaction.getContext().getMessage().withQueue(exchangeOrQueue);
7273
}
7374

7475
// only capture incoming messages headers for now (consistent with other messaging plugins)
7576
AbstractBaseInstrumentation.captureHeaders(messageProperties != null ? messageProperties.getHeaders() : null, transaction.getContext().getMessage());
7677
return transaction.activate();
7778
}
79+
80+
private static String getExchangeOrQueue(MessageProperties messageProperties) {
81+
if (MessagingConfiguration.RabbitMQNamingMode.QUEUE == AbstractBaseInstrumentation.getRabbitMQNamingMode()) {
82+
return messageProperties.getConsumerQueue();
83+
} else {
84+
return messageProperties.getReceivedExchange();
85+
}
86+
}
7887
}

apm-agent-plugins/apm-rabbitmq/apm-rabbitmq-spring/src/test/java/co/elastic/apm/agent/rabbitmq/AbstractRabbitMqTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import co.elastic.apm.agent.impl.transaction.Span;
2222
import co.elastic.apm.agent.impl.transaction.Transaction;
23+
import co.elastic.apm.agent.tracer.configuration.MessagingConfiguration;
2324
import org.junit.Test;
2425

2526
import java.util.List;
@@ -28,8 +29,11 @@
2829
import static co.elastic.apm.agent.rabbitmq.RabbitMQIT.checkSendSpan;
2930
import static co.elastic.apm.agent.rabbitmq.RabbitMQIT.checkTransaction;
3031
import static co.elastic.apm.agent.rabbitmq.RabbitMQIT.getNonRootTransaction;
32+
import static co.elastic.apm.agent.rabbitmq.TestConstants.QUEUE_NAME;
3133
import static co.elastic.apm.agent.rabbitmq.TestConstants.TOPIC_EXCHANGE_NAME;
34+
import static co.elastic.apm.agent.tracer.configuration.MessagingConfiguration.JmsStrategy.POLLING;
3235
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
36+
import static org.mockito.Mockito.doReturn;
3337

3438
public abstract class AbstractRabbitMqTest extends RabbitMqTestBase {
3539

@@ -46,6 +50,20 @@ public void verifyThatTransactionWithSpanCreated() {
4650
checkParentChild(receiveTransaction, testSpan);
4751
}
4852

53+
@Test
54+
public void verifyThatTransactionWithSpanCreated_NamingModeQueue() {
55+
MessagingConfiguration messagingConfiguration = config.getConfig(MessagingConfiguration.class);
56+
doReturn(MessagingConfiguration.RabbitMQNamingMode.QUEUE).when(messagingConfiguration).getRabbitMQNamingMode();
57+
58+
rabbitTemplate.convertAndSend(TOPIC_EXCHANGE_NAME, TestConstants.ROUTING_KEY, MESSAGE);
59+
Transaction receiveTransaction = reporter.getFirstTransaction(1000);
60+
checkTransaction(receiveTransaction, QUEUE_NAME, "Spring AMQP");
61+
Span testSpan = reporter.getFirstSpan(1000);
62+
assertThat(testSpan.getNameAsString()).isEqualTo("testSpan");
63+
assertThat(testSpan.getType()).isEqualTo("custom");
64+
checkParentChild(receiveTransaction, testSpan);
65+
}
66+
4967
@Test
5068
public void verifyThatTransactionWithSpanCreated_DistributedTracing() {
5169
Transaction rootTransaction = startTestRootTransaction("Rabbit-Test Root Transaction");

apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/MessagingConfiguration.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package co.elastic.apm.agent.tracer.configuration;
2020

2121
import co.elastic.apm.agent.common.util.WildcardMatcher;
22-
import co.elastic.apm.agent.tracer.configuration.WildcardMatcherValueConverter;
2322
import org.stagemonitor.configuration.ConfigurationOption;
2423
import org.stagemonitor.configuration.ConfigurationOptionProvider;
2524
import org.stagemonitor.configuration.converter.ListValueConverter;
@@ -33,7 +32,7 @@ public class MessagingConfiguration extends ConfigurationOptionProvider {
3332
private static final String MESSAGE_POLLING_TRANSACTION_STRATEGY = "message_polling_transaction_strategy";
3433
private static final String MESSAGE_BATCH_STRATEGY = "message_batch_strategy";
3534

36-
private ConfigurationOption<JmsStrategy> messagePollingTransactionStrategy = ConfigurationOption.enumOption(JmsStrategy.class)
35+
private final ConfigurationOption<JmsStrategy> messagePollingTransactionStrategy = ConfigurationOption.enumOption(JmsStrategy.class)
3736
.key(MESSAGE_POLLING_TRANSACTION_STRATEGY)
3837
.configurationCategory(MESSAGING_CATEGORY)
3938
.tags("internal")
@@ -45,7 +44,7 @@ public class MessagingConfiguration extends ConfigurationOptionProvider {
4544
.dynamic(true)
4645
.buildWithDefault(JmsStrategy.HANDLING);
4746

48-
private ConfigurationOption<BatchStrategy> messageBatchStrategy = ConfigurationOption.enumOption(BatchStrategy.class)
47+
private final ConfigurationOption<BatchStrategy> messageBatchStrategy = ConfigurationOption.enumOption(BatchStrategy.class)
4948
.key(MESSAGE_BATCH_STRATEGY)
5049
.configurationCategory(MESSAGING_CATEGORY)
5150
.tags("internal")
@@ -57,7 +56,7 @@ public class MessagingConfiguration extends ConfigurationOptionProvider {
5756
.dynamic(true)
5857
.buildWithDefault(BatchStrategy.BATCH_HANDLING);
5958

60-
private ConfigurationOption<Boolean> collectQueueAddress = ConfigurationOption.booleanOption()
59+
private final ConfigurationOption<Boolean> collectQueueAddress = ConfigurationOption.booleanOption()
6160
.key("collect_queue_address")
6261
.configurationCategory(MESSAGING_CATEGORY)
6362
.tags("internal")
@@ -109,6 +108,14 @@ public class MessagingConfiguration extends ConfigurationOptionProvider {
109108
.dynamic(false)
110109
.buildWithDefault(Collections.<String>emptyList());
111110

111+
private final ConfigurationOption<RabbitMQNamingMode> rabbitMQNamingMode = ConfigurationOption.enumOption(RabbitMQNamingMode.class)
112+
.key("rabbitmq_naming_mode")
113+
.configurationCategory(MESSAGING_CATEGORY)
114+
.description("Defines whether the agent should use the exchanges or the queue for the naming of RabbitMQ Transactions. Valid options are `QUEUE` and `EXCHANGE`")
115+
.dynamic(true)
116+
.tags("added[1.46.0]")
117+
.buildWithDefault(RabbitMQNamingMode.EXCHANGE);
118+
112119
public JmsStrategy getMessagePollingTransactionStrategy() {
113120
return messagePollingTransactionStrategy.get();
114121
}
@@ -133,6 +140,10 @@ public Collection<String> getJmsListenerPackages() {
133140
return jmsListenerPackages.get();
134141
}
135142

143+
public RabbitMQNamingMode getRabbitMQNamingMode() {
144+
return rabbitMQNamingMode.get();
145+
}
146+
136147
public enum JmsStrategy {
137148
/**
138149
* Create a transaction capturing JMS {@code receive} invocations
@@ -164,4 +175,15 @@ public enum BatchStrategy {
164175
*/
165176
BATCH_HANDLING
166177
}
178+
179+
public enum RabbitMQNamingMode {
180+
/**
181+
* Use exchange in transaction names
182+
*/
183+
EXCHANGE,
184+
/**
185+
* Use queue in transaction names
186+
*/
187+
QUEUE,
188+
}
167189
}

docs/configuration.asciidoc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ Click on a key to get more information.
171171
* <<config-messaging>>
172172
** <<config-ignore-message-queues>>
173173
** <<config-jms-listener-packages>>
174+
** <<config-rabbitmq-naming-mode>>
174175
* <<config-metrics>>
175176
** <<config-dedot-custom-metrics>>
176177
** <<config-custom-metrics-histogram-boundaries>>
@@ -2504,6 +2505,30 @@ Starting from version 1.43.0, the classes that are part of the 'application_pack
25042505
| `elastic.apm.jms_listener_packages` | `jms_listener_packages` | `ELASTIC_APM_JMS_LISTENER_PACKAGES`
25052506
|============
25062507

2508+
// This file is auto generated. Please make your changes in *Configuration.java (for example CoreConfiguration.java) and execute ConfigurationExporter
2509+
[float]
2510+
[[config-rabbitmq-naming-mode]]
2511+
==== `rabbitmq_naming_mode` (added[1.46.0])
2512+
2513+
Defines whether the agent should use the exchanges or the queue for the naming of RabbitMQ Transactions. Valid options are `QUEUE` and `EXCHANGE`
2514+
2515+
<<configuration-dynamic, image:./images/dynamic-config.svg[] >>
2516+
2517+
Valid options: `EXCHANGE`, `QUEUE`
2518+
2519+
[options="header"]
2520+
|============
2521+
| Default | Type | Dynamic
2522+
| `EXCHANGE` | RabbitMQNamingMode | true
2523+
|============
2524+
2525+
2526+
[options="header"]
2527+
|============
2528+
| Java System Properties | Property file | Environment
2529+
| `elastic.apm.rabbitmq_naming_mode` | `rabbitmq_naming_mode` | `ELASTIC_APM_RABBITMQ_NAMING_MODE`
2530+
|============
2531+
25072532
[[config-metrics]]
25082533
=== Metrics configuration options
25092534

@@ -4603,6 +4628,15 @@ Example: `5ms`.
46034628
#
46044629
# jms_listener_packages=
46054630
4631+
# Defines whether the agent should use the exchanges or the queue for the naming of RabbitMQ Transactions. Valid options are `QUEUE` and `EXCHANGE`
4632+
#
4633+
# Valid options: EXCHANGE, QUEUE
4634+
# This setting can be changed at runtime
4635+
# Type: RabbitMQNamingMode
4636+
# Default value: EXCHANGE
4637+
#
4638+
# rabbitmq_naming_mode=EXCHANGE
4639+
46064640
############################################
46074641
# Metrics #
46084642
############################################

0 commit comments

Comments
 (0)