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

Work in Progress on some Trace API tweaks #1130

Closed

Conversation

jkwatson
Copy link
Contributor

Doing this in Draft PR to make it as open and public as possible.

Also, doing this via a new contrib module for incubating new APIs.

@codecov-io
Copy link

codecov-io commented Apr 22, 2020

Codecov Report

Merging #1130 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #1130   +/-   ##
=========================================
  Coverage     84.17%   84.17%           
  Complexity     1153     1153           
=========================================
  Files           149      149           
  Lines          4449     4449           
  Branches        394      394           
=========================================
  Hits           3745     3745           
  Misses          557      557           
  Partials        147      147           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a71f905...37c87b9. Read the comment docs.

private static Map<String, AttributeValue> makeAttributeMap(Attribute[] attributes) {
Map<String, AttributeValue> result = new HashMap<>();
for (Attribute attribute : attributes) {
result.put(attribute.key().key(), makeValue(attribute));
Copy link
Member

Choose a reason for hiding this comment

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

Having this double key method call looks strange.
The fact that we need to unwrap and wrap again the value makes me thinking that maybe the concrete implementation of Attributes should also already build the proper AttributeValue and hold its reference. This way we don't need a switch since the typing information already suggests the correct method to call. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The goal of this draft PR is to discuss changes to the API, not provide an efficient wrapper for the current API. Don't worry about the internal details of this, as they are just there to make sure we can provide the same functionality, not to be a real implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remember, the impetus for this discussion was getting rid of AttributeValue from the API altogether. :)

import com.google.errorprone.annotations.MustBeClosed;
import io.opentelemetry.context.Scope;

// go Speed Racer, go Speed Racer, go Speed Racer go!
Copy link
Member

Choose a reason for hiding this comment

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

🤣

@Oberon00
Copy link
Member

Am I missing something or is there not yet a SpanEx.put/setAttribute outside the Builder?

@jkwatson
Copy link
Contributor Author

Am I missing something or is there not yet a SpanEx.put/setAttribute outside the Builder?

I've only written options for the Link API at this point. If we can decide on a direction for that, I think the rest will follow pretty clearly.

@jkwatson jkwatson force-pushed the experimental_tracer_api branch from dc14421 to 82e10c0 Compare April 27, 2020 16:52
@jkwatson
Copy link
Contributor Author

@bogdandrutu I added some detailed notes about allocation overhead with some of the various options in this PR.

@jkwatson
Copy link
Contributor Author

jkwatson commented May 1, 2020

@Oberon00 @thisthat @trask Please provide feedback on the various options presented here.

Copy link
Member

@trask trask left a comment

Choose a reason for hiding this comment

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

i think i prefer the more efficient and more user-friendly setAttribute(key, value).

from a user perspective, i don't think the overloaded methods make the API surface feel bigger (they only add to the API surface from a maintainer's perspective).

Comment on lines +130 to +171
// option 1... provide a single attribute
public SpanEx.Builder setAttribute(Attribute attribute) {
builder.setAttribute(attribute.key().key(), makeValue(attribute));
return this;
}
Copy link
Member

Choose a reason for hiding this comment

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

comparing

spanBuilder.setAttribute(Attribute.create(key, value))

and

spanBuilder.setAttribute(key, value)

the latter is more efficient, and seems more user-friendly 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.

ah, cool. This is the obvious option that we should add. I assume you mean with the typed-key. Yes, I'll add this ASAP.

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 added this, as well as all the array-based attribute methods everywhere, for completeness.

Comment on lines +139 to +181
public SpanEx.Builder setAttribute(Attribute... attributes) {
for (Attribute attribute : attributes) {
builder.setAttribute(attribute.key().key(), makeValue(attribute));
}
return this;
}
Copy link
Member

Choose a reason for hiding this comment

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

comparing

Attribute attr1 = Attribute.create(key1, value1);
Attribute attr2 = Attribute.create(key2, value2);
Attribute attr3 = Attribute.create(key3, value3);
spanBuilder.setAttribute(attr1, attr2, attr3);

and

spanBuilder.setAttribute(key1, value1)
           .setAttribute(key2, value2)
           .setAttribute(key3, value3);

the latter is more efficient, and seems more user-friendly 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.

check out the latest updates, which have support for this usage.

Comment on lines +130 to +191
// option 1... provide a single attribute
public SpanEx.Builder setAttribute(Attribute attribute) {
builder.setAttribute(attribute.key().key(), makeValue(attribute));
return this;
}

// option 2... a type-safe key-value pair with varargs parameters

/** doc me. */
public SpanEx.Builder setAttribute(Attribute... attributes) {
for (Attribute attribute : attributes) {
builder.setAttribute(attribute.key().key(), makeValue(attribute));
}
return this;
}

// option 3... accept a bunch of attributes at once

/** doc me. */
public SpanEx.Builder setAttribute(Attributes attributes) {
for (AttributeKey key : attributes.getKeys()) {
builder.setAttribute(key.key(), makeValue(attributes, key));
}
return this;
}
Copy link
Member

Choose a reason for hiding this comment

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

comparing

spanBuilder.setAttributes(
        MapBasedAttributes.newBuilder().put(key1, value1)
            .put(key2, value2)
            .put(key3, value3)
            .build())

and

spanBuilder.setAttribute(key1, value1)
           .setAttribute(key2, value2)
           .setAttribute(key3, value3);

the latter is more efficient, and seems more user-friendly to me

Copy link
Member

Choose a reason for hiding this comment

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

i think i prefer the more efficient and more user-friendly setAttribute(key, value).

from a user perspective, i don't think the overloaded methods make the API surface feel bigger (they only add to the API surface from a maintainer's perspective).

I agree with you that we should offer the setAttribute(key, value) but I think we should also offer the 3rd option using Attributes. In many semantic conventions, say HTTP, many attributes don't change. For example, if a library has to manually instrument its code to serve an HTTP request, the attributes method, url, target, ... do not change between requests so they can be cached.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an interesting thought, yes. Pre-bundling the attributes that are relevant for a given HTTP endpoint is possible, but is that likely to be a common use-case, as opposed to more generic instrumentation that would need to dynamically generate the values?

Copy link
Member

Choose a reason for hiding this comment

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

Would caching an Attributes object give some performance benefit? Or is it just for convenience? Maybe a concrete example would help to understand how caching the Attributes would be more convenient compared to settings the attributes directly.

Copy link
Member

Choose a reason for hiding this comment

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

I was thinking out loud without having a concrete example in mind. Thinking more thoroughly on a possible usage, I would use the Attributes interface to decouple span creation and attribute definition, similarly to how it's used here:

https://github.com/newrelic-forks/opentelemetry-java/blob/37c87b907289de35be6dfe4c3aee132e1815b7db/contrib/api_incubator/src/test/java/io/opentelemetry/trace/TracerExTest.java#L84-L85

Copy link
Member

Choose a reason for hiding this comment

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

The decoupling is nice in that example, but if the attribute values aren't static, I think you'd need to pass in 8 parameters to that httpAttribute() method, at which point it may not be so nice.

@jkwatson jkwatson force-pushed the experimental_tracer_api branch from de62548 to 28640f4 Compare May 18, 2020 20:50
@jkwatson
Copy link
Contributor Author

I'm going to close this, since the introduction of the Attributes class would mean a rework, if we wanted to change to "typed" keys.

@jkwatson jkwatson closed this Jun 30, 2020
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.

5 participants