Skip to content

add option to record transferred artifacts #1875

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

Merged
merged 11 commits into from
May 15, 2025

Conversation

smurf667
Copy link
Contributor

@smurf667 smurf667 commented May 4, 2025

Description:

This adds a TransferListener to the maven-extension so that artifact transfers can be recorded optionally.

Existing Issue(s):

See #1874

Testing:

DRAFT: No additional testing has been added yet.

Documentation:

DRAFT: No additional documentation has been added yet.

Outstanding items:

  • See above: Additional tests and documentation still need to be done.
  • Filtering of transfers below a certain threshold (size, duration) is not implemented yet; I tried to add a custom SpanExporter in OpenTelemetrySdkService - is see it getting called and filtering, but when I used the Jaeger UI setup (see blog) all spans were unexpectedly shown. The issue appears that the span must be created first (because the transfer events define start and end), but those not matching the thresholds should be ignored, and I don't know how to do that other than with the exporter.
  • I am not deeply familiar with the OpenTelemetry API nor the Maven APIs, so some things may have to be rectified.
  • There are some TODOs that should be addressed.

Copy link

linux-foundation-easycla bot commented May 4, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@smurf667 smurf667 marked this pull request as ready for review May 10, 2025 13:31
@smurf667 smurf667 requested a review from a team as a code owner May 10, 2025 13:31
@cyrille-leclerc
Copy link
Member

Thanks for this great contribution.
I would like to discuss a few idas layed out on smurf667#1

@cyrille-leclerc
Copy link
Member

@smurf667 can you share why you considered adding a "wrapping transfer span".
Not that I didn't yet test a build starting with an empty MAven local repo to understand when the first fransfer spans would take place

@smurf667
Copy link
Contributor Author

I just noticed that transfers were happening outside of goals (fair enough) and though it would be helpful to group them in this "wrapping transfer span". There is not concrete need to do that, and we can also leave them "unrooted".

I would like to hear your thoughts and the potential filtering of transfers based on duration and size (e.g. skip fast/small transfers to avoid clutter) - since the transfer is started by one event and only ended by another event, one would have to keep the span in memory, deferred until one could decide if it was worth to record. Sounds tricky.

Also, right now, there are no unit tests; not sure what would be reasonable here?

@@ -43,6 +58,10 @@ public final class OtelLifecycleParticipant extends AbstractMavenLifecyclePartic
*/
@Override
public void afterProjectsRead(MavenSession session) {
registerExecutionListener(session);
Copy link
Member

Choose a reason for hiding this comment

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

Why did we change something here? I didn't expect this PR to touch the execution listener. Did I miss something? I'll look at the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just moved this into a smaller method for symmetry reasons (register<XXX>Listener()) - I left a TODO, because I am not sure if some quirky Maven behavior is responsible for the need to register the exection listener in afterProjectsRead() vs afterSessionStart() - normally, I'd expect both listeners to be registered at the same place, but it appears actual Maven behavior necessitates the current code.

try {
return str.isEmpty() ? Optional.empty() : Optional.of(new URI(str));
} catch (URISyntaxException e) {
return Optional.empty();
Copy link
Member

Choose a reason for hiding this comment

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

Super smart! I was wondering how to track parsing failures :-)

spanBuilder.setAttribute(ServerAttributes.SERVER_PORT, uri.getPort());
}
// prevent ever increasing size
if (repositoryUriMapping.size() > 128) {
Copy link
Member

Choose a reason for hiding this comment

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

Very smart

}

void finish(Span span, TransferEvent event) {
switch (event.getRequestType()) {
Copy link
Member

Choose a reason for hiding this comment

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

@smurf667 did you identify a problem in this logic? I guess that the GET_EXISTENCE / HTTP HEAD will have a transfer size of 0 but who knows.

SpanBuilder spanBuilder =
this.openTelemetrySdkService
.getTracer()
.spanBuilder(spanName)
Copy link
Member

Choose a reason for hiding this comment

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

We could add a comment indicating we chose to create "http client spans" assuming the underlying http lib is not instrumented (span kind client...).
If we instrument the http lib, then we will have to change this spn type.

Copy link
Member

Choose a reason for hiding this comment

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

@cyrille-leclerc
Copy link
Member

Copy link
Member

@cyrille-leclerc cyrille-leclerc left a comment

Choose a reason for hiding this comment

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

Thanks @smurf667 , it's a great improvement!
I'm wondering if we could later introduce threshold based creation of transfer spans like "create a transfer span if transfer.duration > xxx ms". Let's see what's the community feedback.

@smurf667
Copy link
Contributor Author

Found two TODOs, which I removed. I think it's good now; I assume after review & approval the commits will be squashed.
If just not called span.end() is legal, then a size threshold could be easily implemented; not so sure about a time threshold. Maybe it can start like it is now, and if the feature is desired, it could be added later.

@cyrille-leclerc
Copy link
Member

If just not called span.end() is legal, then a size threshold could be easily implemented; not so sure about a time threshold. Maybe it can start like it is now, and if the feature is desired, it could be added later.

I think that you are right and we may use this trick but it would be a challenge if the http library became instrumented with OTel as we would get a missing spn in the chain.

I think it's good now;

Looking at the build failure logs, I forgot to run ./gradlew :maven-extension:spotlessApply on the last change I proposed 👼

@trask
Copy link
Member

trask commented May 14, 2025

@smurf667 can you run ./gradlew spotlessApply to fix CI? thanks!

@cyrille-leclerc
Copy link
Member

@smurf667 please review the suggestion to fix the build failure on the spotlessCheck.

@smurf667
Copy link
Contributor Author

Spotless changes merged...

@trask trask added this pull request to the merge queue May 15, 2025
Merged via the queue into open-telemetry:main with commit 34937d2 May 15, 2025
17 of 18 checks passed
@smurf667
Copy link
Contributor Author

Thank you all! 👍

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

Successfully merging this pull request may close these issues.

4 participants