Documentation ¶
Overview ¶
Package otelhttp provides an http.Handler and functions that are intended to be used to add tracing by wrapping existing handlers (with Handler) and routes WithRouteTag.
Index ¶
- Constants
- Variables
- func Get(ctx context.Context, url string) (resp *http.Response, err error)
- func Head(ctx context.Context, url string) (resp *http.Response, err error)
- func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler
- func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *http.Response, err error)
- func PostForm(ctx context.Context, url string, data url.Values) (resp *http.Response, err error)
- func SemVersion() string
- func Version() string
- func WithRouteTag(route string, h http.Handler) http.Handler
- type Filter
- type Handler
- type Labeler
- type Option
- func WithFilter(f Filter) Option
- func WithMessageEvents(events ...event) Option
- func WithMeterProvider(provider metric.MeterProvider) Option
- func WithPropagators(ps propagation.TextMapPropagator) Option
- func WithPublicEndpoint() Option
- func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option
- func WithSpanOptions(opts ...trace.SpanStartOption) Option
- func WithTracerProvider(provider trace.TracerProvider) Option
- type Transport
Examples ¶
Constants ¶
const ( ReadBytesKey = attribute.Key("http.read_bytes") // if anything was read from the request body, the total number of bytes read ReadErrorKey = attribute.Key("http.read_error") // If an error occurred while reading a request, the string of the error (io.EOF is not recorded) WroteBytesKey = attribute.Key("http.wrote_bytes") // if anything was written to the response writer, the total number of bytes written WriteErrorKey = attribute.Key("http.write_error") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded) )
Attribute keys that can be added to a span.
const ( RequestCount = "http.server.request_count" // Incoming request count total RequestContentLength = "http.server.request_content_length" // Incoming request bytes total ResponseContentLength = "http.server.response_content_length" // Incoming response bytes total ServerLatency = "http.server.duration" // Incoming end to end duration, microseconds )
Server HTTP metrics
const ( ReadEvents event = iota WriteEvents )
Different types of events that can be recorded, see WithMessageEvents
Variables ¶
var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)}
DefaultClient is the default Client and is used by Get, Head, Post and PostForm. Please be careful of intitialization order - for example, if you change the global propagator, the DefaultClient might still be using the old one
Functions ¶
func NewHandler ¶
NewHandler wraps the passed handler, functioning like middleware, in a span named after the operation and with any provided Options.
Example ¶
package main import ( "context" "fmt" "io" "io/ioutil" "log" "net/http" "strings" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "github.com/trussworks/otelhttp" ) func main() { /* curl -v -d "a painting" http://localhost:7777/hello/bob/ross ... * upload completely sent off: 10 out of 10 bytes < HTTP/1.1 200 OK < Traceparent: 00-76ae040ee5753f38edf1c2bd9bd128bd-dd394138cfd7a3dc-01 < Date: Fri, 04 Oct 2019 02:33:08 GMT < Content-Length: 45 < Content-Type: text/plain; charset=utf-8 < Hello, bob/ross! You sent me this: a painting */ figureOutName := func(ctx context.Context, s string) (string, error) { pp := strings.SplitN(s, "/", 2) var err error switch pp[1] { case "": err = fmt.Errorf("expected /hello/:name in %q", s) default: trace.SpanFromContext(ctx).SetAttributes(attribute.String("name", pp[1])) } return pp[1], err } var mux http.ServeMux mux.Handle("/hello/", otelhttp.WithRouteTag("/hello/:name", http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() labeler, _ := otelhttp.LabelerFromContext(ctx) var name string // Wrap another function in its own span if err := func(ctx context.Context) error { ctx, span := trace.SpanFromContext(ctx).TracerProvider().Tracer("exampleTracer").Start(ctx, "figureOutName") defer span.End() var err error name, err = figureOutName(ctx, r.URL.Path[1:]) return err }(ctx); err != nil { log.Println("error figuring out name: ", err) http.Error(w, err.Error(), http.StatusInternalServerError) labeler.Add(attribute.Bool("error", true)) return } d, err := ioutil.ReadAll(r.Body) if err != nil { log.Println("error reading body: ", err) w.WriteHeader(http.StatusBadRequest) labeler.Add(attribute.Bool("error", true)) return } n, err := io.WriteString(w, "Hello, "+name+"!\nYou sent me this:\n"+string(d)) if err != nil { log.Printf("error writing reply after %d bytes: %s", n, err) labeler.Add(attribute.Bool("error", true)) } }), ), ) // "G114: Use of net/http serve function that has no support for setting timeouts" // This is just used in a test, so should be safe to suppress. // #nosec G114 if err := http.ListenAndServe(":7777", otelhttp.NewHandler(&mux, "server", otelhttp.WithMessageEvents(otelhttp.ReadEvents, otelhttp.WriteEvents), ), ); err != nil { log.Fatal(err) } }
Output:
func Post ¶
func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *http.Response, err error)
Post is a convenient replacement for http.Post that adds a span around the request.
func PostForm ¶
PostForm is a convenient replacement for http.PostForm that adds a span around the request.
func SemVersion ¶
func SemVersion() string
SemVersion is the semantic version to be supplied to tracer/meter creation.
Types ¶
type Filter ¶
Filter is a predicate used to determine whether a given http.request should be traced. A Filter must return true if the request should be traced.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is http middleware that corresponds to the http.Handler interface and is designed to wrap a http.Mux (or equivalent), while individual routes on the mux are wrapped with WithRouteTag. A Handler will add various attributes to the span using the attribute.Keys defined in this package.
type Labeler ¶
type Labeler struct {
// contains filtered or unexported fields
}
Labeler is used to allow instrumented HTTP handlers to add custom attributes to the metrics recorded by the net/http instrumentation.
func LabelerFromContext ¶
LabelerFromContext retrieves a Labeler instance from the provided context if one is available. If no Labeler was found in the provided context a new, empty Labeler is returned and the second return value is false. In this case it is safe to use the Labeler but any attributes added to it will not be used.
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option interface used for setting optional config properties.
func WithFilter ¶
WithFilter adds a filter to the list of filters used by the handler. If any filter indicates to exclude a request then the request will not be traced. All filters must allow a request to be traced for a Span to be created. If no filters are provided then all requests are traced. Filters will be invoked for each processed request, it is advised to make them simple and fast.
func WithMessageEvents ¶
func WithMessageEvents(events ...event) Option
WithMessageEvents configures the Handler to record the specified events (span.AddEvent) on spans. By default only summary attributes are added at the end of the request.
Valid events are:
- ReadEvents: Record the number of bytes read after every http.Request.Body.Read using the ReadBytesKey
- WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write using the WriteBytesKey
func WithMeterProvider ¶
func WithMeterProvider(provider metric.MeterProvider) Option
WithMeterProvider specifies a meter provider to use for creating a meter. If none is specified, the global provider is used.
func WithPropagators ¶
func WithPropagators(ps propagation.TextMapPropagator) Option
WithPropagators configures specific propagators. If this option isn't specified, then the global TextMapPropagator is used.
func WithPublicEndpoint ¶
func WithPublicEndpoint() Option
WithPublicEndpoint configures the Handler to link the span with an incoming span context. If this option is not provided, then the association is a child association instead of a link.
func WithSpanNameFormatter ¶
WithSpanNameFormatter takes a function that will be called on every request and the returned string will become the Span Name
func WithSpanOptions ¶
func WithSpanOptions(opts ...trace.SpanStartOption) Option
WithSpanOptions configures an additional set of trace.SpanOptions, which are applied to each new span.
func WithTracerProvider ¶
func WithTracerProvider(provider trace.TracerProvider) Option
WithTracerProvider specifies a tracer provider to use for creating a tracer. If none is specified, the global provider is used.
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport implements the http.RoundTripper interface and wraps outbound HTTP(S) requests with a span.
func NewTransport ¶
func NewTransport(base http.RoundTripper, opts ...Option) *Transport
NewTransport wraps the provided http.RoundTripper with one that starts a span and injects the span context into the outbound request headers.
If the provided http.RoundTripper is nil, http.DefaultTransport will be used as the base http.RoundTripper
Example ¶
// Create an http.Client that uses the (ot)http.Transport // wrapped around the http.DefaultTransport _ = http.Client{ Transport: NewTransport(http.DefaultTransport), }
Output:
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package filters provides a set of filters useful with the otelhttp.WithFilter() option to control which inbound requests are traced.
|
Package filters provides a set of filters useful with the otelhttp.WithFilter() option to control which inbound requests are traced. |
Package test validates the otelhttp instrumentation with the default SDK.
|
Package test validates the otelhttp instrumentation with the default SDK. |