-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Question about correctness of metric.Meter implementation and use #4836
Question about correctness of metric.Meter implementation and use #4836
Comments
This is not true if there was an instrument name error. The returned instrument will be "usable" (though it may produce conflicting metric streams) and the error is It is also not true that all users should pipe their error to |
Should this be part of the documentation of the interface since implementations, such as gRPC, are depending upon this behavior to be correct?
Is there guidance on when to call otel.Handle and when not to? |
For authors of the OTel SDK: whenever an error that cannot be returned to the user (asynchronous, not allowed via the API). For authors of OTel instrumentation: as little as possible. If the error can be handled, handle it; if it cannot but can be returned to the user, return it to the user; if neither can be done and it is possibly recoverable or critical to the use then send to the For users of OTel that is defined by themselves: they are setting a handler, they are in the best position to decide this. |
Sure, sounds good to me. But I think it should be a part of the implementation of the interface's documentation not the interface itself given that is not where the behavior comes from. |
I disagree with that part. Here is my reasoning: gRPC's usage takes a |
This it the reason you cannot say the interface will always return an error for a name defined by OpenTelemetry to be invalid for their SDKs in the interface. There is nothing stopping one of those infinite implementations from deviating from this behavior, nor should there be. |
I'm sorry I'll clarify my problem. I am writing code that takes a If it is ok to call functions on the first parameter, I would like to solidify this contract by putting it in the documentation of the object I'm calling: |
Yeah, I think we can document the |
I'm sorry, I want to document.
I would like to document this because this current behavior of Meter is different than the rest of the Go standard library. For example, http.NewRequest returns a nil first object if the second return value, |
I've submitted an example PR here: #4853 |
You are again describing the behavior of the OTel SDK that backs the interface. I don't think we should limit other implementations of that interface to never return |
I see the disagreement. Is it fair to say: I'm saying:
You're saying:
|
I'm saying all a user can rely on is the interface contract itself. If an implementation of that interface wants to return a partial result and an error that is fine. If they want to return an unrecoverable error and nil, also fine. If we want to communicate to users that an implementation may return partial results through the interface that sounds fine with me. I'm not okay with saying all implementations will be expected to do this and never return |
Thanks for clearing this up! Back to the gRPC implementation of open telemetry with this code
Since this implementation is relying on the behavior that
|
I think the instrumentation needs to check if the instrument is c.rpcResponseSize, err = c.meter.Int64Histogram("rpc."+role+".response.size",
metric.WithDescription("Measures size of RPC response messages (uncompressed)."),
metric.WithUnit("By"))
if err != nil {
otel.Handle(err)
}
// ...
if c.rpcResponseSize != nil {
c.rpcResponseSize.Record(...)
} or, like you mentioned, just set it to a noop if it is nil c.rpcResponseSize, err = c.meter.Int64Histogram("rpc."+role+".response.size",
metric.WithDescription("Measures size of RPC response messages (uncompressed)."),
metric.WithUnit("By"))
if err != nil {
otel.Handle(err)
if c.rpcResponseSize == nil {
c.rpcResponseSize = &noopHistogram{}
}
} |
Thanks for clarifying. I'm trying to write my own collector and am using the existing |
Description
metric.Meter has the following code
Users, like grpc, have the following code.
My problem is that metric.Meter does not document if it is ok to use the first returned value if the second is non-nil. In Go, this answer is generally assumed "no". In the example above,
otel.Handle
is called, but the function is not returned and continues. Later on, because there is no return, code could use thec.rpcResponseSize
object and panic.The only documentation for
otel.Handle
isMy assumption is that handle is intended to allow more than just
panic
. Maybe one idea is the service emails an error to a sys admin, but continues to run.If that's the case, then creates of otel instrumentation, such as gRPC, need to either:
otel.Handle
, but actually set a noop object into their configFor the first option above, the implementation of gRPC otel should be modified. For the second option above, the documentation of metric.Meter needs to be modified.
Recommendation
The contract, IE documentation, of metric.Meter should say "If the second returned value is non-nil, then the first returned value will be a no-op object and users should call otel.Handle."
The text was updated successfully, but these errors were encountered: