Skip to content

Conversation

@thisthat
Copy link
Member

@thisthat thisthat commented Jul 20, 2020

Update attributes API to the latest spec: open-telemetry/opentelemetry-specification#777

@codecov
Copy link

codecov bot commented Jul 20, 2020

Codecov Report

Merging #1437 into master will decrease coverage by 0.02%.
The diff coverage is 96.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #1437      +/-   ##
============================================
- Coverage     91.39%   91.37%   -0.03%     
  Complexity      954      954              
============================================
  Files           116      116              
  Lines          3416     3431      +15     
  Branches        281      290       +9     
============================================
+ Hits           3122     3135      +13     
- Misses          205      206       +1     
- Partials         89       90       +1     
Impacted Files Coverage Δ Complexity Δ
.../main/java/io/opentelemetry/common/Attributes.java 96.07% <93.10%> (-3.93%) 10.00 <0.00> (ø)
...n/java/io/opentelemetry/common/AttributeValue.java 82.22% <100.00%> (+2.47%) 10.00 <1.00> (+1.00)
...ntelemetry/sdk/trace/RecordEventsReadableSpan.java 81.81% <100.00%> (-0.08%) 77.00 <0.00> (-1.00)

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 dfc5cbe...0387979. Read the comment docs.

Copy link
Contributor

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

Shouldn't we just not set null in Attributes instead of filtering on consumption?

"Attribute values of null are considered to be not set and get discarded as if that SetAttribute call had never been made"

@jkwatson
Copy link
Contributor

Shouldn't we just not set null in Attributes instead of filtering on consumption?

"Attribute values of null are considered to be not set and get discarded as if that SetAttribute call had never been made"

Since anyone can create a Resource, even outside of this codebase, we wouldn't be able to control that, so having the filter in place seems like a good idea. But, yes, "don't do that" is always a good rule when it comes to nulls. ;)

@anuraaga
Copy link
Contributor

@jkwatson Sorry wasn't clear, I meant filtering out null values when creating attributes, e.g. the builder's setters

https://github.com/open-telemetry/opentelemetry-java/blob/master/api/src/main/java/io/opentelemetry/common/Attributes.java#L148

@thisthat
Copy link
Member Author

thisthat commented Jul 21, 2020

@anuraaga null values are meaningful because they are used to delete previously set attributes (for Span).

@anuraaga
Copy link
Contributor

Hmm if we use null as an implementation detail of emptiness it's ok. In that case shouldn't forEach internally filter null? Having all users of forEach filter like this seems weird

@anuraaga
Copy link
Contributor

On second thought, do we have an API for deleting attributes?

@thisthat
Copy link
Member Author

Yes we do have it https://github.com/open-telemetry/opentelemetry-java/blob/master/sdk/src/main/java/io/opentelemetry/sdk/trace/RecordEventsReadableSpan.java#L314
However, looking again at the spec, Events and Links attributes should also offer the possibility to delete existing attributes.

@thisthat thisthat changed the title Forbit null values Forbid null values Jul 21, 2020
@jkwatson
Copy link
Contributor

Yes we do have it https://github.com/open-telemetry/opentelemetry-java/blob/master/sdk/src/main/java/io/opentelemetry/sdk/trace/RecordEventsReadableSpan.java#L314
However, looking again at the spec, Events and Links attributes should also offer the possibility to delete existing attributes.

I don't think events and links need to support this. they are created immutable (or lazily so), so you won't be removing attributes from existing links or events.

@jkwatson
Copy link
Contributor

Note: the way that attributes are deleted from spans is pretty hacky at the moment (it involves using an extension of HashMap). I'd love to figure out a better way to do it.

Comment on lines 131 to 145
if (value.getType() == AttributeValue.Type.STRING && value.getStringValue() == null) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

Why other values like null array is not removed?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think along these lines, if we're using null to model deletion, we should just store null directly, not an attribute value with a value of null.

Copy link
Member Author

Choose a reason for hiding this comment

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

Because null values inside arrays are meaningful. Since the Attributes API does not create null attributes, it cannot exist a null value but only a value that contains an AttributeValue with null. Does it make sense?

Copy link
Member

Choose a reason for hiding this comment

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

No, it does not make sense. What if the "array" is null, not the value inside the array?

Copy link
Member Author

Choose a reason for hiding this comment

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

The "array" cannot be null. Resource uses the Attributes class for storing attributes which creates always an object for arrays: https://github.com/open-telemetry/opentelemetry-java/blob/master/api/src/main/java/io/opentelemetry/common/Attributes.java#L204

Copy link
Member

Choose a reason for hiding this comment

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

Very strange behavior for arrays then:

We replace with empty array/list.... Not too much consistency.

Copy link
Contributor

Choose a reason for hiding this comment

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

General Java guidelines are to never return null for a collection, but use an empty one (per Josh Bloch in Effective Java). So, I think this behavior is a good one.

Copy link
Member

Choose a reason for hiding this comment

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

We discussed about this. It is not we return null, it is we get null and add an entry with empty collection, why then not add an entry with empty string?

Copy link
Member Author

Choose a reason for hiding this comment

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

I have uniformed the handling of null in 18e3719. The following cases are dropped (or removed if the key was already present):

  • null strings, e.g. (String) null
  • new arrays with 0 length, e.g. new String[0]
  • null arrays, e.g. (String[]) null

Instead, the following are stored as attributes:

  • Empty strings
  • Arrays with null values as members, e.g. new String[] {null}

@anuraaga
Copy link
Contributor

anuraaga commented Jul 22, 2020

So assuming we do need to keep null values to model deletion (seems a bit weird if we support deletion we could have an explicit deletion API? Java Maps have the exact problem @jkwatson mentions of supporting null values in a very undefined way), still I wonder why we don't filter in the producer rather than all the consumers, here

https://github.com/open-telemetry/opentelemetry-java/blob/master/api/src/main/java/io/opentelemetry/common/ImmutableKeyValuePairs.java#L58

@thisthat
Copy link
Member Author

@anuraaga filtering in the producer makes sense only if we do have an explicit API to delete Span attributes and we would need to change the spec.

@anuraaga
Copy link
Contributor

@anuraaga filtering in the producer makes sense only if we do have an explicit API to delete Span attributes

Really? We'd still be setting the attribute with null, meaning it's deleted. And if we filter in the producer, it won't be returned to the consumer, fulfilling the requirement of acting as if SetAttribute call had never been made. What am I missing? :)

@thisthat
Copy link
Member Author

thisthat commented Jul 23, 2020

I was missing something 😅 ImmutableKeyValuePairs is not used to set Span attributes. We could indeed filter in the producer!

@thisthat thisthat force-pushed the null-resource-value branch from 387ce57 to 18e3719 Compare August 4, 2020 08:43
@jkwatson
Copy link
Contributor

jkwatson commented Aug 5, 2020

I haven't been following the full conversation, but if this about discarding empty arrays, I'm against it. We also don't discard empty strings.

See spec https://github.com/open-telemetry/opentelemetry-specification/blob/v0.6.0/specification/trace/api.md#set-attributes:

Attribute values expressing a numerical value of zero or an empty string are considered meaningful and MUST be stored and passed on to span processors / exporters.

The same should hold for empty arrays IMHO.

This is only for the Resource, not for Span attributes. @thisthat can you update the PR title to reflect that it's just for Resource attributes?

@thisthat thisthat changed the title Forbid null values Forbid null values and empty arrays in Resource Attributes Aug 6, 2020
@anuraaga
Copy link
Contributor

anuraaga commented Aug 6, 2020

Thanks for bearing with my confusion!

@thisthat thisthat changed the title Forbid null values and empty arrays in Resource Attributes Update Attributes API to comply the spec Aug 17, 2020
@thisthat thisthat force-pushed the null-resource-value branch from 98372f3 to 2bdb1cf Compare August 17, 2020 07:17
@thisthat
Copy link
Member Author

@open-telemetry/java-approvers I have update the PR to implement the latest specification introduced by open-telemetry/opentelemetry-specification#777
Resource (Attributes API) and Span attributes have the same behavior:

  • accept empty arrays
  • accept null values within arrays
  • drop null or empty keys
  • drop null values or delete the attribute if was previously set

Copy link
Contributor

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the update! I think it's ok now, but for the future, when making such a large change to a PR it may be better to close the old one and start a new one to give everyone a clean slate.

Copy link
Contributor

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

Thanks!

@jkwatson jkwatson self-requested a review August 17, 2020 15:36
Copy link
Contributor

@jkwatson jkwatson 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 sticking with this one!

@jkwatson jkwatson merged commit 792f0f4 into open-telemetry:master Aug 18, 2020
@thisthat thisthat deleted the null-resource-value branch September 22, 2020 05:59
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.

6 participants