Skip to content

[Bug] OpenTelemetryProducerInterceptor not executing due to eligible check #25584

@hrzzzz

Description

@hrzzzz

Search before reporting

  • I searched in the issues and found nothing similar.

Read release policy

  • I understand that unsupported versions don't get bug fixes. I will attempt to reproduce the issue on a supported version of Pulsar client and Pulsar broker.

User environment

master

Issue Description

The org.apache.pulsar.client.impl.tracing.OpenTelemetryProducerInterceptor adopts a lazy-loading mechanism for initializing its Tracer and TextMapPropagator instances.

Initialization is triggered only by the initializeIfNeeded method at the beginning of the beforeSend method.

private void initializeIfNeeded(Producer producer) {
    if (!initialized && producer instanceof ProducerBase<?> producerBase) {
        PulsarClientImpl client = producerBase.getClient();
        InstrumentProvider instrumentProvider = client.instrumentProvider();

        this.tracer = instrumentProvider.getTracer();
        this.propagator = GlobalOpenTelemetry.getPropagators().getTextMapPropagator();
        this.initialized = true;
    }
}

The eligible method of OpenTelemetryProducerInterceptor is implemented as follows:

public boolean eligible(Message message) {
    return tracer != null && propagator != null;
}

In org.apache.pulsar.client.impl.ProducerInterceptors#beforeSend, if an interceptor’s eligible method returns false, the logic skips the current interceptor and proceeds to the next one, which bypasses the execution of the interceptor’s beforeSend method entirely.

    public Message<?> beforeSend(Producer<?> producer, Message<?> message) {
        Message<?> interceptorMessage = message;
        for (ProducerInterceptor interceptor : interceptors) {
            try {
                if (!interceptor.eligible(message)) {
                    continue;
                }
                interceptorMessage = interceptor.beforeSend(producer, interceptorMessage);
            } catch (Throwable e) {
               // ......
            }
        }
        return interceptorMessage;
    }

This causes the OpenTelemetryProducerInterceptor to never get a chance to perform lazy initialization, ultimately making the interceptor non-functional.

Error messages

none

Reproducing the issue

Run the test case org.apache.pulsar.broker.service.OpenTelemetryTracingIntegrationTest#testBasicProducerConsumerTracing in debug mode and verify the number of generated spans.

Additional information

No response

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugThe PR fixed a bug or issue reported a bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions