123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- package opentracing
- import (
- "errors"
- "net/http"
- )
- ///////////////////////////////////////////////////////////////////////////////
- // CORE PROPAGATION INTERFACES:
- ///////////////////////////////////////////////////////////////////////////////
- var (
- // ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or
- // Tracer.Extract() is not recognized by the Tracer implementation.
- ErrUnsupportedFormat = errors.New("opentracing: Unknown or unsupported Inject/Extract format")
- // ErrSpanContextNotFound occurs when the `carrier` passed to
- // Tracer.Extract() is valid and uncorrupted but has insufficient
- // information to extract a SpanContext.
- ErrSpanContextNotFound = errors.New("opentracing: SpanContext not found in Extract carrier")
- // ErrInvalidSpanContext errors occur when Tracer.Inject() is asked to
- // operate on a SpanContext which it is not prepared to handle (for
- // example, since it was created by a different tracer implementation).
- ErrInvalidSpanContext = errors.New("opentracing: SpanContext type incompatible with tracer")
- // ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Extract()
- // implementations expect a different type of `carrier` than they are
- // given.
- ErrInvalidCarrier = errors.New("opentracing: Invalid Inject/Extract carrier")
- // ErrSpanContextCorrupted occurs when the `carrier` passed to
- // Tracer.Extract() is of the expected type but is corrupted.
- ErrSpanContextCorrupted = errors.New("opentracing: SpanContext data corrupted in Extract carrier")
- )
- ///////////////////////////////////////////////////////////////////////////////
- // BUILTIN PROPAGATION FORMATS:
- ///////////////////////////////////////////////////////////////////////////////
- // BuiltinFormat is used to demarcate the values within package `opentracing`
- // that are intended for use with the Tracer.Inject() and Tracer.Extract()
- // methods.
- type BuiltinFormat byte
- const (
- // Binary represents SpanContexts as opaque binary data.
- //
- // For Tracer.Inject(): the carrier must be an `io.Writer`.
- //
- // For Tracer.Extract(): the carrier must be an `io.Reader`.
- Binary BuiltinFormat = iota
- // TextMap represents SpanContexts as key:value string pairs.
- //
- // Unlike HTTPHeaders, the TextMap format does not restrict the key or
- // value character sets in any way.
- //
- // For Tracer.Inject(): the carrier must be a `TextMapWriter`.
- //
- // For Tracer.Extract(): the carrier must be a `TextMapReader`.
- TextMap
- // HTTPHeaders represents SpanContexts as HTTP header string pairs.
- //
- // Unlike TextMap, the HTTPHeaders format requires that the keys and values
- // be valid as HTTP headers as-is (i.e., character casing may be unstable
- // and special characters are disallowed in keys, values should be
- // URL-escaped, etc).
- //
- // For Tracer.Inject(): the carrier must be a `TextMapWriter`.
- //
- // For Tracer.Extract(): the carrier must be a `TextMapReader`.
- //
- // See HTTPHeadersCarrier for an implementation of both TextMapWriter
- // and TextMapReader that defers to an http.Header instance for storage.
- // For example, Inject():
- //
- // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
- // err := span.Tracer().Inject(
- // span.Context(), opentracing.HTTPHeaders, carrier)
- //
- // Or Extract():
- //
- // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
- // clientContext, err := tracer.Extract(
- // opentracing.HTTPHeaders, carrier)
- //
- HTTPHeaders
- )
- // TextMapWriter is the Inject() carrier for the TextMap builtin format. With
- // it, the caller can encode a SpanContext for propagation as entries in a map
- // of unicode strings.
- type TextMapWriter interface {
- // Set a key:value pair to the carrier. Multiple calls to Set() for the
- // same key leads to undefined behavior.
- //
- // NOTE: The backing store for the TextMapWriter may contain data unrelated
- // to SpanContext. As such, Inject() and Extract() implementations that
- // call the TextMapWriter and TextMapReader interfaces must agree on a
- // prefix or other convention to distinguish their own key:value pairs.
- Set(key, val string)
- }
- // TextMapReader is the Extract() carrier for the TextMap builtin format. With it,
- // the caller can decode a propagated SpanContext as entries in a map of
- // unicode strings.
- type TextMapReader interface {
- // ForeachKey returns TextMap contents via repeated calls to the `handler`
- // function. If any call to `handler` returns a non-nil error, ForeachKey
- // terminates and returns that error.
- //
- // NOTE: The backing store for the TextMapReader may contain data unrelated
- // to SpanContext. As such, Inject() and Extract() implementations that
- // call the TextMapWriter and TextMapReader interfaces must agree on a
- // prefix or other convention to distinguish their own key:value pairs.
- //
- // The "foreach" callback pattern reduces unnecessary copying in some cases
- // and also allows implementations to hold locks while the map is read.
- ForeachKey(handler func(key, val string) error) error
- }
- // TextMapCarrier allows the use of regular map[string]string
- // as both TextMapWriter and TextMapReader.
- type TextMapCarrier map[string]string
- // ForeachKey conforms to the TextMapReader interface.
- func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error {
- for k, v := range c {
- if err := handler(k, v); err != nil {
- return err
- }
- }
- return nil
- }
- // Set implements Set() of opentracing.TextMapWriter
- func (c TextMapCarrier) Set(key, val string) {
- c[key] = val
- }
- // HTTPHeadersCarrier satisfies both TextMapWriter and TextMapReader.
- //
- // Example usage for server side:
- //
- // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
- // clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
- //
- // Example usage for client side:
- //
- // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
- // err := tracer.Inject(
- // span.Context(),
- // opentracing.HTTPHeaders,
- // carrier)
- //
- type HTTPHeadersCarrier http.Header
- // Set conforms to the TextMapWriter interface.
- func (c HTTPHeadersCarrier) Set(key, val string) {
- h := http.Header(c)
- h.Set(key, val)
- }
- // ForeachKey conforms to the TextMapReader interface.
- func (c HTTPHeadersCarrier) ForeachKey(handler func(key, val string) error) error {
- for k, vals := range c {
- for _, v := range vals {
- if err := handler(k, v); err != nil {
- return err
- }
- }
- }
- return nil
- }
|