-
Notifications
You must be signed in to change notification settings - Fork 329
adds ClientTracer option to allow usage of httptrace package with ochttp #848
adds ClientTracer option to allow usage of httptrace package with ochttp #848
Conversation
plugin/ochttp/client_trace.go
Outdated
// ClientTrace implements the annotation of all available hooks for | ||
// httptrace.ClientTrace. | ||
type ClientTrace struct { | ||
*trace.Span |
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.
Don't use embedding here. There's no need to import the whole API surface of Span.
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.
Also, this doesn't need to be exported does it?
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.
We can lose the embedding but we should keep the export as it allows people to write their own func(*trace.Span) *httptrace.ClientTrace
for selecting the set of hooks they want annotated by this ClientTrace.
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.
I don't understand why this needs to be public. If they want to use only a subset of the hooks, they can simply set the corresponding fields to nil in the returned ClientTrace. Likewise, if they want to use their own ClientTrace and copy across some of the fields, they can do this too by calling methods on ClientTrace directly.
plugin/ochttp/client.go
Outdated
// ClientTracer may be set to a function allowing OpenCensus to annotate the | ||
// current span with HTTP request event information emitted by the httptrace | ||
// package. | ||
ClientTracer func(*trace.Span) *httptrace.ClientTrace |
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.
Call it NewClientTrace
, like sync.Pool
's New
.
Also might want to pass in the http.Request
in case they want to specialize based on some attribute of the request.
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.
ok
plugin/ochttp/client_trace.go
Outdated
*trace.Span | ||
} | ||
|
||
// ClientTracer returns a httptrace.ClientTrace instance which instruments all |
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.
I would mention that it adds annotations specifically. Also the word "instance" is a little odd, why not just "returns a httptrace.ClientTrace"?
Second, I would also delegate to the contextual httptrace.ClientTrace (if present) so this doesn't break any other instrumentation they might already have.
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.
Removed the word instance as requested.
Not sure I follow the second remark; the clientTracer uses http.WithClientTrace() to attach itself. This function should take care of playing nice with other instrumentation if I read the description right.
plugin/ochttp/client_trace.go
Outdated
|
||
// ClientTracer returns a httptrace.ClientTrace instance which instruments all | ||
// emitted httptrace events on the provided Span. | ||
func ClientTracer(s *trace.Span) *httptrace.ClientTrace { |
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.
The name here doesn't add much. Maybe NewSpanAnnotator
?
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.
ok
plugin/ochttp/client.go
Outdated
// ClientTracer may be set to a function allowing OpenCensus to annotate the | ||
// current span with HTTP request event information emitted by the httptrace | ||
// package. | ||
ClientTracer func(*http.Request, *trace.Span) *httptrace.ClientTrace |
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.
My point with the name is that this is not the ClientTrace itself - it is a constructor function for the ClientTrace - so I think the name "NewClientTrace" is more appropriate.
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.
NewClientTrace doesn't sit well with me as a property of the Transport struct but I'll admit I see your point on ClientTracer being not great either. I'll use NewClientTrace.
plugin/ochttp/client_trace.go
Outdated
// ClientTrace implements the annotation of all available hooks for | ||
// httptrace.ClientTrace. | ||
type ClientTrace struct { | ||
*trace.Span |
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.
I don't understand why this needs to be public. If they want to use only a subset of the hooks, they can simply set the corresponding fields to nil in the returned ClientTrace. Likewise, if they want to use their own ClientTrace and copy across some of the fields, they can do this too by calling methods on ClientTrace directly.
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.
I think we should call the field NewClientTrace instead of ClientTracer
plugin/ochttp/span_annotator.go
Outdated
|
||
// SpanAnnotator implements the annotation of all available hooks for | ||
// httptrace.ClientTrace. | ||
type SpanAnnotator struct { |
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.
I don't understand why this needs to be public. If they want to use only a subset of the hooks, they can simply set the corresponding fields to nil in the returned ClientTrace. Likewise, if they want to use their own ClientTrace and copy across some of the fields, they can do this too by calling methods on ClientTrace directly.
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.
I guess it is a matter of opinion on what is the friendlier method for consumers.
Your preference is eliminating the hooks not desired:
func NewSpanAnnotatorWrapper(req *http.Request, s *trace.Span) *httptrace.ClientTrace {
clientTrace := ochttp.NewSpanAnnotator(req, s)
// deregister unwanted hooks
clientTrace.GetConn = nil
clientTrace.Got100Continue = nil
...
return clientTrace
}
...
transport := ochttp.Transport{
NewClientTrace: NewSpanAnnotatorWrapper,
}
Mine is choosing the hooks that are:
func NewSpanAnnotator(req *http.Request, s *trace.Span) *httptrace.ClientTrace {
spanAnnotator := ochttp.SpanAnnotator{s}
// register wanted hooks
return &httptrace.ClientTrace{
GetConn: spanAnnotator.PutIdleConn,
GotFirstResponseByte: spanAnnotator.GotFirstResponseByte,
DNSStart: spanAnnotator.DNSStart,
...
}
}
...
transport := ochttp.Transport{
ClientTracer: NewSpanAnnotator,
}
Which reminds me why I wanted SpanAnnotator to embed *trace.Span or otherwise have it be an exported property. Bear in mind that the actual resulting *httptrace.ClientTrace or SpanAnnotator is created and contained within ochttp's traceTransport.RoundTrip().
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.
I still don't see why the type needs to be public. You could do this :
t := &ochttp.Transport {
ClientTracer: func(r *http.Request, s *trace.Span) *httptrace.ClientTrace {
ann := ochttp.NewSpanAnnotator(r,s)
return &httptrace.ClientTrace {
GetConn: ann.GetConn
}
}
}
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.
Adding a type adds complexity and distraction to the godoc
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.
Yeah I seemed to have forgotten because the function outputs *httptrace.ClientTrace I can always wrap it with a new one. Good thing vacation is coming up for some fresh eyes.
Will not only unexport SpanAnnotator but all its methods can be unexported too.
// NewClientTrace may be set to a function allowing the current *trace.Span | ||
// to be annotated with HTTP request event information emitted by the | ||
// httptrace package. | ||
NewClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace |
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.
We don't often call fields after New* in Go. I'd rather wished this was named ClientTrace. Can we make this modification given there are no users of this yet?
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.
Not a huge deal if we are not doing it. I also don't think sync.Pool.New is well representative of the overall Go style in these cases.
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.
Do you have an example from the standard library of something that you think is representative? I couldn't think of anything except that.
I think it's fine to make changes since we haven't created a release yet.
This adds the option to use the httptrace package with the ochttp RountTripper for more granular annotation of http requests.
This solves #309.