You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

115 lines
3.5 KiB

  1. // Copyright 2017 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package trace
  15. import (
  16. "net/http"
  17. )
  18. // Transport is an http.RoundTripper that traces the outgoing requests.
  19. //
  20. // Transport is safe for concurrent usage.
  21. //
  22. // Deprecated: see https://cloud.google.com/trace/docs/setup/go.
  23. type Transport struct {
  24. // Base is the base http.RoundTripper to be used to do the actual request.
  25. //
  26. // Optional. If nil, http.DefaultTransport is used.
  27. Base http.RoundTripper
  28. }
  29. // RoundTrip creates a trace.Span and inserts it into the outgoing request's headers.
  30. // The created span can follow a parent span, if a parent is presented in
  31. // the request's context.
  32. //
  33. // Deprecated: see https://cloud.google.com/trace/docs/setup/go.
  34. func (t Transport) RoundTrip(req *http.Request) (*http.Response, error) {
  35. span := FromContext(req.Context()).NewRemoteChild(req)
  36. resp, err := t.base().RoundTrip(req)
  37. // TODO(jbd): Is it possible to defer the span.Finish?
  38. // In cases where RoundTrip panics, we still can finish the span.
  39. span.Finish(WithResponse(resp))
  40. return resp, err
  41. }
  42. // CancelRequest cancels an in-flight request by closing its connection.
  43. //
  44. // Deprecated: see https://cloud.google.com/trace/docs/setup/go.
  45. func (t Transport) CancelRequest(req *http.Request) {
  46. type canceler interface {
  47. CancelRequest(*http.Request)
  48. }
  49. if cr, ok := t.base().(canceler); ok {
  50. cr.CancelRequest(req)
  51. }
  52. }
  53. func (t Transport) base() http.RoundTripper {
  54. if t.Base != nil {
  55. return t.Base
  56. }
  57. return http.DefaultTransport
  58. }
  59. // HTTPHandler returns a http.Handler from the given handler
  60. // that is aware of the incoming request's span.
  61. // The span can be extracted from the incoming request in handler
  62. // functions from incoming request's context:
  63. //
  64. // span := trace.FromContext(r.Context())
  65. //
  66. // The span will be auto finished by the handler.
  67. //
  68. // Deprecated: see https://cloud.google.com/trace/docs/setup/go.
  69. func (c *Client) HTTPHandler(h http.Handler) http.Handler {
  70. if c == nil {
  71. return h
  72. }
  73. return &handler{traceClient: c, handler: h}
  74. }
  75. type handler struct {
  76. traceClient *Client
  77. handler http.Handler
  78. }
  79. // Deprecated: see https://cloud.google.com/trace/docs/setup/go.
  80. func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  81. traceID, parentSpanID, options, optionsOk, ok := traceInfoFromHeader(r.Header.Get(httpHeader))
  82. if !ok {
  83. traceID = nextTraceID()
  84. }
  85. t := &trace{
  86. traceID: traceID,
  87. client: h.traceClient,
  88. globalOptions: options,
  89. localOptions: options,
  90. }
  91. span := startNewChildWithRequest(r, t, parentSpanID)
  92. span.span.Kind = spanKindServer
  93. span.rootSpan = true
  94. configureSpanFromPolicy(span, h.traceClient.policy, ok)
  95. defer span.Finish()
  96. r = r.WithContext(NewContext(r.Context(), span))
  97. if ok && !optionsOk {
  98. // Inject the trace context back to the response with the sampling options.
  99. // TODO(jbd): Remove when there is a better way to report the client's sampling.
  100. w.Header().Set(httpHeader, spanHeader(traceID, parentSpanID, span.trace.localOptions))
  101. }
  102. h.handler.ServeHTTP(w, r)
  103. }