Skip to content

Commit 536c395

Browse files
author
Liudmila Molkova
authored
Onboard ServiceBus onto new tracing (Azure#33663)
* Onboard ServiceBus onto new tracing and fix tests * update sb admin client * more test hardening * more admin tests fixes
1 parent 95129cc commit 536c395

File tree

20 files changed

+494
-431
lines changed

20 files changed

+494
-431
lines changed

sdk/core/azure-core-metrics-opentelemetry/src/main/java/com/azure/core/metrics/opentelemetry/OpenTelemetryAttributes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private static Map<String, String> getMappings() {
2323
// messaging mapping, attributes are defined in com.azure.core.amqp.implementation.ClientConstants and in EventHubs, ServiceBus
2424
// metric helpers
2525
mappings.put("status", "otel.status_code");
26-
mappings.put("entityName", "messaging.destination");
26+
mappings.put("entityName", "messaging.destination.name");
2727
mappings.put("entityPath", "messaging.az.entity_path");
2828
mappings.put("hostName", "net.peer.name");
2929
mappings.put("errorCondition", "amqp.error_condition");

sdk/core/azure-core-metrics-opentelemetry/src/test/java/com/azure/core/metrics/opentelemetry/OpenTelemetryAttributesTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public void attributeMappings() {
8282
assertEquals(13, attributes.size());
8383
assertEquals("value", attributes.get(AttributeKey.stringKey("foobar")));
8484
assertEquals("host", attributes.get(AttributeKey.stringKey("net.peer.name")));
85-
assertEquals("entity", attributes.get(AttributeKey.stringKey("messaging.destination")));
85+
assertEquals("entity", attributes.get(AttributeKey.stringKey("messaging.destination.name")));
8686
assertEquals("path", attributes.get(AttributeKey.stringKey("messaging.az.entity_path")));
8787
assertEquals("amqp::error::code", attributes.get(AttributeKey.stringKey("amqp.error_condition")));
8888
assertEquals("rejected", attributes.get(AttributeKey.stringKey("amqp.delivery_state")));

sdk/core/azure-core-tracing-opentelemetry/src/main/java/com/azure/core/tracing/opentelemetry/OpenTelemetryUtils.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import io.opentelemetry.api.trace.Span;
1111
import io.opentelemetry.api.trace.StatusCode;
1212

13-
import java.util.Collections;
14-
import java.util.HashMap;
1513
import java.util.Map;
1614
import java.util.Objects;
1715

@@ -21,47 +19,50 @@
2119
class OpenTelemetryUtils {
2220
private static final ClientLogger LOGGER = new ClientLogger(OpenTelemetryUtils.class);
2321

24-
private static final Map<String, String> ATTRIBUTE_MAPPING_V1_17_0 = getMappingsV1200();
2522
static final String SERVICE_REQUEST_ID_ATTRIBUTE = "serviceRequestId";
2623
static final String CLIENT_REQUEST_ID_ATTRIBUTE = "requestId";
2724

28-
private static Map<String, String> getMappingsV1200() {
29-
Map<String, String> mappings = new HashMap<>(8);
30-
// messaging mapping, attributes are defined in com.azure.core.amqp.implementation.ClientConstants
31-
mappings.put(ENTITY_PATH_KEY, "messaging.destination.name");
32-
mappings.put(HOST_NAME_KEY, "net.peer.name");
33-
mappings.put(CLIENT_REQUEST_ID_ATTRIBUTE, "az.client_request_id");
34-
mappings.put(SERVICE_REQUEST_ID_ATTRIBUTE, "az.service_request_id");
35-
36-
return Collections.unmodifiableMap(mappings);
37-
}
3825

3926
public static Attributes convert(Map<String, Object> attributeMap, OpenTelemetrySchemaVersion schemaVersion) {
4027
if (attributeMap == null || attributeMap.isEmpty()) {
4128
return Attributes.empty();
4229
}
4330

44-
Map<String, String> mappings = getMappingsForVersion(schemaVersion);
45-
4631
AttributesBuilder builder = Attributes.builder();
4732
for (Map.Entry<String, Object> kvp : attributeMap.entrySet()) {
4833
if (kvp.getValue() == null) {
4934
continue;
5035
}
5136

52-
addAttribute(builder, mappings.getOrDefault(kvp.getKey(), kvp.getKey()), kvp.getValue());
37+
addAttribute(builder, mapAttributeName(kvp.getKey(), schemaVersion), kvp.getValue());
5338
}
5439

5540
return builder.build();
5641
}
5742

58-
private static Map<String, String> getMappingsForVersion(OpenTelemetrySchemaVersion version) {
43+
private static String mapAttributeName(String name, OpenTelemetrySchemaVersion version) {
5944
if (version == OpenTelemetrySchemaVersion.V1_17_0) {
60-
return ATTRIBUTE_MAPPING_V1_17_0;
45+
return mapAttributeNameV1170(name);
6146
}
6247

6348
LOGGER.verbose("Unknown OpenTelemetry Semantic Conventions version: {}, using latest instead: {}", version, OpenTelemetrySchemaVersion.getLatest());
64-
return getMappingsForVersion(OpenTelemetrySchemaVersion.getLatest());
49+
return mapAttributeNameV1170(name);
50+
}
51+
52+
private static String mapAttributeNameV1170(String name) {
53+
if (ENTITY_PATH_KEY.equals(name)) {
54+
return "messaging.destination.name";
55+
}
56+
if (HOST_NAME_KEY.equals(name)) {
57+
return "net.peer.name";
58+
}
59+
if (CLIENT_REQUEST_ID_ATTRIBUTE.equals(name)) {
60+
return "az.client_request_id";
61+
}
62+
if (SERVICE_REQUEST_ID_ATTRIBUTE.equals(name)) {
63+
return "az.service_request_id";
64+
}
65+
return name;
6566
}
6667

6768
/**
@@ -107,7 +108,7 @@ private static void addAttribute(AttributesBuilder attributesBuilder, String key
107108
static void addAttribute(Span span, String key, Object value, OpenTelemetrySchemaVersion schemaVersion) {
108109
Objects.requireNonNull(key, "OpenTelemetry attribute name cannot be null.");
109110

110-
key = getMappingsForVersion(schemaVersion).getOrDefault(key, key);
111+
key = mapAttributeName(key, schemaVersion);
111112
if (value instanceof String) {
112113
span.setAttribute(AttributeKey.stringKey(key), (String) value);
113114
} else if (value instanceof Long) {

sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/FluxTrace.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ protected void hookOnNext(ServiceBusMessageContext message) {
6060
Context span = instrumentation.instrumentProcess("ServiceBus.process", message.getMessage(), Context.NONE);
6161
message.getMessage().setContext(span);
6262

63+
AutoCloseable scope = tracer.makeSpanCurrent(span);
6364
try {
6465
downstream.onNext(message);
6566
} catch (Throwable t) {
@@ -72,7 +73,7 @@ protected void hookOnNext(ServiceBusMessageContext message) {
7273
exception = (Throwable) processorException;
7374
}
7475
}
75-
tracer.endSpan(exception, context, null);
76+
tracer.endSpan(exception, context, scope);
7677
}
7778
}
7879

sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/ServiceBusClientBuilder.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import com.azure.core.util.logging.ClientLogger;
3535
import com.azure.core.util.metrics.Meter;
3636
import com.azure.core.util.metrics.MeterProvider;
37+
import com.azure.core.util.tracing.Tracer;
38+
import com.azure.core.util.tracing.TracerProvider;
3739
import com.azure.messaging.servicebus.implementation.MessageUtils;
3840
import com.azure.messaging.servicebus.implementation.MessagingEntityType;
3941
import com.azure.messaging.servicebus.implementation.ServiceBusAmqpConnection;
@@ -42,7 +44,6 @@
4244
import com.azure.messaging.servicebus.implementation.ServiceBusReactorAmqpConnection;
4345
import com.azure.messaging.servicebus.implementation.instrumentation.ServiceBusReceiverInstrumentation;
4446
import com.azure.messaging.servicebus.implementation.ServiceBusSharedKeyCredential;
45-
import com.azure.messaging.servicebus.implementation.instrumentation.ServiceBusTracer;
4647
import com.azure.messaging.servicebus.implementation.ServiceBusProcessorClientOptions;
4748
import com.azure.messaging.servicebus.models.ServiceBusReceiveMode;
4849
import com.azure.messaging.servicebus.models.SubQueue;
@@ -64,6 +65,7 @@
6465
import java.util.regex.Pattern;
6566

6667
import static com.azure.core.amqp.implementation.ClientConstants.ENTITY_PATH_KEY;
68+
import static com.azure.messaging.servicebus.implementation.ServiceBusConstants.AZ_TRACING_NAMESPACE_VALUE;
6769

6870
/**
6971
* The builder to create Service Bus clients:
@@ -209,7 +211,6 @@ public final class ServiceBusClientBuilder implements
209211
private static final Pattern HOST_PORT_PATTERN = Pattern.compile("^[^:]+:\\d+");
210212
private static final Duration MAX_LOCK_RENEW_DEFAULT_DURATION = Duration.ofMinutes(5);
211213
private static final ClientLogger LOGGER = new ClientLogger(ServiceBusClientBuilder.class);
212-
213214
private final Object connectionLock = new Object();
214215
private final MessageSerializer messageSerializer = new ServiceBusMessageSerializer();
215216
private ClientOptions clientOptions;
@@ -932,8 +933,8 @@ public ServiceBusSenderAsyncClient buildAsyncClient() {
932933
clientIdentifier = UUID.randomUUID().toString();
933934
}
934935

935-
final ServiceBusSenderInstrumentation instrumentation = new ServiceBusSenderInstrumentation(ServiceBusTracer.getDefaultTracer(),
936-
createMeter(), connectionProcessor.getFullyQualifiedNamespace(), entityName);
936+
final ServiceBusSenderInstrumentation instrumentation = new ServiceBusSenderInstrumentation(
937+
createTracer(), createMeter(), connectionProcessor.getFullyQualifiedNamespace(), entityName);
937938

938939
return new ServiceBusSenderAsyncClient(entityName, entityType, connectionProcessor, retryOptions,
939940
instrumentation, messageSerializer, ServiceBusClientBuilder.this::onClientClose, null, clientIdentifier);
@@ -1418,7 +1419,7 @@ ServiceBusReceiverAsyncClient buildAsyncClientForProcessor() {
14181419
connectionProcessor, messageSerializer, receiverOptions, clientIdentifier);
14191420

14201421
final ServiceBusReceiverInstrumentation instrumentation = new ServiceBusReceiverInstrumentation(
1421-
ServiceBusTracer.getDefaultTracer(), createMeter(), connectionProcessor.getFullyQualifiedNamespace(),
1422+
createTracer(), createMeter(), connectionProcessor.getFullyQualifiedNamespace(),
14221423
entityPath, subscriptionName, false);
14231424
return new ServiceBusReceiverAsyncClient(connectionProcessor.getFullyQualifiedNamespace(), entityPath,
14241425
entityType, receiverOptions, connectionProcessor, ServiceBusConstants.OPERATION_TIMEOUT,
@@ -1494,8 +1495,8 @@ private ServiceBusSessionReceiverAsyncClient buildAsyncClient(boolean isAutoComp
14941495
clientIdentifier = UUID.randomUUID().toString();
14951496
}
14961497

1497-
final ServiceBusReceiverInstrumentation instrumentation = new ServiceBusReceiverInstrumentation(ServiceBusTracer.getDefaultTracer(),
1498-
createMeter(), connectionProcessor.getFullyQualifiedNamespace(), entityPath, subscriptionName, syncConsumer);
1498+
final ServiceBusReceiverInstrumentation instrumentation = new ServiceBusReceiverInstrumentation(
1499+
createTracer(), createMeter(), connectionProcessor.getFullyQualifiedNamespace(), entityPath, subscriptionName, syncConsumer);
14991500
return new ServiceBusSessionReceiverAsyncClient(connectionProcessor.getFullyQualifiedNamespace(),
15001501
entityPath, entityType, receiverOptions, connectionProcessor, instrumentation, messageSerializer,
15011502
ServiceBusClientBuilder.this::onClientClose, clientIdentifier);
@@ -1977,8 +1978,8 @@ ServiceBusReceiverAsyncClient buildAsyncClient(boolean isAutoCompleteAllowed, bo
19771978
clientIdentifier = UUID.randomUUID().toString();
19781979
}
19791980

1980-
final ServiceBusReceiverInstrumentation instrumentation = new ServiceBusReceiverInstrumentation(ServiceBusTracer.getDefaultTracer(),
1981-
createMeter(), connectionProcessor.getFullyQualifiedNamespace(), entityPath, subscriptionName, syncConsumer);
1981+
final ServiceBusReceiverInstrumentation instrumentation = new ServiceBusReceiverInstrumentation(
1982+
createTracer(), createMeter(), connectionProcessor.getFullyQualifiedNamespace(), entityPath, subscriptionName, syncConsumer);
19821983
return new ServiceBusReceiverAsyncClient(connectionProcessor.getFullyQualifiedNamespace(), entityPath,
19831984
entityType, receiverOptions, connectionProcessor, ServiceBusConstants.OPERATION_TIMEOUT,
19841985
instrumentation, messageSerializer, ServiceBusClientBuilder.this::onClientClose, clientIdentifier);
@@ -2074,4 +2075,9 @@ private Meter createMeter() {
20742075
return MeterProvider.getDefaultProvider().createMeter(LIBRARY_NAME, LIBRARY_VERSION,
20752076
clientOptions == null ? null : clientOptions.getMetricsOptions());
20762077
}
2078+
2079+
private Tracer createTracer() {
2080+
return TracerProvider.getDefaultProvider().createTracer(LIBRARY_NAME, LIBRARY_VERSION,
2081+
AZ_TRACING_NAMESPACE_VALUE, clientOptions == null ? null : clientOptions.getTracingOptions());
2082+
}
20772083
}

sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClient.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package com.azure.messaging.servicebus;
55

66
import com.azure.core.amqp.AmqpRetryPolicy;
7+
import com.azure.core.amqp.AmqpSession;
78
import com.azure.core.amqp.AmqpTransaction;
89
import com.azure.core.amqp.exception.AmqpException;
910
import com.azure.core.amqp.implementation.MessageSerializer;
@@ -834,15 +835,11 @@ public Flux<ServiceBusReceivedMessage> receiveMessages() {
834835
Flux<ServiceBusReceivedMessage> receiveMessagesNoBackPressure() {
835836
return receiveMessagesWithContext(0)
836837
.handle((serviceBusMessageContext, sink) -> {
837-
try (AutoCloseable scope = tracer.makeSpanCurrent(serviceBusMessageContext.getMessage().getContext())) {
838-
if (serviceBusMessageContext.hasError()) {
839-
sink.error(serviceBusMessageContext.getThrowable());
840-
return;
841-
}
842-
sink.next(serviceBusMessageContext.getMessage());
843-
} catch (Exception ex) {
844-
LOGGER.verbose("Error disposing scope", ex);
838+
if (serviceBusMessageContext.hasError()) {
839+
sink.error(serviceBusMessageContext.getThrowable());
840+
return;
845841
}
842+
sink.next(serviceBusMessageContext.getMessage());
846843
});
847844
}
848845

@@ -1199,7 +1196,7 @@ public Mono<ServiceBusTransactionContext> createTransaction() {
11991196

12001197
return tracer.traceMono("ServiceBus.commitTransaction", connectionProcessor
12011198
.flatMap(connection -> connection.createSession(TRANSACTION_LINK_NAME))
1202-
.flatMap(transactionSession -> transactionSession.createTransaction())
1199+
.flatMap(AmqpSession::createTransaction)
12031200
.map(transaction -> new ServiceBusTransactionContext(transaction.getTransactionId())))
12041201
.onErrorMap(throwable -> mapError(throwable, ServiceBusErrorSource.RECEIVE));
12051202
}

sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ public Flux<Long> scheduleMessages(Iterable<ServiceBusMessage> messages, OffsetD
508508
return messageBatch;
509509
})
510510
.flatMapMany(messageBatch ->
511-
tracer.traceFluxWithLinks("ServiceBus.scheduleMessages",
511+
tracer.traceScheduleFlux("ServiceBus.scheduleMessages",
512512
connectionProcessor
513513
.flatMap(connection -> connection.getManagementNode(entityName, entityType))
514514
.flatMapMany(managementNode -> managementNode.schedule(messageBatch.getMessages(), scheduledEnqueueTime,
@@ -703,7 +703,7 @@ private Mono<Long> scheduleMessageInternal(ServiceBusMessage message, OffsetDate
703703
return monoError(LOGGER, new NullPointerException("'scheduledEnqueueTime' cannot be null."));
704704
}
705705

706-
return tracer.traceMonoWithLink("ServiceBus.scheduleMessage",
706+
return tracer.traceScheduleMono("ServiceBus.scheduleMessage",
707707
getSendLink().flatMap(link -> link.getLinkSize().flatMap(size -> {
708708
int maxSize = size > 0
709709
? size

sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/ServiceBusSenderInstrumentation.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@ <T> Mono<T> instrumentSendBatch(String spanName, Mono<T> publisher, List<Service
4545
meter.reportBatchSend(batch.size(), signal.getThrowable(), span);
4646
tracer.endSpan(signal.getThrowable(), span, null);
4747
})
48-
.contextWrite(reactor.util.context.Context.of(REACTOR_PARENT_TRACE_CONTEXT_KEY, tracer.startSpanWithLinks(spanName, batch,
48+
.contextWrite(reactor.util.context.Context.of(REACTOR_PARENT_TRACE_CONTEXT_KEY, tracer.startSpanWithLinks(spanName,
49+
ServiceBusTracer.OperationName.PUBLISH, batch,
4950
ServiceBusMessage::getContext, Context.NONE)));
5051
} else {
5152
return publisher
52-
.doOnEach(signal -> {
53-
meter.reportBatchSend(batch.size(), signal.getThrowable(), Context.NONE);
54-
});
53+
.doOnEach(signal -> meter.reportBatchSend(batch.size(), signal.getThrowable(), Context.NONE));
5554
}
5655
}
5756
}

0 commit comments

Comments
 (0)