|
- // Copyright 2018, OpenCensus Authors
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- package ochttp
-
- import (
- "net/http"
- "net/http/httptrace"
-
- "go.opencensus.io/trace"
- "go.opencensus.io/trace/propagation"
- )
-
- // Transport is an http.RoundTripper that instruments all outgoing requests with
- // OpenCensus stats and tracing.
- //
- // The zero value is intended to be a useful default, but for
- // now it's recommended that you explicitly set Propagation, since the default
- // for this may change.
- type Transport struct {
- // Base may be set to wrap another http.RoundTripper that does the actual
- // requests. By default http.DefaultTransport is used.
- //
- // If base HTTP roundtripper implements CancelRequest,
- // the returned round tripper will be cancelable.
- Base http.RoundTripper
-
- // Propagation defines how traces are propagated. If unspecified, a default
- // (currently B3 format) will be used.
- Propagation propagation.HTTPFormat
-
- // StartOptions are applied to the span started by this Transport around each
- // request.
- //
- // StartOptions.SpanKind will always be set to trace.SpanKindClient
- // for spans started by this transport.
- StartOptions trace.StartOptions
-
- // GetStartOptions allows to set start options per request. If set,
- // StartOptions is going to be ignored.
- GetStartOptions func(*http.Request) trace.StartOptions
-
- // NameFromRequest holds the function to use for generating the span name
- // from the information found in the outgoing HTTP Request. By default the
- // name equals the URL Path.
- FormatSpanName func(*http.Request) string
-
- // 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
-
- // TODO: Implement tag propagation for HTTP.
- }
-
- // RoundTrip implements http.RoundTripper, delegating to Base and recording stats and traces for the request.
- func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
- rt := t.base()
- if isHealthEndpoint(req.URL.Path) {
- return rt.RoundTrip(req)
- }
- // TODO: remove excessive nesting of http.RoundTrippers here.
- format := t.Propagation
- if format == nil {
- format = defaultFormat
- }
- spanNameFormatter := t.FormatSpanName
- if spanNameFormatter == nil {
- spanNameFormatter = spanNameFromURL
- }
-
- startOpts := t.StartOptions
- if t.GetStartOptions != nil {
- startOpts = t.GetStartOptions(req)
- }
-
- rt = &traceTransport{
- base: rt,
- format: format,
- startOptions: trace.StartOptions{
- Sampler: startOpts.Sampler,
- SpanKind: trace.SpanKindClient,
- },
- formatSpanName: spanNameFormatter,
- newClientTrace: t.NewClientTrace,
- }
- rt = statsTransport{base: rt}
- return rt.RoundTrip(req)
- }
-
- func (t *Transport) base() http.RoundTripper {
- if t.Base != nil {
- return t.Base
- }
- return http.DefaultTransport
- }
-
- // CancelRequest cancels an in-flight request by closing its connection.
- func (t *Transport) CancelRequest(req *http.Request) {
- type canceler interface {
- CancelRequest(*http.Request)
- }
- if cr, ok := t.base().(canceler); ok {
- cr.CancelRequest(req)
- }
- }
|