io.opentelemetry.instrumentation.kafka.internal.KafkaInstrumenterFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-kafka-clients-common Show documentation
Show all versions of opentelemetry-kafka-clients-common Show documentation
Instrumentation of Java libraries using OpenTelemetry.
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.kafka.internal;
import static java.util.Collections.emptyList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.ErrorCauseExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.messaging.MessageOperation;
import io.opentelemetry.instrumentation.api.instrumenter.messaging.MessagingAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.messaging.MessagingAttributesGetter;
import io.opentelemetry.instrumentation.api.instrumenter.messaging.MessagingSpanNameExtractor;
import io.opentelemetry.instrumentation.api.internal.PropagatorBasedSpanLinksExtractor;
import java.util.Collections;
import java.util.List;
import org.apache.kafka.clients.producer.RecordMetadata;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class KafkaInstrumenterFactory {
private final OpenTelemetry openTelemetry;
private final String instrumentationName;
private ErrorCauseExtractor errorCauseExtractor = ErrorCauseExtractor.getDefault();
private List capturedHeaders = emptyList();
private boolean captureExperimentalSpanAttributes = false;
private boolean messagingReceiveInstrumentationEnabled = false;
public KafkaInstrumenterFactory(OpenTelemetry openTelemetry, String instrumentationName) {
this.openTelemetry = openTelemetry;
this.instrumentationName = instrumentationName;
}
@CanIgnoreReturnValue
public KafkaInstrumenterFactory setErrorCauseExtractor(ErrorCauseExtractor errorCauseExtractor) {
this.errorCauseExtractor = errorCauseExtractor;
return this;
}
@CanIgnoreReturnValue
public KafkaInstrumenterFactory setCapturedHeaders(List capturedHeaders) {
this.capturedHeaders = capturedHeaders;
return this;
}
@CanIgnoreReturnValue
public KafkaInstrumenterFactory setCaptureExperimentalSpanAttributes(
boolean captureExperimentalSpanAttributes) {
this.captureExperimentalSpanAttributes = captureExperimentalSpanAttributes;
return this;
}
/**
* @deprecated if you have a need for this configuration option please open an issue in the opentelemetry-java-instrumentation
* repository.
*/
@Deprecated
@CanIgnoreReturnValue
public KafkaInstrumenterFactory setPropagationEnabled(boolean propagationEnabled) {
return this;
}
@CanIgnoreReturnValue
public KafkaInstrumenterFactory setMessagingReceiveInstrumentationEnabled(
boolean messagingReceiveInstrumentationEnabled) {
this.messagingReceiveInstrumentationEnabled = messagingReceiveInstrumentationEnabled;
return this;
}
public Instrumenter createProducerInstrumenter() {
return createProducerInstrumenter(Collections.emptyList());
}
public Instrumenter createProducerInstrumenter(
Iterable> extractors) {
KafkaProducerAttributesGetter getter = KafkaProducerAttributesGetter.INSTANCE;
MessageOperation operation = MessageOperation.PUBLISH;
return Instrumenter.builder(
openTelemetry,
instrumentationName,
MessagingSpanNameExtractor.create(getter, operation))
.addAttributesExtractor(
buildMessagingAttributesExtractor(getter, operation, capturedHeaders))
.addAttributesExtractors(extractors)
.addAttributesExtractor(new KafkaProducerAttributesExtractor())
.setErrorCauseExtractor(errorCauseExtractor)
.buildInstrumenter(SpanKindExtractor.alwaysProducer());
}
public Instrumenter createConsumerReceiveInstrumenter() {
return createConsumerReceiveInstrumenter(Collections.emptyList());
}
public Instrumenter createConsumerReceiveInstrumenter(
Iterable> extractors) {
KafkaReceiveAttributesGetter getter = KafkaReceiveAttributesGetter.INSTANCE;
MessageOperation operation = MessageOperation.RECEIVE;
return Instrumenter.builder(
openTelemetry,
instrumentationName,
MessagingSpanNameExtractor.create(getter, operation))
.addAttributesExtractor(
buildMessagingAttributesExtractor(getter, operation, capturedHeaders))
.addAttributesExtractor(KafkaReceiveAttributesExtractor.INSTANCE)
.addAttributesExtractors(extractors)
.setErrorCauseExtractor(errorCauseExtractor)
.setEnabled(messagingReceiveInstrumentationEnabled)
.buildInstrumenter(SpanKindExtractor.alwaysConsumer());
}
public Instrumenter createConsumerProcessInstrumenter() {
return createConsumerProcessInstrumenter(Collections.emptyList());
}
public Instrumenter createConsumerProcessInstrumenter(
Iterable> extractors) {
KafkaConsumerAttributesGetter getter = KafkaConsumerAttributesGetter.INSTANCE;
MessageOperation operation = MessageOperation.PROCESS;
InstrumenterBuilder builder =
Instrumenter.builder(
openTelemetry,
instrumentationName,
MessagingSpanNameExtractor.create(getter, operation))
.addAttributesExtractor(
buildMessagingAttributesExtractor(getter, operation, capturedHeaders))
.addAttributesExtractor(new KafkaConsumerAttributesExtractor())
.addAttributesExtractors(extractors)
.setErrorCauseExtractor(errorCauseExtractor);
if (captureExperimentalSpanAttributes) {
builder.addAttributesExtractor(new KafkaConsumerExperimentalAttributesExtractor());
}
if (messagingReceiveInstrumentationEnabled) {
builder.addSpanLinksExtractor(
new PropagatorBasedSpanLinksExtractor<>(
openTelemetry.getPropagators().getTextMapPropagator(),
KafkaConsumerRecordGetter.INSTANCE));
return builder.buildInstrumenter(SpanKindExtractor.alwaysConsumer());
} else {
return builder.buildConsumerInstrumenter(KafkaConsumerRecordGetter.INSTANCE);
}
}
public Instrumenter createBatchProcessInstrumenter() {
KafkaReceiveAttributesGetter getter = KafkaReceiveAttributesGetter.INSTANCE;
MessageOperation operation = MessageOperation.PROCESS;
return Instrumenter.builder(
openTelemetry,
instrumentationName,
MessagingSpanNameExtractor.create(getter, operation))
.addAttributesExtractor(
buildMessagingAttributesExtractor(getter, operation, capturedHeaders))
.addAttributesExtractor(KafkaReceiveAttributesExtractor.INSTANCE)
.addSpanLinksExtractor(
new KafkaBatchProcessSpanLinksExtractor(
openTelemetry.getPropagators().getTextMapPropagator()))
.setErrorCauseExtractor(errorCauseExtractor)
.buildInstrumenter(SpanKindExtractor.alwaysConsumer());
}
private static
AttributesExtractor buildMessagingAttributesExtractor(
MessagingAttributesGetter getter,
MessageOperation operation,
List capturedHeaders) {
return MessagingAttributesExtractor.builder(getter, operation)
.setCapturedHeaders(capturedHeaders)
.build();
}
}