Skip to content

Conversation

@Technoboy-
Copy link
Contributor

Motivation

Implementation of PIP-446

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

@Technoboy- Technoboy- self-assigned this Oct 18, 2025
@Technoboy- Technoboy- added this to the 4.2.0 milestone Oct 18, 2025
@Technoboy- Technoboy- added ready-to-test area/client type/feature The PR added a new feature or issue requested a new feature labels Oct 18, 2025
@github-actions github-actions bot added the doc-not-needed Your PR changes do not impact docs label Oct 18, 2025
@lhotari lhotari requested a review from asafm November 17, 2025 16:55
@lhotari
Copy link
Member

lhotari commented Nov 17, 2025

@asafm Do you have a chance to review this PR?

@asafm
Copy link
Contributor

asafm commented Nov 17, 2025

@lhotari yes. This was the only comment I saw.

@asafm
Copy link
Contributor

asafm commented Nov 18, 2025

@lhotari yes. This was the only comment I saw.

Sorry @lhotari I confused with the other one. This one I didn't review

Copy link
Contributor

@poorbarcode poorbarcode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have one suggestion, it should be useful to determine client-side publish latency issue

  • Should we add more events for producers, to let us to record more spans? Such as follows
    • users call send -> cache message with message container
    • publish message to broker -> receive broker response


@Override
public void close() {
// No cleanup needed - spans are attached to messages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// No cleanup needed - spans are attached to messages
// Producer will fail pending messages when it being closed, which will trigger the `onSendAcknowledgement` events

Copy link
Member

@lhotari lhotari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the comments about exposing internals on the public API.

Comment on lines +39 to +47
/**
* Set the OpenTelemetry span associated with this message.
* <p>
* This method is called by tracing interceptors to attach a span to the message
* for later retrieval when completing the span.
*
* @param span the span to associate with this message, or null to clear
*/
void setTracingSpan(Span span);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to make sense to have this method on the public Pulsar client API. Isn't this a method that should only be used internally?

*
* @param span the span to associate with this message ID, or null to clear
*/
void setTracingSpan(Span span);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to make sense to have this method on the public Pulsar client API. Isn't this a method that should only be used internally?

* @param span the span to end
*/
public static void endSpan(Span span) {
if (span != null && span.isRecording()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the usage of span.isRecording() doesn't make sense here. It should only be used to skip adding some costly values to the span.

Comment on lines +166 to +170
if (span != null && span.isRecording()) {
span.setStatus(StatusCode.ERROR, throwable.getMessage());
span.recordException(throwable);
span.end();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revisit the usage of span.isRecording()

Suggested change
if (span != null && span.isRecording()) {
span.setStatus(StatusCode.ERROR, throwable.getMessage());
span.recordException(throwable);
span.end();
}
if (span != null) {
span.setStatus(StatusCode.ERROR, throwable.getMessage());
if (span.isRecording() {
span.recordException(throwable);
}
span.end();
}

Comment on lines +187 to +205
Message<String> msg = consumer.receive();

// Create a custom span for processing
Span span = tracer.spanBuilder("process-message")
.setSpanKind(SpanKind.INTERNAL)
.startSpan();

try (Scope scope = span.makeCurrent()) {
// Your processing logic
processMessage(msg.getValue());
span.setStatus(StatusCode.OK);
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR);
throw e;
} finally {
span.end();
consumer.acknowledge(msg);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just wondering how could this work. Does this PR contains tests that the custom processing span becomes a child span of the span that is created by the PulsarClient tracing.

Copy link
Member

@lhotari lhotari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also check the comments about "custom span creation"

Comment on lines +44 to +50
/**
* Integration tests for OpenTelemetry tracing with real broker.
* Note: These tests may be timing-dependent and could be flaky in CI environments.
* They verify end-to-end tracing functionality with actual Pulsar broker.
*/
@Test(groups = "broker")
public class OpenTelemetryTracingIntegrationTest extends BrokerTestBase {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test class doesn't seem to test that "Custom Span Creation" feature described in TRACING.md works as expected. I believe that it would be expected that the custom span would be the child span of the span created by the Pulsar client's consume tracing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/client doc-not-needed Your PR changes do not impact docs ready-to-test type/feature The PR added a new feature or issue requested a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants