otelhttp

package module
v0.57.0 Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2024 License: Apache-2.0 Imports: 18 Imported by: 1,652

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

Examples

Constants

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

View Source
const (
	ReadEvents event = iota
	WriteEvents
)

Different types of events that can be recorded, see WithMessageEvents.

View Source
const ScopeName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

ScopeName is the instrumentation scope name.

Variables

View Source
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 initialization order - for example, if you change the global propagator, the DefaultClient might still be using the old one.

Functions

func ContextWithLabeler added in v0.53.0

func ContextWithLabeler(parent context.Context, l *Labeler) context.Context

ContextWithLabeler returns a new context with the provided Labeler instance. Attributes added to the specified labeler will be injected into metrics emitted by the instrumentation. Only one labeller can be injected into the context. Injecting it multiple times will override the previous calls.

func ContextWithStartTime added in v0.57.0

func ContextWithStartTime(parent context.Context, start time.Time) context.Context

ContextWithStartTime returns a new context with the provided start time. The start time will be used for metrics and traces emitted by the instrumentation. Only one labeller can be injected into the context. Injecting it multiple times will override the previous calls.

func Get added in v0.14.0

func Get(ctx context.Context, targetURL string) (resp *http.Response, err error)

Get is a convenient replacement for http.Get that adds a span around the request.

func Head(ctx context.Context, targetURL string) (resp *http.Response, err error)

Head is a convenient replacement for http.Head that adds a span around the request.

func NewHandler

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

NewHandler wraps the passed handler in a span named after the operation and enriches it with metrics.

Example
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"

	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"

	"go.opentelemetry.io/contrib/instrumentation/net/http/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 := io.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))
				}
			}),
		),
	)

	if err := http.ListenAndServe(":7777", //nolint:gosec // Ignoring G114: Use of net/http serve function that has no support for setting timeouts.
		otelhttp.NewHandler(&mux, "server",
			otelhttp.WithMessageEvents(otelhttp.ReadEvents, otelhttp.WriteEvents),
		),
	); err != nil {
		log.Fatal(err)
	}
}
Output:

func NewMiddleware added in v0.43.0

func NewMiddleware(operation string, opts ...Option) func(http.Handler) http.Handler

NewMiddleware returns a tracing and metrics instrumentation middleware. The handler returned by the middleware wraps a handler in a span named after the operation and enriches it with metrics.

func Post added in v0.14.0

func Post(ctx context.Context, targetURL, 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 added in v0.14.0

func PostForm(ctx context.Context, targetURL string, data url.Values) (resp *http.Response, err error)

PostForm is a convenient replacement for http.PostForm that adds a span around the request.

func SemVersion deprecated added in v0.24.0

func SemVersion() string

SemVersion is the semantic version to be supplied to tracer/meter creation.

Deprecated: Use Version instead.

func StartTimeFromContext added in v0.57.0

func StartTimeFromContext(ctx context.Context) time.Time

StartTimeFromContext retrieves a time.Time from the provided context if one is available. If no start time was found in the provided context, a new, zero start time is returned and the second return value is false.

func Version added in v0.24.0

func Version() string

Version is the current release version of the otelhttp instrumentation.

func WithRouteTag

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

WithRouteTag annotates spans and metrics with the provided route name with HTTP route attribute.

Types

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

func LabelerFromContext(ctx context.Context) (*Labeler, bool)

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.

func (*Labeler) Add

func (l *Labeler) Add(ls ...attribute.KeyValue)

Add attributes to a Labeler.

func (*Labeler) Get

func (l *Labeler) Get() []attribute.KeyValue

Get returns a copy of the attributes added to the Labeler.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option interface used for setting optional config properties.

func WithClientTrace added in v0.29.0

func WithClientTrace(f func(context.Context) *httptrace.ClientTrace) Option

WithClientTrace takes a function that returns client trace instance that will be applied to the requests sent through the otelhttp Transport.

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 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 WithMetricAttributesFn added in v0.54.0

func WithMetricAttributesFn(metricAttributesFn func(r *http.Request) []attribute.KeyValue) Option

WithMetricAttributesFn returns an Option to set a function that maps an HTTP request to a slice of attribute.KeyValue. These attributes will be included in metrics for every request.

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 WithPublicEndpointFn added in v0.33.0

func WithPublicEndpointFn(fn func(*http.Request) bool) Option

WithPublicEndpointFn runs with every request, and allows conditionally configuring the Handler to link the span with an incoming span context. If this option is not provided or returns false, then the association is a child association instead of a link. Note: WithPublicEndpoint takes precedence over WithPublicEndpointFn.

func WithServerName added in v0.38.0

func WithServerName(server string) Option

WithServerName returns an Option that sets the name of the (virtual) server handling requests.

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.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 and enriches it with metrics.

func NewTransport

func NewTransport(base http.RoundTripper, opts ...Option) *Transport

NewTransport wraps the provided http.RoundTripper with one that starts a span, injects the span context into the outbound request headers, and enriches it with metrics.

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:

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
example module
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.
internal
test module

Jump to

Keyboard shortcuts

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