-
Notifications
You must be signed in to change notification settings - Fork 805
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
ValueType.INT metric instrument integer overflow #3014
Comments
JS can only safely represent numbers between Options:
The proto defines numeric integer metric values as signed 64-bit ints ( Personally I think option (2) is the safest, but (3) is also reasonable. |
We can also use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt When converting to proto we would need to be sure to properly overflow numbers larger than |
I'm not sure if its related but we had an issue to support int64 here: #104, maybe can we tackle both a the same time ? Just serializing it in proto differently depending on the value ? |
Now that we don't have 8,10,12 we can use BigInt there too |
How do we want to handle this? I don't want to just use BigInt for everything since numbers larger than 2^53 aren't the most common and there is a significant performance hit vs using Here is my proposal: /cc @open-telemetry/javascript-maintainers especially @legendecas Int GaugeAccept Int SumAccept Histograms and float gauge/sumNo need for special handling as the API for histograms specifies float input. Bucket counts should never reach above MAX_SAFE_INTEGER. |
Once we agree on a strategy i'm happy to work on this one |
I would be inclined not to introduce implicit conversion between numbers and bigints. Conversion from numbers to bigints is easy, but the interoperability between numbers and bigints is not trivial as all the operands must be a bigint. Lots of places must be aware of this implication and it can complicate the common path:
I'd suggest introducing a series of APIs explicitly involved with the bigints, like |
@dyladan Would you mind clarifying why backends that support signed 64-bit ints can not handle resets from Either way, as the overflow has to be manually reset, resetting |
Generally other languages have dedicated method for each type so i would be in favor to have different methods too |
It may be interpreted as a 64 bit overflow not a 53 bit overflow as 53 bits is a weird time for integers to overflow.
I like this idea. We actually don't need to overflow the regular counter at all if we do this because we can simply document that any int instrument that goes larger than Number.MAX_SAFE_INTEGER should use the bigint version |
Would it be better to have a separate method or to have a Option 1meter.createBigIntCounter("my_big_int_counter", { description, unit }); Option 2meter.createCounter("my_big_int_counter", { description, unit, valueType: ValueType.BIG_INT }); |
I wonder which one would be preferable for for platform that doesn't support bigint ? specially old browser version or edge platform that use old engines ? I personally prefer option 1 though |
I guess it depends what you want your fallback to look like. Would option 1 fail or return a regular int counter on platforms with no BigInt? If it returns a regular int counter then we are back to the complexity of an API that has to support multiple input types in order to support the fallback behavior. For both options, we need to decide if we're going to allow |
I would have suggested to make new functions for bigint that are optional in the API but its not great as UX |
I would prefer a more explicit and fail-early approach for feature absence.
For both options, my idea is that their internal representation is what their name/flag suggests. I don't have a strong opinion on allowing numbers on bigint counters yet, but I'd find a naive start with no implicit conversion would be great. |
So just use BigInt and it might throw. User is responsible for doing any feature detection? |
Yeah, as we don't provide any polyfills, I don't think we can do many things without BigInt support. |
I did a little digging because I was curious how you would pass BigInt to the protocol buffers implementation. It looks like we are using protobuf.js implementation and the typescript stubs it generates look like this: /** Properties of a NumberDataPoint. */
interface INumberDataPoint {
// ....
/** NumberDataPoint asDouble */
asDouble?: (number|null);
/** NumberDataPoint asInt */
asInt?: (number|Long|null);
// ....
} the
|
Yes that is what that is from.
They actually aren't bundling long.js. You can look at the bundler and see that it is
You can pass a string but it is converted to a number (or Long if you have included that dependency) for internal representation. There is also a PR open to add BigInt support to protobuf.js protobufjs/protobuf.js#1557
I did consider it, but decided that I would rather use a real builtin and wait for proper support. Using an external module for 64-bit support means we have to support it for a very long time when the JS ecosystem is clearly moving in another direction.
See above comments about bundler but this actually isn't true. I was going to convert BigInts to |
We wouldn't really need to provide polyfills. We could just accept |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
Whats the solution? |
JavaScript integer numbers are coerced to floating-point values implicitly if the value goes over the Number.MAX_SAFE_INTEGER. A metric instrument with ValueType.INT should stick to integer values if possible.
Spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/supplementary-guidelines.md#integer
The text was updated successfully, but these errors were encountered: