use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class BatchTracingPropagationTest method testFromKafkaToAppWithNoParent.
@Test
public void testFromKafkaToAppWithNoParent() {
MyAppReceivingData bean = runApplication(getKafkaSinkConfigForMyAppReceivingData(topic), MyAppReceivingData.class);
companion.produceIntegers().usingGenerator(i -> new ProducerRecord<>(topic, null, null, "a-key", i), 10);
await().until(() -> bean.list().size() >= 10);
assertThat(bean.list()).containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertThat(bean.tracing()).hasSizeGreaterThanOrEqualTo(10);
assertThat(bean.tracing()).doesNotContainNull().doesNotHaveDuplicates();
List<String> spanIds = new ArrayList<>();
for (TracingMetadata tracing : bean.tracing()) {
spanIds.add(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getSpanId());
assertThat(Span.fromContextOrNull(tracing.getPreviousContext())).isNull();
}
assertThat(spanIds).doesNotContainNull().doesNotHaveDuplicates().hasSizeGreaterThanOrEqualTo(10);
for (SpanData data : testExporter.getFinishedSpanItems()) {
assertThat(data.getSpanId()).isIn(spanIds);
assertThat(data.getSpanId()).isNotEqualTo(data.getParentSpanId());
assertThat(data.getKind()).isEqualByComparingTo(SpanKind.CONSUMER);
}
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingUtils method createOutgoingTrace.
/**
* Creates a new outgoing message span message, and ensures span metadata is added to the
* message headers.
*
* @param message the source message
* @param headers the outgoing headers, must be mutable
* @param exchange the target exchange
* @param routingKey the routing key
* @param attributeHeaders a list (possibly empty) of header names whose values (if present)
* should be used as span attributes
*/
public static void createOutgoingTrace(final Message<?> message, final Map<String, Object> headers, final String exchange, final String routingKey, final List<String> attributeHeaders) {
// Extract tracing metadata from the source message itself
final TracingMetadata tracingMetadata = TracingMetadata.fromMessage(message).orElse(null);
final SpanBuilder spanBuilder = tracer.spanBuilder(exchange + " send").setSpanKind(SpanKind.PRODUCER);
if (tracingMetadata != null) {
// Handle possible parent span
final Context parentSpanContext = tracingMetadata.getPreviousContext();
if (parentSpanContext != null) {
spanBuilder.setParent(parentSpanContext);
} else {
spanBuilder.setNoParent();
}
} else {
spanBuilder.setNoParent();
}
final Span span = spanBuilder.startSpan();
final Context sendingContext = Context.current().with(span);
// Filter the outgoing message headers to just those that should map to span tags
final Map<String, Object> headerValues = message.getMetadata(OutgoingRabbitMQMetadata.class).map(md -> md.getHeaders().entrySet().stream().filter(e -> attributeHeaders.contains(e.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))).orElse(Collections.emptyMap());
setOutgoingSpanAttributes(span, exchange, routingKey, headerValues);
// Set span onto outgoing headers
GlobalOpenTelemetry.getPropagators().getTextMapPropagator().inject(sendingContext, headers, HeadersMapInjectAdapter.SETTER);
span.end();
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingUtils method getTracingMetaData.
/**
* Extract tracing metadata from a received RabbitMQ message and return
* it as {@link TracingMetadata}.
*
* @param msg the incoming RabbitMQ message
* @return a {@link TracingMetadata} instance, possibly empty but never null
*/
public static TracingMetadata getTracingMetaData(final io.vertx.rabbitmq.RabbitMQMessage msg) {
// Default
TracingMetadata tracingMetadata = TracingMetadata.empty();
if (msg.properties().getHeaders() != null) {
// Extract the tracing headers from the incoming RabbitMQ message into a tracing context
final Context context = GlobalOpenTelemetry.getPropagators().getTextMapPropagator().extract(io.opentelemetry.context.Context.root(), msg.properties().getHeaders(), HeadersMapExtractAdapter.GETTER);
// create tracing metadata based on that tracing context
tracingMetadata = TracingMetadata.withPrevious(context);
}
return tracingMetadata;
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class TracingUtils method addIncomingTrace.
/**
* Creates a span based on any tracing metadata in the incoming message.
*
* @param msg the incoming message
* @param attributeHeaders a list (possibly empty) of header names whose values (if present)
* should be used as span attributes
* @param <T> the message body type
* @return the message, with injected tracing metadata
*/
public static <T> Message<T> addIncomingTrace(final IncomingRabbitMQMessage<T> msg, final String queue, final List<String> attributeHeaders) {
final TracingMetadata tracingMetadata = TracingMetadata.fromMessage(msg).orElse(TracingMetadata.empty());
final Envelope envelope = msg.getRabbitMQMessage().envelope();
final SpanBuilder spanBuilder = tracer.spanBuilder(envelope.getExchange() + " receive").setSpanKind(SpanKind.CONSUMER);
// Handle possible parent span
final Context parentSpanContext = tracingMetadata.getPreviousContext();
if (parentSpanContext != null) {
spanBuilder.setParent(parentSpanContext);
} else {
spanBuilder.setNoParent();
}
final Span span = spanBuilder.startSpan();
// Filter the incoming message headers to just those that should map to span tags
final Map<String, Object> headerValues = msg.getHeaders().entrySet().stream().filter(e -> attributeHeaders.contains(e.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
try {
setIncomingSpanAttributes(span, queue, envelope.getRoutingKey(), headerValues);
// Make available as parent for subsequent spans inside message processing
span.makeCurrent();
msg.injectTracingMetadata(tracingMetadata.withSpan(span));
} finally {
span.end();
}
return msg;
}
use of io.smallrye.reactive.messaging.TracingMetadata in project smallrye-reactive-messaging by smallrye.
the class BatchTracingPropagationTest method testFromKafkaToAppWithParentSpan.
@Test
public void testFromKafkaToAppWithParentSpan() {
String parentTopic = topic + "-parent";
String stuffTopic = topic + "-stuff";
MyAppReceivingData bean = runApplication(getKafkaSinkConfigForMyAppReceivingData(parentTopic), MyAppReceivingData.class);
List<SpanContext> producedSpanContexts = new CopyOnWriteArrayList<>();
companion.produceIntegers().usingGenerator(i -> new ProducerRecord<>(parentTopic, null, null, "a-key", i, createTracingSpan(producedSpanContexts, stuffTopic)), 10);
await().until(() -> bean.list().size() >= 10);
assertThat(bean.list()).containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
List<String> producedTraceIds = producedSpanContexts.stream().map(SpanContext::getTraceId).collect(Collectors.toList());
assertThat(producedTraceIds).hasSize(10);
assertThat(bean.tracing()).hasSizeGreaterThanOrEqualTo(10);
assertThat(bean.tracing()).doesNotContainNull().doesNotHaveDuplicates();
List<String> receivedTraceIds = bean.tracing().stream().map(tracingMetadata -> Span.fromContext(tracingMetadata.getCurrentContext()).getSpanContext().getTraceId()).collect(Collectors.toList());
assertThat(receivedTraceIds).doesNotContainNull().doesNotHaveDuplicates().hasSize(10);
assertThat(receivedTraceIds).containsExactlyInAnyOrderElementsOf(producedTraceIds);
List<String> spanIds = new ArrayList<>();
for (TracingMetadata tracing : bean.tracing()) {
spanIds.add(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getSpanId());
assertThat(tracing.getPreviousContext()).isNotNull();
Span previousSpan = Span.fromContextOrNull(tracing.getPreviousContext());
assertThat(previousSpan).isNotNull();
assertThat(previousSpan.getSpanContext().getTraceId()).isEqualTo(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getTraceId());
assertThat(previousSpan.getSpanContext().getSpanId()).isNotEqualTo(Span.fromContext(tracing.getCurrentContext()).getSpanContext().getSpanId());
}
assertThat(spanIds).doesNotContainNull().doesNotHaveDuplicates().hasSizeGreaterThanOrEqualTo(10);
List<String> parentIds = bean.tracing().stream().map(tracingMetadata -> Span.fromContextOrNull(tracingMetadata.getPreviousContext()).getSpanContext().getSpanId()).collect(Collectors.toList());
assertThat(producedSpanContexts.stream().map(SpanContext::getSpanId)).containsExactlyElementsOf(parentIds);
for (SpanData data : testExporter.getFinishedSpanItems()) {
assertThat(data.getSpanId()).isIn(spanIds);
assertThat(data.getSpanId()).isNotEqualTo(data.getParentSpanId());
assertThat(data.getKind()).isEqualByComparingTo(SpanKind.CONSUMER);
assertThat(data.getParentSpanId()).isNotNull();
assertThat(data.getParentSpanId()).isIn(parentIds);
}
}
Aggregations