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

Only allow certain types of Numeric values as attribute values. #1173

Merged
merged 6 commits into from Apr 8, 2022

Conversation

plantfansam
Copy link
Contributor

We ran into a pretty odd failure mode, which this patch will hopefully help address (h/t @ericmustin for sussing this out):

In an app, we set a span attribute value to an ActiveSupport::Duration instance. So imagine something like .in_span("foobar", { "baz" => 1.minute }. When we viewed the span in various destinations, it the attribute showed up with the value as nil (or null or what have you). We saw the symptom (null attribute value, which is not allowed per the otel spec) before we sussed out the problem.

Turns out that, when exporting, the otlp exporter checks for a whitelist of exportable value classes that are pretty basic (code here). As a result, a value with class ActiveSupport::Duration will be nil.

This patch should ensure that users will get a warning if they use an unsupported Numeric class, and that the invalid attribute k/v pair will not be exported.

I didn't see the need to do this, but we could also potentially:

  • log a warning from the OTLP exporter about this
  • allow other numeric classes (BigDecimal, etc.)

@@ -20,8 +20,12 @@ def valid_key?(key)
key.instance_of?(String)
end

def valid_numeric?(value)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe try to be consistent with boolean? above?

Suggested change
def valid_numeric?(value)
def numeric?(value)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 791ebcb

@@ -20,8 +20,12 @@ def valid_key?(key)
key.instance_of?(String)
end

def valid_numeric?(value)
value.is_a?(Integer) || value.is_a?(Float)
Copy link
Contributor

Choose a reason for hiding this comment

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

Two things:

  1. I wonder if we should explicitly use .instance_of? to restrict values to instances of these specific classes, in case someone tries to subclass them & that 💥 in protobuf serialization later.
  2. What's the current state of BigInteger? IIRC it was merged with Integer some releases of MRI ago. I'm not sure whether we should check for it here or if we can now comfortably assume value.is_a?(Integer) covers that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

100% agree with moving to instance_of? - that's a great idea.

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 think Bignum and Fixnum are kaput as of 2.4.0: https://github.com/ruby/ruby/blob/master/doc/ChangeLog-2.4.0#L4927-L4963

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed from is_a? to instance_of? here 0c1f281

def valid_simple_value?(value)
value.instance_of?(String) || value == false || value == true || value.is_a?(Numeric)
value.instance_of?(String) || value == false || value == true || valid_numeric?(value)
Copy link
Contributor

Choose a reason for hiding this comment

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

Further to the instance_of? vs is_a? question, we are using == here for booleans, which may be too loose a constraint. We also have boolean? defined above in terms of is_a? and used in valid_array_value? below. Should we instead use instance_of? in boolean? and use boolean?(value) here?

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 can't think of a single reason why not, hence f5755d07f734b3f9bbcce65ed53bc36cc07cba2a

Copy link
Contributor

@ericmustin ericmustin 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 this lgtm, as a followup (but not blocking imo, this is a good incremental improvement) we can think about how similar work for Strings might look, see: #1146

Nice work!

@plantfansam
Copy link
Contributor Author

I think this lgtm, as a followup (but not blocking imo, this is a good incremental improvement) we can think about how similar work for Strings might look, see: #1146

Nice work!

TY! I will make a note to see about giving the ol' 👁️ 👁️ to our Strings

@robertlaurin robertlaurin merged commit b22c5c6 into open-telemetry:main Apr 8, 2022
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.

None yet

4 participants