othttp

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2020 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package othttp provides a http.Handler and functions that are intended to be used to add tracing by wrapping existing handlers (with Handler) and routes WithRouteTag.

Index

Examples

Constants

View Source
const (
	ReadBytesKey  = kv.Key("http.read_bytes")  // if anything was read from the request body, the total number of bytes read
	ReadErrorKey  = kv.Key("http.read_error")  // If an error occurred while reading a request, the string of the error (io.EOF is not recorded)
	WroteBytesKey = kv.Key("http.wrote_bytes") // if anything was written to the response writer, the total number of bytes written
	WriteErrorKey = kv.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.

View Source
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

View Source
const (
	ReadEvents event = iota
	WriteEvents
)

Different types of events that can be recorded, see WithMessageEvents

Variables

This section is empty.

Functions

func NewHandler

func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler

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/api/kv"

	"go.opentelemetry.io/otel/api/trace"
	"go.opentelemetry.io/otel/instrumentation/othttp"
)

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(kv.String("name", pp[1]))
		}
		return pp[1], err
	}

	var mux http.ServeMux
	mux.Handle("/hello/",
		othttp.WithRouteTag("/hello/:name", http.HandlerFunc(
			func(w http.ResponseWriter, r *http.Request) {
				ctx := r.Context()
				var name string
				// Wrap another function in its own span
				if err := trace.SpanFromContext(ctx).Tracer().WithSpan(ctx, "figureOutName",
					func(ctx context.Context) error {
						var err error
						name, err = figureOutName(ctx, r.URL.Path[1:])
						return err
					}); err != nil {
					log.Println("error figuring out name: ", err)
					http.Error(w, err.Error(), http.StatusInternalServerError)
					return
				}

				d, err := ioutil.ReadAll(r.Body)
				if err != nil {
					log.Println("error reading body: ", err)
					w.WriteHeader(http.StatusBadRequest)
					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)
				}
			}),
		),
	)

	if err := http.ListenAndServe(":7777",
		othttp.NewHandler(&mux, "server",
			othttp.WithMessageEvents(othttp.ReadEvents, othttp.WriteEvents),
		),
	); err != nil {
		log.Fatal(err)
	}
}
Output:

func WithRouteTag

func WithRouteTag(route string, h http.Handler) http.Handler

WithRouteTag annotates a span with the provided route name using the RouteKey Tag.

Types

type Config

type Config struct {
	Tracer            trace.Tracer
	Meter             metric.Meter
	Propagators       propagation.Propagators
	SpanStartOptions  []trace.StartOption
	ReadEvent         bool
	WriteEvent        bool
	Filters           []Filter
	SpanNameFormatter func(string, *http.Request) string
}

Config represents the configuration options available for the othttp.Handler and othttp.Transport types.

func NewConfig

func NewConfig(opts ...Option) *Config

NewConfig creates a new Config struct and applies opts to it.

type Filter

type Filter func(*http.Request) bool

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 kv.Keys defined in this package.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serves HTTP requests (http.Handler)

type Option

type Option interface {
	Apply(*Config)
}

Option Interface used for setting *optional* Config properties

func WithFilter

func WithFilter(f Filter) Option

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 WithMeter

func WithMeter(meter metric.Meter) Option

WithMeter configures a specific meter. If this option isn't specified then the global meter is used.

func WithPropagators

func WithPropagators(ps propagation.Propagators) Option

WithPropagators configures specific propagators. If this option isn't specified then go.opentelemetry.io/otel/api/global.Propagators are 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

func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option

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.StartOption) Option

WithSpanOptions configures an additional set of trace.StartOptions, which are applied to each new span.

func WithTracer

func WithTracer(tracer trace.Tracer) Option

WithTracer configures a specific tracer. If this option isn't specified then the global tracer is used.

type OptionFunc

type OptionFunc func(*Config)

OptionFunc provides a convenience wrapper for simple Options that can be represented as functions.

func (OptionFunc) Apply

func (o OptionFunc) Apply(c *Config)

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.

Example
// Create an http.Client that uses the othttp.Transport
// wrapped around the http.DefaultTransport
_ = http.Client{
	Transport: NewTransport(http.DefaultTransport),
}
Output:

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip creates a Span and propagates its context via the provided request's headers before handing the request to the configured base RoundTripper. The created span will end when the response body is closed or when a read from the body returns io.EOF.

Directories

Path Synopsis
Package filters provides a set of filters useful with the othttp.WithFilter() option to control which inbound requests are traced.
Package filters provides a set of filters useful with the othttp.WithFilter() option to control which inbound requests are traced.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL