Repository navigation
OpenTracing integration - #247
Conversation
Start with endpoint middleware, the raw http transport, and the gRPC transport.
Rather than support both Zipkin and OpenTracing, this diff replaces the former with the latter. It would be feasible to support both, though.
| decodeSumResponse, | ||
| pb.SumReply{}, | ||
| ).Endpoint(), cc, err | ||
| func NewSumEndpointFactory(tracer opentracing.Tracer) loadbalancer.Factory { |
There was a problem hiding this comment.
btw, there is an opentracing.GlobalTracer() singleton; if we embrace it, the indirection here would not be necessary.
There was a problem hiding this comment.
I like the explicitness of the parameter much better.
|
Oh, this would also resolve #37 since Appdash supports OpenTracing (thanks to @bg451 / sourcegraph/appdash#110). |
| return func(next endpoint.Endpoint) endpoint.Endpoint { | ||
| return func(ctx context.Context, request interface{}) (interface{}, error) { | ||
| serverSpan := opentracing.SpanFromContext(ctx) | ||
| if serverSpan == nil { |
There was a problem hiding this comment.
Is there any reason why opentracing.StartSpanFromContext isn't used instead?
There was a problem hiding this comment.
@bg451 opentracing.StartSpanFromContext relies on the global/singleton Tracer
|
Effectively all of my comments were nitpicking. This is a perfect approach.
Yes, please! I'm all for standardization here. I'm happy if Go kit exposes only an OpenTracing interface and helpers in its @basvanbeek would this be a problem for you? And for the record Go kit has no problem with API breakage; all of our consumers are vendoring. |
|
No problem for me provided we have a proper OpenTracing driver for Zipkin which allow us to have all the features and functionality we currently have with the native implementation. |
|
@peterbourgon @basvanbeek I am going to get coverage in for other transports, add tests, then ping this PR for another (closer) look. I don't think it makes sense to port the Zipkin client over to OpenTracing as part of this PR... though I do think it's feasible and desirable. |
| if span == nil { | ||
| span = opentracing.StartSpan(operationName) | ||
| } | ||
| return opentracing.ContextWithSpan(ctx, span) |
There was a problem hiding this comment.
we usually capture http.url tag here
There was a problem hiding this comment.
and peer tags too - in Zipkin they drive SA/CA annotations.
There was a problem hiding this comment.
@yurishkuro I'm not clear on how you capture peer tags from the server-side of an http.Request... from the client it seems easier, of course. Pro-tips?
There was a problem hiding this comment.
hm, you're right, I just checked and for Go I didn't do much on the server side. In Python it looked like this:
span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER)
span.set_tag('http.url', request.full_url)
remote_ip = request.remote_ip
if remote_ip:
span.set_tag(tags.PEER_HOST_IPV4, remote_ip)
caller_name = request.caller_name
if caller_name:
span.set_tag(tags.PEER_SERVICE, caller_name)
remote_port = request.remote_port
if remote_port:
span.set_tag(tags.PEER_PORT, remote_port)The caller_name was a custom behavior based on a special HTTP header that our services send to identify themselves, and the instrumentation is configured with the name of that header. And Python libs usually expose remote addr to the server, similar to Java servlets. Go's Request also has RemoteAddr field, but I was lazy to parse it (note to self: don't be lazy, fix it).
(See #237 for motivation and context)
"Demo" (sic)
The
addsvcin this PR uses the generic OpenTracing bindings for the httpjson and grpc transports, and in itsmain()it binds to either Appdash or LightStep (both of which are trivial to set up and have implementations of the Go OpenTracing API). As such, without changing any of the actual instrumentation beyond themain()function, both Appdash and LightStep are able to trace addsvc:Appdash
LightStep
Misc notes
The default implementation of OpenTracing is a noop. As such, rather than forcing users to install these various pieces of middleware/etc, some of this instrumentation could be opt-out, or perhaps downright unavoidable. Again, if the programmer didn't bother binding to OpenTracing, there would be near-zero overhead to support the noop implementation.
Also, the existing Zipkin instrumentation is worth thinking through in more detail. There are major companies that have adopted OpenTracing and bound it to Zipkin internally, so we know it's possible to go that route. If there's interest, we could try to port the
tracing/zipkinpackage to be a pure OpenTracing implementation. I don't know how many depend on its API already, though.Next steps
I'd like to get basic feedback about the direction. If there's enthusiasm, I can finish up the other transports, add real tests, and merge this in. If there are problems, I'd rather go through them now before finishing up all of the odds and ends.
Thanks for reviewing!
This change is