Bump sigs.k8s.io/controller-runtime to v0.14.4 (#5507)
* Bump sigs.k8s.io/controller-runtime to v0.14.4 * Update gofmt
This commit is contained in:
331
vendor/go.opentelemetry.io/otel/trace/config.go
generated
vendored
331
vendor/go.opentelemetry.io/otel/trace/config.go
generated
vendored
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package trace
|
||||
package trace // import "go.opentelemetry.io/otel/trace"
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -22,110 +22,199 @@ import (
|
||||
|
||||
// TracerConfig is a group of options for a Tracer.
|
||||
type TracerConfig struct {
|
||||
// InstrumentationVersion is the version of the library providing
|
||||
// instrumentation.
|
||||
InstrumentationVersion string
|
||||
instrumentationVersion string
|
||||
// Schema URL of the telemetry emitted by the Tracer.
|
||||
schemaURL string
|
||||
}
|
||||
|
||||
// InstrumentationVersion returns the version of the library providing instrumentation.
|
||||
func (t *TracerConfig) InstrumentationVersion() string {
|
||||
return t.instrumentationVersion
|
||||
}
|
||||
|
||||
// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.
|
||||
func (t *TracerConfig) SchemaURL() string {
|
||||
return t.schemaURL
|
||||
}
|
||||
|
||||
// NewTracerConfig applies all the options to a returned TracerConfig.
|
||||
func NewTracerConfig(options ...TracerOption) *TracerConfig {
|
||||
config := new(TracerConfig)
|
||||
func NewTracerConfig(options ...TracerOption) TracerConfig {
|
||||
var config TracerConfig
|
||||
for _, option := range options {
|
||||
option.ApplyTracer(config)
|
||||
config = option.apply(config)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// TracerOption applies an option to a TracerConfig.
|
||||
type TracerOption interface {
|
||||
ApplyTracer(*TracerConfig)
|
||||
apply(TracerConfig) TracerConfig
|
||||
}
|
||||
|
||||
// A private method to prevent users implementing the
|
||||
// interface and so future additions to it will not
|
||||
// violate compatibility.
|
||||
private()
|
||||
type tracerOptionFunc func(TracerConfig) TracerConfig
|
||||
|
||||
func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig {
|
||||
return fn(cfg)
|
||||
}
|
||||
|
||||
// SpanConfig is a group of options for a Span.
|
||||
type SpanConfig struct {
|
||||
// Attributes describe the associated qualities of a Span.
|
||||
Attributes []attribute.KeyValue
|
||||
// Timestamp is a time in a Span life-cycle.
|
||||
Timestamp time.Time
|
||||
// Links are the associations a Span has with other Spans.
|
||||
Links []Link
|
||||
// NewRoot identifies a Span as the root Span for a new trace. This is
|
||||
// commonly used when an existing trace crosses trust boundaries and the
|
||||
// remote parent span context should be ignored for security.
|
||||
NewRoot bool
|
||||
// SpanKind is the role a Span has in a trace.
|
||||
SpanKind SpanKind
|
||||
attributes []attribute.KeyValue
|
||||
timestamp time.Time
|
||||
links []Link
|
||||
newRoot bool
|
||||
spanKind SpanKind
|
||||
stackTrace bool
|
||||
}
|
||||
|
||||
// NewSpanConfig applies all the options to a returned SpanConfig.
|
||||
// Attributes describe the associated qualities of a Span.
|
||||
func (cfg *SpanConfig) Attributes() []attribute.KeyValue {
|
||||
return cfg.attributes
|
||||
}
|
||||
|
||||
// Timestamp is a time in a Span life-cycle.
|
||||
func (cfg *SpanConfig) Timestamp() time.Time {
|
||||
return cfg.timestamp
|
||||
}
|
||||
|
||||
// StackTrace checks whether stack trace capturing is enabled.
|
||||
func (cfg *SpanConfig) StackTrace() bool {
|
||||
return cfg.stackTrace
|
||||
}
|
||||
|
||||
// Links are the associations a Span has with other Spans.
|
||||
func (cfg *SpanConfig) Links() []Link {
|
||||
return cfg.links
|
||||
}
|
||||
|
||||
// NewRoot identifies a Span as the root Span for a new trace. This is
|
||||
// commonly used when an existing trace crosses trust boundaries and the
|
||||
// remote parent span context should be ignored for security.
|
||||
func (cfg *SpanConfig) NewRoot() bool {
|
||||
return cfg.newRoot
|
||||
}
|
||||
|
||||
// SpanKind is the role a Span has in a trace.
|
||||
func (cfg *SpanConfig) SpanKind() SpanKind {
|
||||
return cfg.spanKind
|
||||
}
|
||||
|
||||
// NewSpanStartConfig applies all the options to a returned SpanConfig.
|
||||
// No validation is performed on the returned SpanConfig (e.g. no uniqueness
|
||||
// checking or bounding of data), it is left to the SDK to perform this
|
||||
// action.
|
||||
func NewSpanConfig(options ...SpanOption) *SpanConfig {
|
||||
c := new(SpanConfig)
|
||||
func NewSpanStartConfig(options ...SpanStartOption) SpanConfig {
|
||||
var c SpanConfig
|
||||
for _, option := range options {
|
||||
option.ApplySpan(c)
|
||||
c = option.applySpanStart(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// SpanOption applies an option to a SpanConfig.
|
||||
type SpanOption interface {
|
||||
ApplySpan(*SpanConfig)
|
||||
|
||||
// A private method to prevent users implementing the
|
||||
// interface and so future additions to it will not
|
||||
// violate compatibility.
|
||||
private()
|
||||
// NewSpanEndConfig applies all the options to a returned SpanConfig.
|
||||
// No validation is performed on the returned SpanConfig (e.g. no uniqueness
|
||||
// checking or bounding of data), it is left to the SDK to perform this
|
||||
// action.
|
||||
func NewSpanEndConfig(options ...SpanEndOption) SpanConfig {
|
||||
var c SpanConfig
|
||||
for _, option := range options {
|
||||
c = option.applySpanEnd(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// NewEventConfig applies all the EventOptions to a returned SpanConfig. If no
|
||||
// timestamp option is passed, the returned SpanConfig will have a Timestamp
|
||||
// SpanStartOption applies an option to a SpanConfig. These options are applicable
|
||||
// only when the span is created.
|
||||
type SpanStartOption interface {
|
||||
applySpanStart(SpanConfig) SpanConfig
|
||||
}
|
||||
|
||||
type spanOptionFunc func(SpanConfig) SpanConfig
|
||||
|
||||
func (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig {
|
||||
return fn(cfg)
|
||||
}
|
||||
|
||||
// SpanEndOption applies an option to a SpanConfig. These options are
|
||||
// applicable only when the span is ended.
|
||||
type SpanEndOption interface {
|
||||
applySpanEnd(SpanConfig) SpanConfig
|
||||
}
|
||||
|
||||
// EventConfig is a group of options for an Event.
|
||||
type EventConfig struct {
|
||||
attributes []attribute.KeyValue
|
||||
timestamp time.Time
|
||||
stackTrace bool
|
||||
}
|
||||
|
||||
// Attributes describe the associated qualities of an Event.
|
||||
func (cfg *EventConfig) Attributes() []attribute.KeyValue {
|
||||
return cfg.attributes
|
||||
}
|
||||
|
||||
// Timestamp is a time in an Event life-cycle.
|
||||
func (cfg *EventConfig) Timestamp() time.Time {
|
||||
return cfg.timestamp
|
||||
}
|
||||
|
||||
// StackTrace checks whether stack trace capturing is enabled.
|
||||
func (cfg *EventConfig) StackTrace() bool {
|
||||
return cfg.stackTrace
|
||||
}
|
||||
|
||||
// NewEventConfig applies all the EventOptions to a returned EventConfig. If no
|
||||
// timestamp option is passed, the returned EventConfig will have a Timestamp
|
||||
// set to the call time, otherwise no validation is performed on the returned
|
||||
// SpanConfig.
|
||||
func NewEventConfig(options ...EventOption) *SpanConfig {
|
||||
c := new(SpanConfig)
|
||||
// EventConfig.
|
||||
func NewEventConfig(options ...EventOption) EventConfig {
|
||||
var c EventConfig
|
||||
for _, option := range options {
|
||||
option.ApplyEvent(c)
|
||||
c = option.applyEvent(c)
|
||||
}
|
||||
if c.Timestamp.IsZero() {
|
||||
c.Timestamp = time.Now()
|
||||
if c.timestamp.IsZero() {
|
||||
c.timestamp = time.Now()
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// EventOption applies span event options to a SpanConfig.
|
||||
// EventOption applies span event options to an EventConfig.
|
||||
type EventOption interface {
|
||||
ApplyEvent(*SpanConfig)
|
||||
|
||||
// A private method to prevent users implementing the
|
||||
// interface and so future additions to it will not
|
||||
// violate compatibility.
|
||||
private()
|
||||
applyEvent(EventConfig) EventConfig
|
||||
}
|
||||
|
||||
// LifeCycleOption applies span life-cycle options to a SpanConfig. These
|
||||
// options set values releated to events in a spans life-cycle like starting,
|
||||
// ending, experiencing an error and other user defined notable events.
|
||||
type LifeCycleOption interface {
|
||||
SpanOption
|
||||
// SpanOption are options that can be used at both the beginning and end of a span.
|
||||
type SpanOption interface {
|
||||
SpanStartOption
|
||||
SpanEndOption
|
||||
}
|
||||
|
||||
// SpanStartEventOption are options that can be used at the start of a span, or with an event.
|
||||
type SpanStartEventOption interface {
|
||||
SpanStartOption
|
||||
EventOption
|
||||
}
|
||||
|
||||
type attributeSpanOption []attribute.KeyValue
|
||||
|
||||
func (o attributeSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) }
|
||||
func (o attributeSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) }
|
||||
func (attributeSpanOption) private() {}
|
||||
func (o attributeSpanOption) apply(c *SpanConfig) {
|
||||
c.Attributes = append(c.Attributes, []attribute.KeyValue(o)...)
|
||||
// SpanEndEventOption are options that can be used at the end of a span, or with an event.
|
||||
type SpanEndEventOption interface {
|
||||
SpanEndOption
|
||||
EventOption
|
||||
}
|
||||
|
||||
type attributeOption []attribute.KeyValue
|
||||
|
||||
func (o attributeOption) applySpan(c SpanConfig) SpanConfig {
|
||||
c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
|
||||
return c
|
||||
}
|
||||
func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
func (o attributeOption) applyEvent(c EventConfig) EventConfig {
|
||||
c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
|
||||
return c
|
||||
}
|
||||
|
||||
var _ SpanStartEventOption = attributeOption{}
|
||||
|
||||
// WithAttributes adds the attributes related to a span life-cycle event.
|
||||
// These attributes are used to describe the work a Span represents when this
|
||||
// option is provided to a Span's start or end events. Otherwise, these
|
||||
@@ -135,71 +224,93 @@ func (o attributeSpanOption) apply(c *SpanConfig) {
|
||||
// If multiple of these options are passed the attributes of each successive
|
||||
// option will extend the attributes instead of overwriting. There is no
|
||||
// guarantee of uniqueness in the resulting attributes.
|
||||
func WithAttributes(attributes ...attribute.KeyValue) LifeCycleOption {
|
||||
return attributeSpanOption(attributes)
|
||||
func WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption {
|
||||
return attributeOption(attributes)
|
||||
}
|
||||
|
||||
type timestampSpanOption time.Time
|
||||
|
||||
func (o timestampSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) }
|
||||
func (o timestampSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) }
|
||||
func (timestampSpanOption) private() {}
|
||||
func (o timestampSpanOption) apply(c *SpanConfig) { c.Timestamp = time.Time(o) }
|
||||
|
||||
// WithTimestamp sets the time of a Span life-cycle moment (e.g. started,
|
||||
// stopped, errored).
|
||||
func WithTimestamp(t time.Time) LifeCycleOption {
|
||||
return timestampSpanOption(t)
|
||||
// SpanEventOption are options that can be used with an event or a span.
|
||||
type SpanEventOption interface {
|
||||
SpanOption
|
||||
EventOption
|
||||
}
|
||||
|
||||
type linksSpanOption []Link
|
||||
type timestampOption time.Time
|
||||
|
||||
func (o linksSpanOption) ApplySpan(c *SpanConfig) { c.Links = append(c.Links, []Link(o)...) }
|
||||
func (linksSpanOption) private() {}
|
||||
func (o timestampOption) applySpan(c SpanConfig) SpanConfig {
|
||||
c.timestamp = time.Time(o)
|
||||
return c
|
||||
}
|
||||
func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
func (o timestampOption) applyEvent(c EventConfig) EventConfig {
|
||||
c.timestamp = time.Time(o)
|
||||
return c
|
||||
}
|
||||
|
||||
var _ SpanEventOption = timestampOption{}
|
||||
|
||||
// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g.
|
||||
// started, stopped, errored).
|
||||
func WithTimestamp(t time.Time) SpanEventOption {
|
||||
return timestampOption(t)
|
||||
}
|
||||
|
||||
type stackTraceOption bool
|
||||
|
||||
func (o stackTraceOption) applyEvent(c EventConfig) EventConfig {
|
||||
c.stackTrace = bool(o)
|
||||
return c
|
||||
}
|
||||
func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
|
||||
c.stackTrace = bool(o)
|
||||
return c
|
||||
}
|
||||
func (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
|
||||
// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false).
|
||||
func WithStackTrace(b bool) SpanEndEventOption {
|
||||
return stackTraceOption(b)
|
||||
}
|
||||
|
||||
// WithLinks adds links to a Span. The links are added to the existing Span
|
||||
// links, i.e. this does not overwrite.
|
||||
func WithLinks(links ...Link) SpanOption {
|
||||
return linksSpanOption(links)
|
||||
// links, i.e. this does not overwrite. Links with invalid span context are ignored.
|
||||
func WithLinks(links ...Link) SpanStartOption {
|
||||
return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
|
||||
cfg.links = append(cfg.links, links...)
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
type newRootSpanOption bool
|
||||
|
||||
func (o newRootSpanOption) ApplySpan(c *SpanConfig) { c.NewRoot = bool(o) }
|
||||
func (newRootSpanOption) private() {}
|
||||
|
||||
// WithNewRoot specifies that the Span should be treated as a root Span. Any
|
||||
// existing parent span context will be ignored when defining the Span's trace
|
||||
// identifiers.
|
||||
func WithNewRoot() SpanOption {
|
||||
return newRootSpanOption(true)
|
||||
func WithNewRoot() SpanStartOption {
|
||||
return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
|
||||
cfg.newRoot = true
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
type spanKindSpanOption SpanKind
|
||||
|
||||
func (o spanKindSpanOption) ApplySpan(c *SpanConfig) { c.SpanKind = SpanKind(o) }
|
||||
func (o spanKindSpanOption) private() {}
|
||||
|
||||
// WithSpanKind sets the SpanKind of a Span.
|
||||
func WithSpanKind(kind SpanKind) SpanOption {
|
||||
return spanKindSpanOption(kind)
|
||||
}
|
||||
|
||||
// InstrumentationOption is an interface for applying instrumentation specific
|
||||
// options.
|
||||
type InstrumentationOption interface {
|
||||
TracerOption
|
||||
func WithSpanKind(kind SpanKind) SpanStartOption {
|
||||
return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
|
||||
cfg.spanKind = kind
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithInstrumentationVersion sets the instrumentation version.
|
||||
func WithInstrumentationVersion(version string) InstrumentationOption {
|
||||
return instrumentationVersionOption(version)
|
||||
func WithInstrumentationVersion(version string) TracerOption {
|
||||
return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
|
||||
cfg.instrumentationVersion = version
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
type instrumentationVersionOption string
|
||||
|
||||
func (i instrumentationVersionOption) ApplyTracer(config *TracerConfig) {
|
||||
config.InstrumentationVersion = string(i)
|
||||
// WithSchemaURL sets the schema URL for the Tracer.
|
||||
func WithSchemaURL(schemaURL string) TracerOption {
|
||||
return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
|
||||
cfg.schemaURL = schemaURL
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
func (instrumentationVersionOption) private() {}
|
||||
|
||||
4
vendor/go.opentelemetry.io/otel/trace/doc.go
generated
vendored
4
vendor/go.opentelemetry.io/otel/trace/doc.go
generated
vendored
@@ -16,10 +16,6 @@
|
||||
Package trace provides an implementation of the tracing part of the
|
||||
OpenTelemetry API.
|
||||
|
||||
This package is currently in a pre-GA phase. Backwards incompatible changes
|
||||
may be introduced in subsequent minor version releases as we work to track the
|
||||
evolving OpenTelemetry specification and user feedback.
|
||||
|
||||
To participate in distributed traces a Span needs to be created for the
|
||||
operation being performed as part of a traced workflow. It its simplest form:
|
||||
|
||||
|
||||
19
vendor/go.opentelemetry.io/otel/trace/noop.go
generated
vendored
19
vendor/go.opentelemetry.io/otel/trace/noop.go
generated
vendored
@@ -42,9 +42,14 @@ type noopTracer struct{}
|
||||
|
||||
var _ Tracer = noopTracer{}
|
||||
|
||||
// Start starts a noop span.
|
||||
func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanOption) (context.Context, Span) {
|
||||
span := noopSpan{}
|
||||
// Start carries forward a non-recording Span, if one is present in the context, otherwise it
|
||||
// creates a no-op Span.
|
||||
func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption) (context.Context, Span) {
|
||||
span := SpanFromContext(ctx)
|
||||
if _, ok := span.(nonRecordingSpan); !ok {
|
||||
// span is likely already a noopSpan, but let's be sure
|
||||
span = noopSpan{}
|
||||
}
|
||||
return ContextWithSpan(ctx, span), span
|
||||
}
|
||||
|
||||
@@ -69,16 +74,16 @@ func (noopSpan) SetError(bool) {}
|
||||
func (noopSpan) SetAttributes(...attribute.KeyValue) {}
|
||||
|
||||
// End does nothing.
|
||||
func (noopSpan) End(...SpanOption) {}
|
||||
func (noopSpan) End(...SpanEndOption) {}
|
||||
|
||||
// RecordError does nothing.
|
||||
func (noopSpan) RecordError(error, ...EventOption) {}
|
||||
|
||||
// Tracer returns the Tracer that created this Span.
|
||||
func (noopSpan) Tracer() Tracer { return noopTracer{} }
|
||||
|
||||
// AddEvent does nothing.
|
||||
func (noopSpan) AddEvent(string, ...EventOption) {}
|
||||
|
||||
// SetName does nothing.
|
||||
func (noopSpan) SetName(string) {}
|
||||
|
||||
// TracerProvider returns a no-op TracerProvider.
|
||||
func (noopSpan) TracerProvider() TracerProvider { return noopTracerProvider{} }
|
||||
|
||||
323
vendor/go.opentelemetry.io/otel/trace/trace.go
generated
vendored
323
vendor/go.opentelemetry.io/otel/trace/trace.go
generated
vendored
@@ -19,9 +19,6 @@ import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
@@ -39,18 +36,6 @@ const (
|
||||
|
||||
errInvalidSpanIDLength errorConst = "hex encoded span-id must have length equals to 16"
|
||||
errNilSpanID errorConst = "span-id can't be all zero"
|
||||
|
||||
// based on the W3C Trace Context specification, see https://www.w3.org/TR/trace-context-1/#tracestate-header
|
||||
traceStateKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}`
|
||||
traceStateKeyFormatWithMultiTenantVendor = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
|
||||
traceStateValueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
|
||||
|
||||
traceStateMaxListMembers = 32
|
||||
|
||||
errInvalidTraceStateKeyValue errorConst = "provided key or value is not valid according to the" +
|
||||
" W3C Trace Context specification"
|
||||
errInvalidTraceStateMembersNumber errorConst = "trace state would exceed the maximum limit of members (32)"
|
||||
errInvalidTraceStateDuplicate errorConst = "trace state key/value pairs with duplicate keys provided"
|
||||
)
|
||||
|
||||
type errorConst string
|
||||
@@ -60,7 +45,7 @@ func (e errorConst) Error() string {
|
||||
}
|
||||
|
||||
// TraceID is a unique identity of a trace.
|
||||
// nolint:golint
|
||||
// nolint:revive // revive complains about stutter of `trace.TraceID`.
|
||||
type TraceID [16]byte
|
||||
|
||||
var nilTraceID TraceID
|
||||
@@ -78,7 +63,7 @@ func (t TraceID) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
// String returns the hex string representation form of a TraceID
|
||||
// String returns the hex string representation form of a TraceID.
|
||||
func (t TraceID) String() string {
|
||||
return hex.EncodeToString(t[:])
|
||||
}
|
||||
@@ -101,7 +86,7 @@ func (s SpanID) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(s.String())
|
||||
}
|
||||
|
||||
// String returns the hex string representation form of a SpanID
|
||||
// String returns the hex string representation form of a SpanID.
|
||||
func (s SpanID) String() string {
|
||||
return hex.EncodeToString(s[:])
|
||||
}
|
||||
@@ -109,7 +94,7 @@ func (s SpanID) String() string {
|
||||
// TraceIDFromHex returns a TraceID from a hex string if it is compliant with
|
||||
// the W3C trace-context specification. See more at
|
||||
// https://www.w3.org/TR/trace-context/#trace-id
|
||||
// nolint:golint
|
||||
// nolint:revive // revive complains about stutter of `trace.TraceIDFromHex`.
|
||||
func TraceIDFromHex(h string) (TraceID, error) {
|
||||
t := TraceID{}
|
||||
if len(h) != 32 {
|
||||
@@ -166,155 +151,8 @@ func decodeHex(h string, b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TraceState provides additional vendor-specific trace identification information
|
||||
// across different distributed tracing systems. It represents an immutable list consisting
|
||||
// of key/value pairs. There can be a maximum of 32 entries in the list.
|
||||
//
|
||||
// Key and value of each list member must be valid according to the W3C Trace Context specification
|
||||
// (see https://www.w3.org/TR/trace-context-1/#key and https://www.w3.org/TR/trace-context-1/#value
|
||||
// respectively).
|
||||
//
|
||||
// Trace state must be valid according to the W3C Trace Context specification at all times. All
|
||||
// mutating operations validate their input and, in case of valid parameters, return a new TraceState.
|
||||
type TraceState struct { //nolint:golint
|
||||
// TODO @matej-g: Consider implementing this as attribute.Set, see
|
||||
// comment https://github.com/open-telemetry/opentelemetry-go/pull/1340#discussion_r540599226
|
||||
kvs []attribute.KeyValue
|
||||
}
|
||||
|
||||
var _ json.Marshaler = TraceState{}
|
||||
var _ json.Marshaler = SpanContext{}
|
||||
|
||||
var keyFormatRegExp = regexp.MustCompile(
|
||||
`^((` + traceStateKeyFormat + `)|(` + traceStateKeyFormatWithMultiTenantVendor + `))$`,
|
||||
)
|
||||
var valueFormatRegExp = regexp.MustCompile(`^(` + traceStateValueFormat + `)$`)
|
||||
|
||||
// MarshalJSON implements a custom marshal function to encode trace state.
|
||||
func (ts TraceState) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(ts.kvs)
|
||||
}
|
||||
|
||||
// String returns trace state as a string valid according to the
|
||||
// W3C Trace Context specification.
|
||||
func (ts TraceState) String() string {
|
||||
var sb strings.Builder
|
||||
|
||||
for i, kv := range ts.kvs {
|
||||
sb.WriteString((string)(kv.Key))
|
||||
sb.WriteByte('=')
|
||||
sb.WriteString(kv.Value.Emit())
|
||||
|
||||
if i != len(ts.kvs)-1 {
|
||||
sb.WriteByte(',')
|
||||
}
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// Get returns a value for given key from the trace state.
|
||||
// If no key is found or provided key is invalid, returns an empty value.
|
||||
func (ts TraceState) Get(key attribute.Key) attribute.Value {
|
||||
if !isTraceStateKeyValid(key) {
|
||||
return attribute.Value{}
|
||||
}
|
||||
|
||||
for _, kv := range ts.kvs {
|
||||
if kv.Key == key {
|
||||
return kv.Value
|
||||
}
|
||||
}
|
||||
|
||||
return attribute.Value{}
|
||||
}
|
||||
|
||||
// Insert adds a new key/value, if one doesn't exists; otherwise updates the existing entry.
|
||||
// The new or updated entry is always inserted at the beginning of the TraceState, i.e.
|
||||
// on the left side, as per the W3C Trace Context specification requirement.
|
||||
func (ts TraceState) Insert(entry attribute.KeyValue) (TraceState, error) {
|
||||
if !isTraceStateKeyValueValid(entry) {
|
||||
return ts, errInvalidTraceStateKeyValue
|
||||
}
|
||||
|
||||
ckvs := ts.copyKVsAndDeleteEntry(entry.Key)
|
||||
if len(ckvs)+1 > traceStateMaxListMembers {
|
||||
return ts, errInvalidTraceStateMembersNumber
|
||||
}
|
||||
|
||||
ckvs = append(ckvs, attribute.KeyValue{})
|
||||
copy(ckvs[1:], ckvs)
|
||||
ckvs[0] = entry
|
||||
|
||||
return TraceState{ckvs}, nil
|
||||
}
|
||||
|
||||
// Delete removes specified entry from the trace state.
|
||||
func (ts TraceState) Delete(key attribute.Key) (TraceState, error) {
|
||||
if !isTraceStateKeyValid(key) {
|
||||
return ts, errInvalidTraceStateKeyValue
|
||||
}
|
||||
|
||||
return TraceState{ts.copyKVsAndDeleteEntry(key)}, nil
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the TraceState does not contain any entries
|
||||
func (ts TraceState) IsEmpty() bool {
|
||||
return len(ts.kvs) == 0
|
||||
}
|
||||
|
||||
func (ts TraceState) copyKVsAndDeleteEntry(key attribute.Key) []attribute.KeyValue {
|
||||
ckvs := make([]attribute.KeyValue, len(ts.kvs))
|
||||
copy(ckvs, ts.kvs)
|
||||
for i, kv := range ts.kvs {
|
||||
if kv.Key == key {
|
||||
ckvs = append(ckvs[:i], ckvs[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return ckvs
|
||||
}
|
||||
|
||||
// TraceStateFromKeyValues is a convenience method to create a new TraceState from
|
||||
// provided key/value pairs.
|
||||
func TraceStateFromKeyValues(kvs ...attribute.KeyValue) (TraceState, error) { //nolint:golint
|
||||
if len(kvs) == 0 {
|
||||
return TraceState{}, nil
|
||||
}
|
||||
|
||||
if len(kvs) > traceStateMaxListMembers {
|
||||
return TraceState{}, errInvalidTraceStateMembersNumber
|
||||
}
|
||||
|
||||
km := make(map[attribute.Key]bool)
|
||||
for _, kv := range kvs {
|
||||
if !isTraceStateKeyValueValid(kv) {
|
||||
return TraceState{}, errInvalidTraceStateKeyValue
|
||||
}
|
||||
_, ok := km[kv.Key]
|
||||
if ok {
|
||||
return TraceState{}, errInvalidTraceStateDuplicate
|
||||
}
|
||||
km[kv.Key] = true
|
||||
}
|
||||
|
||||
ckvs := make([]attribute.KeyValue, len(kvs))
|
||||
copy(ckvs, kvs)
|
||||
return TraceState{ckvs}, nil
|
||||
}
|
||||
|
||||
func isTraceStateKeyValid(key attribute.Key) bool {
|
||||
return keyFormatRegExp.MatchString(string(key))
|
||||
}
|
||||
|
||||
func isTraceStateKeyValueValid(kv attribute.KeyValue) bool {
|
||||
return isTraceStateKeyValid(kv.Key) &&
|
||||
valueFormatRegExp.MatchString(kv.Value.Emit())
|
||||
}
|
||||
|
||||
// TraceFlags contains flags that can be set on a SpanContext
|
||||
type TraceFlags byte //nolint:golint
|
||||
// TraceFlags contains flags that can be set on a SpanContext.
|
||||
type TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`.
|
||||
|
||||
// IsSampled returns if the sampling bit is set in the TraceFlags.
|
||||
func (tf TraceFlags) IsSampled() bool {
|
||||
@@ -322,7 +160,7 @@ func (tf TraceFlags) IsSampled() bool {
|
||||
}
|
||||
|
||||
// WithSampled sets the sampling bit in a new copy of the TraceFlags.
|
||||
func (tf TraceFlags) WithSampled(sampled bool) TraceFlags {
|
||||
func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive // sampled is not a control flag.
|
||||
if sampled {
|
||||
return tf | FlagsSampled
|
||||
}
|
||||
@@ -336,7 +174,7 @@ func (tf TraceFlags) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(tf.String())
|
||||
}
|
||||
|
||||
// String returns the hex string representation form of TraceFlags
|
||||
// String returns the hex string representation form of TraceFlags.
|
||||
func (tf TraceFlags) String() string {
|
||||
return hex.EncodeToString([]byte{byte(tf)}[:])
|
||||
}
|
||||
@@ -372,6 +210,8 @@ type SpanContext struct {
|
||||
remote bool
|
||||
}
|
||||
|
||||
var _ json.Marshaler = SpanContext{}
|
||||
|
||||
// IsValid returns if the SpanContext is valid. A valid span context has a
|
||||
// valid TraceID and SpanID.
|
||||
func (sc SpanContext) IsValid() bool {
|
||||
@@ -497,16 +337,14 @@ func (sc SpanContext) MarshalJSON() ([]byte, error) {
|
||||
// and timed operation of a workflow that is traced. A Tracer is used to
|
||||
// create a Span and it is then up to the operation the Span represents to
|
||||
// properly end the Span when the operation itself ends.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Span interface {
|
||||
// Tracer returns the Tracer that created the Span. Tracer MUST NOT be
|
||||
// nil.
|
||||
Tracer() Tracer
|
||||
|
||||
// End completes the Span. The Span is considered complete and ready to be
|
||||
// delivered through the rest of the telemetry pipeline after this method
|
||||
// is called. Therefore, updates to the Span are not allowed after this
|
||||
// method has been called.
|
||||
End(options ...SpanOption)
|
||||
End(options ...SpanEndOption)
|
||||
|
||||
// AddEvent adds an event with the provided name and options.
|
||||
AddEvent(name string, options ...EventOption)
|
||||
@@ -516,19 +354,19 @@ type Span interface {
|
||||
IsRecording() bool
|
||||
|
||||
// RecordError will record err as an exception span event for this span. An
|
||||
// additional call toSetStatus is required if the Status of the Span should
|
||||
// be set to Error, this method does not change the Span status. If this
|
||||
// span is not being recorded or err is nil than this method does nothing.
|
||||
// additional call to SetStatus is required if the Status of the Span should
|
||||
// be set to Error, as this method does not change the Span status. If this
|
||||
// span is not being recorded or err is nil then this method does nothing.
|
||||
RecordError(err error, options ...EventOption)
|
||||
|
||||
// SpanContext returns the SpanContext of the Span. The returned
|
||||
// SpanContext is usable even after the End has been called for the Span.
|
||||
// SpanContext returns the SpanContext of the Span. The returned SpanContext
|
||||
// is usable even after the End method has been called for the Span.
|
||||
SpanContext() SpanContext
|
||||
|
||||
// SetStatus sets the status of the Span in the form of a code and a
|
||||
// message. SetStatus overrides the value of previous calls to SetStatus
|
||||
// on the Span.
|
||||
SetStatus(code codes.Code, msg string)
|
||||
// description, overriding previous values set. The description is only
|
||||
// included in a status when the code is for an error.
|
||||
SetStatus(code codes.Code, description string)
|
||||
|
||||
// SetName sets the Span name.
|
||||
SetName(name string)
|
||||
@@ -537,22 +375,10 @@ type Span interface {
|
||||
// already exists for an attribute of the Span it will be overwritten with
|
||||
// the value contained in kv.
|
||||
SetAttributes(kv ...attribute.KeyValue)
|
||||
}
|
||||
|
||||
// Event is a thing that happened during a Span's lifetime.
|
||||
type Event struct {
|
||||
// Name is the name of this event
|
||||
Name string
|
||||
|
||||
// Attributes describe the aspects of the event.
|
||||
Attributes []attribute.KeyValue
|
||||
|
||||
// DroppedAttributeCount is the number of attributes that were not
|
||||
// recorded due to configured limits being reached.
|
||||
DroppedAttributeCount int
|
||||
|
||||
// Time at which this event was recorded.
|
||||
Time time.Time
|
||||
// TracerProvider returns a TracerProvider that can be used to generate
|
||||
// additional Spans on the same telemetry pipeline as the current Span.
|
||||
TracerProvider() TracerProvider
|
||||
}
|
||||
|
||||
// Link is the relationship between two Spans. The relationship can be within
|
||||
@@ -560,26 +386,30 @@ type Event struct {
|
||||
//
|
||||
// For example, a Link is used in the following situations:
|
||||
//
|
||||
// 1. Batch Processing: A batch of operations may contain operations
|
||||
// associated with one or more traces/spans. Since there can only be one
|
||||
// parent SpanContext, a Link is used to keep reference to the
|
||||
// SpanContext of all operations in the batch.
|
||||
// 2. Public Endpoint: A SpanContext for an in incoming client request on a
|
||||
// public endpoint should be considered untrusted. In such a case, a new
|
||||
// trace with its own identity and sampling decision needs to be created,
|
||||
// but this new trace needs to be related to the original trace in some
|
||||
// form. A Link is used to keep reference to the original SpanContext and
|
||||
// track the relationship.
|
||||
// 1. Batch Processing: A batch of operations may contain operations
|
||||
// associated with one or more traces/spans. Since there can only be one
|
||||
// parent SpanContext, a Link is used to keep reference to the
|
||||
// SpanContext of all operations in the batch.
|
||||
// 2. Public Endpoint: A SpanContext for an in incoming client request on a
|
||||
// public endpoint should be considered untrusted. In such a case, a new
|
||||
// trace with its own identity and sampling decision needs to be created,
|
||||
// but this new trace needs to be related to the original trace in some
|
||||
// form. A Link is used to keep reference to the original SpanContext and
|
||||
// track the relationship.
|
||||
type Link struct {
|
||||
// SpanContext of the linked Span.
|
||||
SpanContext
|
||||
SpanContext SpanContext
|
||||
|
||||
// Attributes describe the aspects of the link.
|
||||
Attributes []attribute.KeyValue
|
||||
}
|
||||
|
||||
// DroppedAttributeCount is the number of attributes that were not
|
||||
// recorded due to configured limits being reached.
|
||||
DroppedAttributeCount int
|
||||
// LinkFromContext returns a link encapsulating the SpanContext in the provided ctx.
|
||||
func LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link {
|
||||
return Link{
|
||||
SpanContext: SpanContextFromContext(ctx),
|
||||
Attributes: attrs,
|
||||
}
|
||||
}
|
||||
|
||||
// SpanKind is the role a Span plays in a Trace.
|
||||
@@ -654,20 +484,67 @@ func (sk SpanKind) String() string {
|
||||
}
|
||||
|
||||
// Tracer is the creator of Spans.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Tracer interface {
|
||||
// Start creates a span.
|
||||
Start(ctx context.Context, spanName string, opts ...SpanOption) (context.Context, Span)
|
||||
// Start creates a span and a context.Context containing the newly-created span.
|
||||
//
|
||||
// If the context.Context provided in `ctx` contains a Span then the newly-created
|
||||
// Span will be a child of that span, otherwise it will be a root span. This behavior
|
||||
// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the
|
||||
// newly-created Span to be a root span even if `ctx` contains a Span.
|
||||
//
|
||||
// When creating a Span it is recommended to provide all known span attributes using
|
||||
// the `WithAttributes()` SpanOption as samplers will only have access to the
|
||||
// attributes provided when a Span is created.
|
||||
//
|
||||
// Any Span that is created MUST also be ended. This is the responsibility of the user.
|
||||
// Implementations of this API may leak memory or other resources if Spans are not ended.
|
||||
Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)
|
||||
}
|
||||
|
||||
// TracerProvider provides access to instrumentation Tracers.
|
||||
// TracerProvider provides Tracers that are used by instrumentation code to
|
||||
// trace computational workflows.
|
||||
//
|
||||
// A TracerProvider is the collection destination of all Spans from Tracers it
|
||||
// provides, it represents a unique telemetry collection pipeline. How that
|
||||
// pipeline is defined, meaning how those Spans are collected, processed, and
|
||||
// where they are exported, depends on its implementation. Instrumentation
|
||||
// authors do not need to define this implementation, rather just use the
|
||||
// provided Tracers to instrument code.
|
||||
//
|
||||
// Commonly, instrumentation code will accept a TracerProvider implementation
|
||||
// at runtime from its users or it can simply use the globally registered one
|
||||
// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider).
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type TracerProvider interface {
|
||||
// Tracer creates an implementation of the Tracer interface.
|
||||
// The instrumentationName must be the name of the library providing
|
||||
// instrumentation. This name may be the same as the instrumented code
|
||||
// only if that code provides built-in instrumentation. If the
|
||||
// instrumentationName is empty, then a implementation defined default
|
||||
// name will be used instead.
|
||||
// Tracer returns a unique Tracer scoped to be used by instrumentation code
|
||||
// to trace computational workflows. The scope and identity of that
|
||||
// instrumentation code is uniquely defined by the name and options passed.
|
||||
//
|
||||
// This method must be concurrency safe.
|
||||
Tracer(instrumentationName string, opts ...TracerOption) Tracer
|
||||
// The passed name needs to uniquely identify instrumentation code.
|
||||
// Therefore, it is recommended that name is the Go package name of the
|
||||
// library providing instrumentation (note: not the code being
|
||||
// instrumented). Instrumentation libraries can have multiple versions,
|
||||
// therefore, the WithInstrumentationVersion option should be used to
|
||||
// distinguish these different codebases. Additionally, instrumentation
|
||||
// libraries may sometimes use traces to communicate different domains of
|
||||
// workflow data (i.e. using spans to communicate workflow events only). If
|
||||
// this is the case, the WithScopeAttributes option should be used to
|
||||
// uniquely identify Tracers that handle the different domains of workflow
|
||||
// data.
|
||||
//
|
||||
// If the same name and options are passed multiple times, the same Tracer
|
||||
// will be returned (it is up to the implementation if this will be the
|
||||
// same underlying instance of that Tracer or not). It is not necessary to
|
||||
// call this multiple times with the same name and options to get an
|
||||
// up-to-date Tracer. All implementations will ensure any TracerProvider
|
||||
// configuration changes are propagated to all provided Tracers.
|
||||
//
|
||||
// If name is empty, then an implementation defined default name will be
|
||||
// used instead.
|
||||
//
|
||||
// This method is safe to call concurrently.
|
||||
Tracer(name string, options ...TracerOption) Tracer
|
||||
}
|
||||
|
||||
212
vendor/go.opentelemetry.io/otel/trace/tracestate.go
generated
vendored
Normal file
212
vendor/go.opentelemetry.io/otel/trace/tracestate.go
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
// Copyright The OpenTelemetry 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 trace // import "go.opentelemetry.io/otel/trace"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
maxListMembers = 32
|
||||
|
||||
listDelimiter = ","
|
||||
|
||||
// based on the W3C Trace Context specification, see
|
||||
// https://www.w3.org/TR/trace-context-1/#tracestate-header
|
||||
noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}`
|
||||
withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
|
||||
valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
|
||||
|
||||
errInvalidKey errorConst = "invalid tracestate key"
|
||||
errInvalidValue errorConst = "invalid tracestate value"
|
||||
errInvalidMember errorConst = "invalid tracestate list-member"
|
||||
errMemberNumber errorConst = "too many list-members in tracestate"
|
||||
errDuplicate errorConst = "duplicate list-member in tracestate"
|
||||
)
|
||||
|
||||
var (
|
||||
keyRe = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`)
|
||||
valueRe = regexp.MustCompile(`^(` + valueFormat + `)$`)
|
||||
memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
|
||||
)
|
||||
|
||||
type member struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
func newMember(key, value string) (member, error) {
|
||||
if !keyRe.MatchString(key) {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
|
||||
}
|
||||
if !valueRe.MatchString(value) {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidValue, value)
|
||||
}
|
||||
return member{Key: key, Value: value}, nil
|
||||
}
|
||||
|
||||
func parseMember(m string) (member, error) {
|
||||
matches := memberRe.FindStringSubmatch(m)
|
||||
if len(matches) != 5 {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
|
||||
}
|
||||
|
||||
return member{
|
||||
Key: matches[1],
|
||||
Value: matches[4],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String encodes member into a string compliant with the W3C Trace Context
|
||||
// specification.
|
||||
func (m member) String() string {
|
||||
return fmt.Sprintf("%s=%s", m.Key, m.Value)
|
||||
}
|
||||
|
||||
// TraceState provides additional vendor-specific trace identification
|
||||
// information across different distributed tracing systems. It represents an
|
||||
// immutable list consisting of key/value pairs, each pair is referred to as a
|
||||
// list-member.
|
||||
//
|
||||
// TraceState conforms to the W3C Trace Context specification
|
||||
// (https://www.w3.org/TR/trace-context-1). All operations that create or copy
|
||||
// a TraceState do so by validating all input and will only produce TraceState
|
||||
// that conform to the specification. Specifically, this means that all
|
||||
// list-member's key/value pairs are valid, no duplicate list-members exist,
|
||||
// and the maximum number of list-members (32) is not exceeded.
|
||||
type TraceState struct { //nolint:revive // revive complains about stutter of `trace.TraceState`
|
||||
// list is the members in order.
|
||||
list []member
|
||||
}
|
||||
|
||||
var _ json.Marshaler = TraceState{}
|
||||
|
||||
// ParseTraceState attempts to decode a TraceState from the passed
|
||||
// string. It returns an error if the input is invalid according to the W3C
|
||||
// Trace Context specification.
|
||||
func ParseTraceState(tracestate string) (TraceState, error) {
|
||||
if tracestate == "" {
|
||||
return TraceState{}, nil
|
||||
}
|
||||
|
||||
wrapErr := func(err error) error {
|
||||
return fmt.Errorf("failed to parse tracestate: %w", err)
|
||||
}
|
||||
|
||||
var members []member
|
||||
found := make(map[string]struct{})
|
||||
for _, memberStr := range strings.Split(tracestate, listDelimiter) {
|
||||
if len(memberStr) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
m, err := parseMember(memberStr)
|
||||
if err != nil {
|
||||
return TraceState{}, wrapErr(err)
|
||||
}
|
||||
|
||||
if _, ok := found[m.Key]; ok {
|
||||
return TraceState{}, wrapErr(errDuplicate)
|
||||
}
|
||||
found[m.Key] = struct{}{}
|
||||
|
||||
members = append(members, m)
|
||||
if n := len(members); n > maxListMembers {
|
||||
return TraceState{}, wrapErr(errMemberNumber)
|
||||
}
|
||||
}
|
||||
|
||||
return TraceState{list: members}, nil
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the TraceState into JSON.
|
||||
func (ts TraceState) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(ts.String())
|
||||
}
|
||||
|
||||
// String encodes the TraceState into a string compliant with the W3C
|
||||
// Trace Context specification. The returned string will be invalid if the
|
||||
// TraceState contains any invalid members.
|
||||
func (ts TraceState) String() string {
|
||||
members := make([]string, len(ts.list))
|
||||
for i, m := range ts.list {
|
||||
members[i] = m.String()
|
||||
}
|
||||
return strings.Join(members, listDelimiter)
|
||||
}
|
||||
|
||||
// Get returns the value paired with key from the corresponding TraceState
|
||||
// list-member if it exists, otherwise an empty string is returned.
|
||||
func (ts TraceState) Get(key string) string {
|
||||
for _, member := range ts.list {
|
||||
if member.Key == key {
|
||||
return member.Value
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Insert adds a new list-member defined by the key/value pair to the
|
||||
// TraceState. If a list-member already exists for the given key, that
|
||||
// list-member's value is updated. The new or updated list-member is always
|
||||
// moved to the beginning of the TraceState as specified by the W3C Trace
|
||||
// Context specification.
|
||||
//
|
||||
// If key or value are invalid according to the W3C Trace Context
|
||||
// specification an error is returned with the original TraceState.
|
||||
//
|
||||
// If adding a new list-member means the TraceState would have more members
|
||||
// then is allowed, the new list-member will be inserted and the right-most
|
||||
// list-member will be dropped in the returned TraceState.
|
||||
func (ts TraceState) Insert(key, value string) (TraceState, error) {
|
||||
m, err := newMember(key, value)
|
||||
if err != nil {
|
||||
return ts, err
|
||||
}
|
||||
|
||||
cTS := ts.Delete(key)
|
||||
if cTS.Len()+1 <= maxListMembers {
|
||||
cTS.list = append(cTS.list, member{})
|
||||
}
|
||||
// When the number of members exceeds capacity, drop the "right-most".
|
||||
copy(cTS.list[1:], cTS.list)
|
||||
cTS.list[0] = m
|
||||
|
||||
return cTS, nil
|
||||
}
|
||||
|
||||
// Delete returns a copy of the TraceState with the list-member identified by
|
||||
// key removed.
|
||||
func (ts TraceState) Delete(key string) TraceState {
|
||||
members := make([]member, ts.Len())
|
||||
copy(members, ts.list)
|
||||
for i, member := range ts.list {
|
||||
if member.Key == key {
|
||||
members = append(members[:i], members[i+1:]...)
|
||||
// TraceState should contain no duplicate members.
|
||||
break
|
||||
}
|
||||
}
|
||||
return TraceState{list: members}
|
||||
}
|
||||
|
||||
// Len returns the number of list-members in the TraceState.
|
||||
func (ts TraceState) Len() int {
|
||||
return len(ts.list)
|
||||
}
|
||||
Reference in New Issue
Block a user