-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
stats: add client side user agent to outgoing header #3331
Conversation
|
On the server side, you should be able to get the metadata from context ( On the client side, outgoing metadata doesn't have user-agent (it's appended later by the transport), so either this change, or we need to add it to the metadata. In your interceptor based solution, how did you get user-agent on the client side? |
To get the gRPC version on this client side, you could use |
I like the idea of passing the data using an already existing mechanism.
I haven't, as you described metadata is not available.
Especially when it is overridden. From an application maintainer point of view, I expect to change my code more frequently than gRPC version, so |
With a second thought: For the same reason, I would prefer to keep the transport specific details independent from the APIs gRPC exposes. (Though we are already violating that by having a dial option to set user agent, but that's more for historical reasons, and a better way that I would do today is to have a generic dial option to set transport configs that only a specific transport can understand) Adding Will you need |
The main reason to have such value on both sides is to be able to match metrics with each other or being able to distinguish metrics (e.g. number of outgoing requests) produced by different version of an app. Something like this might be done on the server-side, however:
I completely get your point, and it is clear to me that this is not the best way to address my problem. Do you consider to introduce any other mechanism that would serve a similar purpose? |
Another option is to add user-agent to This means you won't get the info in |
I would say that some of the stats API already contains HTTP-transport-specific details (e.g. wire length). So adding something transport-specific to that API is not out of the question IMO. However, we should be careful about how we expose it.
I agree with this. If we add it, it should be done inside the transport instead (and include the full header value, matching what would be seen by the server). |
A problem I can see with this approach is that such metadata would not be available in all |
The timing problem is a little tricky. Would it be OK to leave user-agent empty, and populate it later while handling OutHeader? Or even log the begin while handling OutHeader? This should be early enough for both unary and streaming RPCs. |
@menghanl makes sense. Done. |
…metadata produced on the client side
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix.
Seems vet isn't happy for some reason (travis log doesn't show the actually error...)
Looks like it failed gofmt -s -d -l .
. Try it locally and see if there's any diff? You can also just run vet.sh
.
internal/transport/http2_client.go
Outdated
@@ -681,13 +681,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea | |||
} | |||
if t.statsHandler != nil { | |||
header, _, _ := metadata.FromOutgoingContextRaw(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I believe this is a bug to call Raw
here.
This should be just FromOutgoingContext()
, otherwise it will miss the metadata that's appended.
Can you fix it, too? Thanks!
And I believe if you change this, the copy()
won't be necessary anymore, because FromOutgoingContext
always does a join. (The comment of the function also needs update, but that's another issue).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the changes! LGTM.
This PR is a PoC and a proposal at the same time. It adds
UserAgent
field tostats.RPCTagInfo
that carry the same information that is passed through metadatauser-agent
field. I have tried a similar approach withstats.ConnTagInfo
however metadata is not yet available whenTagConn
is called on the server-side.My main motivation to submit this change was to make a transition of my instrumentation library from
Interceptors
tostats.Handler
possible. Sinceuser-agent
stores information about gRPC version and at the same time it may carry similar information about the client app name and its version, I think it might be very relevant information, e.g. to measure how newly deployed version behaves (canary deployment).Related issue piotrkowalczuk/promgrpc#11