Skip to content
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

PeerService Resolver #9061

Merged
merged 21 commits into from
Oct 12, 2023
Merged

PeerService Resolver #9061

merged 21 commits into from
Oct 12, 2023

Conversation

mmorel-35
Copy link
Contributor

@mmorel-35 mmorel-35 commented Jul 27, 2023

Hi!

Here is a first draft of a Resolver for Peer Services.
For now protocol and path are not wired in instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/net/PeerServiceAttributesExtractor.java but PeerServiceResolver is already able to handle them.

What do you think ?

Fixes #9047

@mmorel-35 mmorel-35 force-pushed the issue-9047 branch 18 times, most recently from 4a0db07 to 9ae9082 Compare July 27, 2023 19:41
@mmorel-35 mmorel-35 marked this pull request as ready for review July 27, 2023 20:03
@mmorel-35 mmorel-35 requested a review from a team as a code owner July 27, 2023 20:03
Copy link
Contributor

@breedx-splk breedx-splk left a comment

Choose a reason for hiding this comment

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

Thanks for contributing! Sorry that I had so many comments. I don't think any of them should be particularly challenging to implement.

@mmorel-35 mmorel-35 force-pushed the issue-9047 branch 3 times, most recently from 450763e to d9faa5e Compare July 29, 2023 08:37
@mmorel-35
Copy link
Contributor Author

Also, as otel.instrumentation.common.peer-service-mapping is defined once for all, the PeerServiceResolver could be Singleton but I don't see how to achieve this.

The config is created in javaagent-extension-api and the extractor in ‎instrumentation-api-semconv. Would it be possible to place the PeerServiceResolver class in a way they can both use it ?

@mmorel-35 mmorel-35 force-pushed the issue-9047 branch 2 times, most recently from 9a8ac32 to a4d697c Compare August 4, 2023 16:49
Comment on lines 114 to 106
if (port != null) {
return port.equals(this.port);
}
Copy link
Member

Choose a reason for hiding this comment

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

Why is a port condition here? Isn't this part about the path?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it is. When the matcher has a path, the tested port need to match the matcher's port. Otherwise with the mapping :
localhost/mypath=myservice

localhost:4859/mypath and localhost:8081/mypath would both be resolved as myservice.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, but doesn't the

        if (port != null) {
          return port.equals(this.port);
        }

condition above already handle that?

Copy link
Contributor Author

@mmorel-35 mmorel-35 Aug 11, 2023

Choose a reason for hiding this comment

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

The checker can have a null port.
The first port checking requires the two ports to match if the checker has a defined port.

When it comes to path checking.
Once the path are matching, then the ports must also be equals.

condition above already handle that?

With the tests I did, it was not enough.

I'm interested if there is a shorter and easier way to ensure that without making port a required attribute.

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 not sure I get the scenario you're trying to cover.

So, when the mapping is 1.2.3.4/abc -> def and you pass (1.2.3.4, 8080, /abc) shouldn't you get def in return? That extra condition makes it return null, which does not seem correct to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you have the mapping (1.2.3.4, null, /abc) -> def but in reality you have (1.2.3.4, 8080, /abc) -> def and (1.2.3.4, 8081, /abc) -> ghi, I believe that it's better to return null so the mapping has to be fixed to have the port provided instead of having a misleading mapping.

@mateuszrzeszutek
Copy link
Member

Also, as otel.instrumentation.common.peer-service-mapping is defined once for all, the PeerServiceResolver could be Singleton but I don't see how to achieve this.

The config is created in javaagent-extension-api and the extractor in ‎instrumentation-api-semconv. Would it be possible to place the PeerServiceResolver class in a way they can both use it ?

You could make the PeerServiceResolver a functional interface, with a static create(Map<String, String>) factory method that would built the resolver from the configuration. Then, the PeerServiceAttributesExtractor factory methods could accept a PeerServiceResolver instead of the string map; you could build and store the singleton resolver instance in the javaagent CommonConfig. This way you could remove the MAPPINGS global from the resolver implementation.

Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
Co-Authored-By: Trask Stalnaker <trask.stalnaker@gmail.com>

String serverAddress = attributesGetter.getServerAddress(request);
Integer serverPort = attributesGetter.getServerPort(request);
String path = getUrlPath(attributesGetter, request);
Copy link
Member

Choose a reason for hiding this comment

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

what do you think about passing in the http.url (and only the http.url) to the PeerServiceResolver? and the PeerServiceResolver could then just check matches directly against the http.url without needing to do any parsing I think

Alternatively, the resolver could accept a Supplier<String> just for the path parameter, and only lazily evaluate that when host & port match.

mmorel-35 and others added 2 commits September 9, 2023 14:25
Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
@mmorel-35
Copy link
Contributor Author

Hi @trask , @mateuszrzeszutek ,
Any news on this ?
Can it be in the next release?
Can it be merged as is and then you optimize it with your new ideas?

Copy link
Member

@mateuszrzeszutek mateuszrzeszutek left a comment

Choose a reason for hiding this comment

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

Approved 👍

@trask there is one more open discussion about the port behavior: #9061 (comment)
Perhaps we should merge this PR and tackle that later?

@trask trask added this to the v1.31.0 milestone Sep 27, 2023
@trask
Copy link
Member

trask commented Oct 12, 2023

@trask there is one more open discussion about the port behavior: #9061 (comment)

I just resolved that discussion (sorry, I was having boolean logic failures in my head).

I'd still prefer not to add url parsing on the hot path for a feature that most people won't be using, so would prefer if we can implement some kind of lazy evaluation in this PR. I think the Supplier<String> proposal sounds reasonable.

@mmorel-35 can you try that out?

@mmorel-35
Copy link
Contributor Author

mmorel-35 commented Oct 12, 2023

Hi @trask ,
It’s done.

@trask
Copy link
Member

trask commented Oct 12, 2023

thanks @mmorel-35 ❤️

@trask trask merged commit 9a1c178 into open-telemetry:main Oct 12, 2023
47 checks passed
@mmorel-35 mmorel-35 deleted the issue-9047 branch October 12, 2023 15:18
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.

Peer Service Mapping per host, name and base-path
5 participants