Skip to content

Add messaging wrappers to support lightweight manual instrumentation #1855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

Cirilla-zmh
Copy link
Member

@Cirilla-zmh Cirilla-zmh commented Apr 16, 2025

Description:

This PR introduces a complete implementation of a generic messaging process wrapper API, designed to facilitate the creation of process spans and the propagation of trace context in a standardized and lightweight manner. It builds upon the initial draft presented in PR #1803, which provides additional context for this work.

Key features and contributions include:

  • Generic Process Wrapper API: A flexible and reusable API that supports the creation of process spans and ensures trace context propagation across different libraries and frameworks.
  • Library Implementations:
    • Added support for kafka-clients.
    • Added support for aliyun-mns-sdk (Alibaba Cloud Simple Message Queue).

Existing Issue(s):

Testing:

  • Base API integration tests.
  • Integration tests for kafka-clients.
  • Integration tests for aliyun-mns-sdk (pending for building mocked server).

Documentation:

For detailed usage instructions and API documentation, please refer to the updated README.md

@Cirilla-zmh Cirilla-zmh requested a review from a team as a code owner April 16, 2025 14:42
* <p>Inspired from <a
* href=https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/messaging/MessagingAttributesGetter.java>MessagingAttributesGetter</a>.
*/
public interface MessagingProcessRequest {
Copy link
Member

Choose a reason for hiding this comment

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

Can define separate extractors for each implementation instead of implementing this interface for each implementation? that would seem more similar to the existing instrumentation extractor design

Copy link
Member Author

@Cirilla-zmh Cirilla-zmh Apr 17, 2025

Choose a reason for hiding this comment

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

separate extractors for each implementation instead of implementing this interface for each implementation

Sorry, I don't think so.

If we do that, users have got to create an AttributesExtractor for each manual implementation, rather than reuse the DefaultMessagingAttributesGetter. Therefore, users should associate the attributes keys defined in semconv with the fields of messages - it's normally hard (semconv attributes are not such stable, and users may always ignore documents...), and that's one of reasons why we give the process wrapper today.

Conversely, if we give this interface. We can take advantage of the self-explanatory nature of the method names and add java comments to tell users what this value should point to. This process seems more natural, especially for those users who are not such familiar to OTel.

Copy link
Member

Choose a reason for hiding this comment

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

I don't disagree with your reasoning, but doesn't that same reasoning apply to all of the existing instrumentation api semconv attribute extractor design?

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe I didn't get your point. Are you suggesting a design like this:

Drop the interface of MessagingProcessRequest and create a interface of MessagingAttribute (or reuse that in instrumentations)

If we do so, the complexity for manual users may increase slightly—they will need to implement the MyMessagingGetter and define a request in cases where the framework's provided message structure is insufficient to retrieve all attributes (similar to KafkaProcessRequest). This is also why I didn't reuse the design of MessagingAttributesGetter—I believe it might introduce additional cognitive overhead.

However, if you prefer to maintain consistency in the design to make it easier for developers to manage, that makes sense as well. I can adjust my implementation to align with the instrumentation as much as possible.

Copy link
Member

Choose a reason for hiding this comment

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

If we do so, the complexity for manual users may increase slightly—they will need to implement the MyMessagingGetter and define a request in cases where the framework's provided message structure is insufficient to retrieve all attributes (similar to KafkaProcessRequest). This is also why I didn't reuse the design of MessagingAttributesGetter—I believe it might introduce additional cognitive overhead.

yeah, it's a good point, but I'd prefer to stay consistent with existing instrumentation.

ideally most users of this will be using our pre-built implementations (e.g. for kafka and mns) and so hopefully won't even be aware of which design we use

Copy link
Member Author

Choose a reason for hiding this comment

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

It makes sense to me. I'll adjust this implementation.

Copy link

linux-foundation-easycla bot commented May 28, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@otelbot-java-contrib
Copy link
Contributor

❌ The result from spotlessApply could not be committed to the PR branch, see logs: https://github.com/open-telemetry/opentelemetry-java-contrib/actions/runs/15303539997.

@Cirilla-zmh
Copy link
Member Author

Cirilla-zmh commented May 28, 2025

Update:

  • Refactored the README by moving the given implementation instructions ahead of the manual setup ones.
  • Regarding the generic parameters in AttributesGetter: I believe we have to keep them this way because we're reusing the definition of AttributesExtractor from the instrumentation. If we restrict the type to a specific interface, users wouldn't be able to define their own AttributesExtractor without resorting to explicit type casting. At this point, I think it's reasonable to provide an extensible and generic type here.
  • Added tests for aliyun-mns-sdk ;)

cc @steverao @trask

@Cirilla-zmh
Copy link
Member Author

Cirilla-zmh commented May 29, 2025

Some feedback: reducing the complexity of AttributesGetter

@Cirilla-zmh Cirilla-zmh force-pushed the main branch 3 times, most recently from 2dd0c16 to 933ad88 Compare June 11, 2025 13:45
@otelbot-java-contrib
Copy link
Contributor

🔧 The result from spotlessApply was committed to the PR branch.

1 similar comment
@otelbot-java-contrib
Copy link
Contributor

🔧 The result from spotlessApply was committed to the PR branch.

@otelbot-java-contrib
Copy link
Contributor

🔧 The result from spotlessApply was committed to the PR branch.

@Cirilla-zmh
Copy link
Member Author

@trask Hey Trask, I've refactored the design, and we now have an implementation that's very similar to the one in
instrumentation. Could you please take a look at it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants