aboutsummaryrefslogtreecommitdiff
path: root/vendor/go.opencensus.io/plugin/ochttp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.opencensus.io/plugin/ochttp')
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/client.go27
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/server.go291
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/span_annotator.go160
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/stats.go10
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/trace.go39
5 files changed, 472 insertions, 55 deletions
diff --git a/vendor/go.opencensus.io/plugin/ochttp/client.go b/vendor/go.opencensus.io/plugin/ochttp/client.go
index 37f42b3..68faf24 100644
--- a/vendor/go.opencensus.io/plugin/ochttp/client.go
+++ b/vendor/go.opencensus.io/plugin/ochttp/client.go
@@ -16,14 +16,18 @@ 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
-// stats and tracing. The zero value is intended to be a useful default, but for
-// now it's recommended that you explicitly set Propagation.
+// 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.
@@ -43,17 +47,34 @@ type Transport struct {
// for spans started by this transport.
StartOptions 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
+ }
rt = &traceTransport{
base: rt,
format: format,
@@ -61,6 +82,8 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
Sampler: t.StartOptions.Sampler,
SpanKind: trace.SpanKindClient,
},
+ formatSpanName: spanNameFormatter,
+ newClientTrace: t.NewClientTrace,
}
rt = statsTransport{base: rt}
return rt.RoundTrip(req)
diff --git a/vendor/go.opencensus.io/plugin/ochttp/server.go b/vendor/go.opencensus.io/plugin/ochttp/server.go
index 4b3c855..72aa8c2 100644
--- a/vendor/go.opencensus.io/plugin/ochttp/server.go
+++ b/vendor/go.opencensus.io/plugin/ochttp/server.go
@@ -15,10 +15,8 @@
package ochttp
import (
- "bufio"
"context"
- "errors"
- "net"
+ "io"
"net/http"
"strconv"
"sync"
@@ -30,16 +28,19 @@ import (
"go.opencensus.io/trace/propagation"
)
-// Handler is a http.Handler that is aware of the incoming request's span.
+// Handler is an http.Handler wrapper to instrument your HTTP server with
+// OpenCensus. It supports both stats and tracing.
//
+// Tracing
+//
+// This handler is aware of the incoming request's span, reading it from request
+// headers as configured using the Propagation field.
// The extracted span can be accessed from the incoming request's
// context.
//
// span := trace.FromContext(r.Context())
//
// The server span will be automatically ended at the end of ServeHTTP.
-//
-// Incoming propagation mechanism is determined by the given HTTP propagators.
type Handler struct {
// Propagation defines how traces are propagated. If unspecified,
// B3 propagation will be used.
@@ -60,6 +61,11 @@ type Handler struct {
// be added as a linked trace instead of being added as a parent of the
// current trace.
IsPublicEndpoint bool
+
+ // FormatSpanName holds the function to use for generating the span name
+ // from the information found in the incoming HTTP Request. By default the
+ // name equals the URL Path.
+ FormatSpanName func(*http.Request) string
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -76,7 +82,15 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
func (h *Handler) startTrace(w http.ResponseWriter, r *http.Request) (*http.Request, func()) {
- name := spanNameFromURL(r.URL)
+ if isHealthEndpoint(r.URL.Path) {
+ return r, func() {}
+ }
+ var name string
+ if h.FormatSpanName == nil {
+ name = spanNameFromURL(r)
+ } else {
+ name = h.FormatSpanName(r)
+ }
ctx := r.Context()
var span *trace.Span
sc, ok := h.extractSpanContext(r)
@@ -126,7 +140,7 @@ func (h *Handler) startStats(w http.ResponseWriter, r *http.Request) (http.Respo
track.reqSize = r.ContentLength
}
stats.Record(ctx, ServerRequestCount.M(1))
- return track, track.end
+ return track.wrappedResponseWriter(), track.end
}
type trackingResponseWriter struct {
@@ -140,39 +154,9 @@ type trackingResponseWriter struct {
writer http.ResponseWriter
}
-// Compile time assertions for widely used net/http interfaces
-var _ http.CloseNotifier = (*trackingResponseWriter)(nil)
-var _ http.Flusher = (*trackingResponseWriter)(nil)
-var _ http.Hijacker = (*trackingResponseWriter)(nil)
-var _ http.Pusher = (*trackingResponseWriter)(nil)
+// Compile time assertion for ResponseWriter interface
var _ http.ResponseWriter = (*trackingResponseWriter)(nil)
-var errHijackerUnimplemented = errors.New("ResponseWriter does not implement http.Hijacker")
-
-func (t *trackingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- hj, ok := t.writer.(http.Hijacker)
- if !ok {
- return nil, nil, errHijackerUnimplemented
- }
- return hj.Hijack()
-}
-
-func (t *trackingResponseWriter) CloseNotify() <-chan bool {
- cn, ok := t.writer.(http.CloseNotifier)
- if !ok {
- return nil
- }
- return cn.CloseNotify()
-}
-
-func (t *trackingResponseWriter) Push(target string, opts *http.PushOptions) error {
- pusher, ok := t.writer.(http.Pusher)
- if !ok {
- return http.ErrNotSupported
- }
- return pusher.Push(target, opts)
-}
-
func (t *trackingResponseWriter) end() {
t.endOnce.Do(func() {
if t.statusCode == 0 {
@@ -210,8 +194,231 @@ func (t *trackingResponseWriter) WriteHeader(statusCode int) {
t.statusLine = http.StatusText(t.statusCode)
}
-func (t *trackingResponseWriter) Flush() {
- if flusher, ok := t.writer.(http.Flusher); ok {
- flusher.Flush()
+// wrappedResponseWriter returns a wrapped version of the original
+// ResponseWriter and only implements the same combination of additional
+// interfaces as the original.
+// This implementation is based on https://github.com/felixge/httpsnoop.
+func (t *trackingResponseWriter) wrappedResponseWriter() http.ResponseWriter {
+ var (
+ hj, i0 = t.writer.(http.Hijacker)
+ cn, i1 = t.writer.(http.CloseNotifier)
+ pu, i2 = t.writer.(http.Pusher)
+ fl, i3 = t.writer.(http.Flusher)
+ rf, i4 = t.writer.(io.ReaderFrom)
+ )
+
+ switch {
+ case !i0 && !i1 && !i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ }{t}
+ case !i0 && !i1 && !i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ io.ReaderFrom
+ }{t, rf}
+ case !i0 && !i1 && !i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Flusher
+ }{t, fl}
+ case !i0 && !i1 && !i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Flusher
+ io.ReaderFrom
+ }{t, fl, rf}
+ case !i0 && !i1 && i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Pusher
+ }{t, pu}
+ case !i0 && !i1 && i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Pusher
+ io.ReaderFrom
+ }{t, pu, rf}
+ case !i0 && !i1 && i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Pusher
+ http.Flusher
+ }{t, pu, fl}
+ case !i0 && !i1 && i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Pusher
+ http.Flusher
+ io.ReaderFrom
+ }{t, pu, fl, rf}
+ case !i0 && i1 && !i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ }{t, cn}
+ case !i0 && i1 && !i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ io.ReaderFrom
+ }{t, cn, rf}
+ case !i0 && i1 && !i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ http.Flusher
+ }{t, cn, fl}
+ case !i0 && i1 && !i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ http.Flusher
+ io.ReaderFrom
+ }{t, cn, fl, rf}
+ case !i0 && i1 && i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ http.Pusher
+ }{t, cn, pu}
+ case !i0 && i1 && i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ http.Pusher
+ io.ReaderFrom
+ }{t, cn, pu, rf}
+ case !i0 && i1 && i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ http.Pusher
+ http.Flusher
+ }{t, cn, pu, fl}
+ case !i0 && i1 && i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.CloseNotifier
+ http.Pusher
+ http.Flusher
+ io.ReaderFrom
+ }{t, cn, pu, fl, rf}
+ case i0 && !i1 && !i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ }{t, hj}
+ case i0 && !i1 && !i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ io.ReaderFrom
+ }{t, hj, rf}
+ case i0 && !i1 && !i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.Flusher
+ }{t, hj, fl}
+ case i0 && !i1 && !i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.Flusher
+ io.ReaderFrom
+ }{t, hj, fl, rf}
+ case i0 && !i1 && i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.Pusher
+ }{t, hj, pu}
+ case i0 && !i1 && i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.Pusher
+ io.ReaderFrom
+ }{t, hj, pu, rf}
+ case i0 && !i1 && i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.Pusher
+ http.Flusher
+ }{t, hj, pu, fl}
+ case i0 && !i1 && i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.Pusher
+ http.Flusher
+ io.ReaderFrom
+ }{t, hj, pu, fl, rf}
+ case i0 && i1 && !i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ }{t, hj, cn}
+ case i0 && i1 && !i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ io.ReaderFrom
+ }{t, hj, cn, rf}
+ case i0 && i1 && !i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ http.Flusher
+ }{t, hj, cn, fl}
+ case i0 && i1 && !i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ http.Flusher
+ io.ReaderFrom
+ }{t, hj, cn, fl, rf}
+ case i0 && i1 && i2 && !i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ http.Pusher
+ }{t, hj, cn, pu}
+ case i0 && i1 && i2 && !i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ http.Pusher
+ io.ReaderFrom
+ }{t, hj, cn, pu, rf}
+ case i0 && i1 && i2 && i3 && !i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ http.Pusher
+ http.Flusher
+ }{t, hj, cn, pu, fl}
+ case i0 && i1 && i2 && i3 && i4:
+ return struct {
+ http.ResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+ http.Pusher
+ http.Flusher
+ io.ReaderFrom
+ }{t, hj, cn, pu, fl, rf}
+ default:
+ return struct {
+ http.ResponseWriter
+ }{t}
}
}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/span_annotator.go b/vendor/go.opencensus.io/plugin/ochttp/span_annotator.go
new file mode 100644
index 0000000..1282287
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/span_annotator.go
@@ -0,0 +1,160 @@
+// 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 (
+ "crypto/tls"
+ "net/http"
+ "net/http/httptrace"
+ "strings"
+
+ "go.opencensus.io/trace"
+)
+
+type spanAnnotator struct {
+ sp *trace.Span
+}
+
+// NewSpanAnnotator returns a httptrace.ClientTrace which annotates all emitted
+// httptrace events on the provided Span.
+func NewSpanAnnotator(_ *http.Request, s *trace.Span) *httptrace.ClientTrace {
+ sa := spanAnnotator{sp: s}
+
+ return &httptrace.ClientTrace{
+ GetConn: sa.getConn,
+ GotConn: sa.gotConn,
+ PutIdleConn: sa.putIdleConn,
+ GotFirstResponseByte: sa.gotFirstResponseByte,
+ Got100Continue: sa.got100Continue,
+ DNSStart: sa.dnsStart,
+ DNSDone: sa.dnsDone,
+ ConnectStart: sa.connectStart,
+ ConnectDone: sa.connectDone,
+ TLSHandshakeStart: sa.tlsHandshakeStart,
+ TLSHandshakeDone: sa.tlsHandshakeDone,
+ WroteHeaders: sa.wroteHeaders,
+ Wait100Continue: sa.wait100Continue,
+ WroteRequest: sa.wroteRequest,
+ }
+}
+
+func (s spanAnnotator) getConn(hostPort string) {
+ attrs := []trace.Attribute{
+ trace.StringAttribute("httptrace.get_connection.host_port", hostPort),
+ }
+ s.sp.Annotate(attrs, "GetConn")
+}
+
+func (s spanAnnotator) gotConn(info httptrace.GotConnInfo) {
+ attrs := []trace.Attribute{
+ trace.BoolAttribute("httptrace.got_connection.reused", info.Reused),
+ trace.BoolAttribute("httptrace.got_connection.was_idle", info.WasIdle),
+ }
+ if info.WasIdle {
+ attrs = append(attrs,
+ trace.StringAttribute("httptrace.got_connection.idle_time", info.IdleTime.String()))
+ }
+ s.sp.Annotate(attrs, "GotConn")
+}
+
+// PutIdleConn implements a httptrace.ClientTrace hook
+func (s spanAnnotator) putIdleConn(err error) {
+ var attrs []trace.Attribute
+ if err != nil {
+ attrs = append(attrs,
+ trace.StringAttribute("httptrace.put_idle_connection.error", err.Error()))
+ }
+ s.sp.Annotate(attrs, "PutIdleConn")
+}
+
+func (s spanAnnotator) gotFirstResponseByte() {
+ s.sp.Annotate(nil, "GotFirstResponseByte")
+}
+
+func (s spanAnnotator) got100Continue() {
+ s.sp.Annotate(nil, "Got100Continue")
+}
+
+func (s spanAnnotator) dnsStart(info httptrace.DNSStartInfo) {
+ attrs := []trace.Attribute{
+ trace.StringAttribute("httptrace.dns_start.host", info.Host),
+ }
+ s.sp.Annotate(attrs, "DNSStart")
+}
+
+func (s spanAnnotator) dnsDone(info httptrace.DNSDoneInfo) {
+ var addrs []string
+ for _, addr := range info.Addrs {
+ addrs = append(addrs, addr.String())
+ }
+ attrs := []trace.Attribute{
+ trace.StringAttribute("httptrace.dns_done.addrs", strings.Join(addrs, " , ")),
+ }
+ if info.Err != nil {
+ attrs = append(attrs,
+ trace.StringAttribute("httptrace.dns_done.error", info.Err.Error()))
+ }
+ s.sp.Annotate(attrs, "DNSDone")
+}
+
+func (s spanAnnotator) connectStart(network, addr string) {
+ attrs := []trace.Attribute{
+ trace.StringAttribute("httptrace.connect_start.network", network),
+ trace.StringAttribute("httptrace.connect_start.addr", addr),
+ }
+ s.sp.Annotate(attrs, "ConnectStart")
+}
+
+func (s spanAnnotator) connectDone(network, addr string, err error) {
+ attrs := []trace.Attribute{
+ trace.StringAttribute("httptrace.connect_done.network", network),
+ trace.StringAttribute("httptrace.connect_done.addr", addr),
+ }
+ if err != nil {
+ attrs = append(attrs,
+ trace.StringAttribute("httptrace.connect_done.error", err.Error()))
+ }
+ s.sp.Annotate(attrs, "ConnectDone")
+}
+
+func (s spanAnnotator) tlsHandshakeStart() {
+ s.sp.Annotate(nil, "TLSHandshakeStart")
+}
+
+func (s spanAnnotator) tlsHandshakeDone(_ tls.ConnectionState, err error) {
+ var attrs []trace.Attribute
+ if err != nil {
+ attrs = append(attrs,
+ trace.StringAttribute("httptrace.tls_handshake_done.error", err.Error()))
+ }
+ s.sp.Annotate(attrs, "TLSHandshakeDone")
+}
+
+func (s spanAnnotator) wroteHeaders() {
+ s.sp.Annotate(nil, "WroteHeaders")
+}
+
+func (s spanAnnotator) wait100Continue() {
+ s.sp.Annotate(nil, "Wait100Continue")
+}
+
+func (s spanAnnotator) wroteRequest(info httptrace.WroteRequestInfo) {
+ var attrs []trace.Attribute
+ if info.Err != nil {
+ attrs = append(attrs,
+ trace.StringAttribute("httptrace.wrote_request.error", info.Err.Error()))
+ }
+ s.sp.Annotate(attrs, "WroteRequest")
+}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/stats.go b/vendor/go.opencensus.io/plugin/ochttp/stats.go
index 2bd11f6..19a8825 100644
--- a/vendor/go.opencensus.io/plugin/ochttp/stats.go
+++ b/vendor/go.opencensus.io/plugin/ochttp/stats.go
@@ -41,6 +41,10 @@ var (
// ClientRequestCount or ServerRequestCount, since it is recorded before the status is known.
var (
// Host is the value of the HTTP Host header.
+ //
+ // The value of this tag can be controlled by the HTTP client, so you need
+ // to watch out for potentially generating high-cardinality labels in your
+ // metrics backend if you use this tag in views.
Host, _ = tag.NewKey("http.host")
// StatusCode is the numeric HTTP response status code,
@@ -48,6 +52,10 @@ var (
StatusCode, _ = tag.NewKey("http.status")
// Path is the URL path (not including query string) in the request.
+ //
+ // The value of this tag can be controlled by the HTTP client, so you need
+ // to watch out for potentially generating high-cardinality labels in your
+ // metrics backend if you use this tag in views.
Path, _ = tag.NewKey("http.path")
// Method is the HTTP method of the request, capitalized (GET, POST, etc.).
@@ -61,7 +69,7 @@ var (
)
// Package ochttp provides some convenience views.
-// You need to subscribe to the views for data to actually be collected.
+// You need to register the views for data to actually be collected.
var (
ClientRequestCountView = &view.View{
Name: "opencensus.io/http/client/request_count",
diff --git a/vendor/go.opencensus.io/plugin/ochttp/trace.go b/vendor/go.opencensus.io/plugin/ochttp/trace.go
index 79bbfd1..980b639 100644
--- a/vendor/go.opencensus.io/plugin/ochttp/trace.go
+++ b/vendor/go.opencensus.io/plugin/ochttp/trace.go
@@ -17,7 +17,7 @@ package ochttp
import (
"io"
"net/http"
- "net/url"
+ "net/http/httptrace"
"go.opencensus.io/plugin/ochttp/propagation/b3"
"go.opencensus.io/trace"
@@ -39,9 +39,11 @@ const (
)
type traceTransport struct {
- base http.RoundTripper
- startOptions trace.StartOptions
- format propagation.HTTPFormat
+ base http.RoundTripper
+ startOptions trace.StartOptions
+ format propagation.HTTPFormat
+ formatSpanName func(*http.Request) string
+ newClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace
}
// TODO(jbd): Add message events for request and response size.
@@ -50,14 +52,19 @@ type traceTransport struct {
// The created span can follow a parent span, if a parent is presented in
// the request's context.
func (t *traceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
- name := spanNameFromURL(req.URL)
+ name := t.formatSpanName(req)
// TODO(jbd): Discuss whether we want to prefix
// outgoing requests with Sent.
- _, span := trace.StartSpan(req.Context(), name,
+ ctx, span := trace.StartSpan(req.Context(), name,
trace.WithSampler(t.startOptions.Sampler),
trace.WithSpanKind(trace.SpanKindClient))
- req = req.WithContext(trace.WithSpan(req.Context(), span))
+ if t.newClientTrace != nil {
+ req = req.WithContext(httptrace.WithClientTrace(ctx, t.newClientTrace(req, span)))
+ } else {
+ req = req.WithContext(ctx)
+ }
+
if t.format != nil {
t.format.SpanContextToRequest(span.SpanContext(), req)
}
@@ -127,8 +134,8 @@ func (t *traceTransport) CancelRequest(req *http.Request) {
}
}
-func spanNameFromURL(u *url.URL) string {
- return u.Path
+func spanNameFromURL(req *http.Request) string {
+ return req.URL.Path
}
func requestAttrs(r *http.Request) []trace.Attribute {
@@ -146,7 +153,7 @@ func responseAttrs(resp *http.Response) []trace.Attribute {
}
}
-// TraceStatus converts the HTTP status code to a trace.Status that
+// TraceStatus is a utility to convert the HTTP status code to a trace.Status that
// represents the outcome as closely as possible.
func TraceStatus(httpStatusCode int, statusLine string) trace.Status {
var code int32
@@ -197,3 +204,15 @@ var codeToStr = map[int32]string{
trace.StatusCodeDataLoss: `"DATA_LOSS"`,
trace.StatusCodeUnauthenticated: `"UNAUTHENTICATED"`,
}
+
+func isHealthEndpoint(path string) bool {
+ // Health checking is pretty frequent and
+ // traces collected for health endpoints
+ // can be extremely noisy and expensive.
+ // Disable canonical health checking endpoints
+ // like /healthz and /_ah/health for now.
+ if path == "/healthz" || path == "/_ah/health" {
+ return true
+ }
+ return false
+}