cockroach: github.com/cockroachdb/cockroach/pkg/util/tracing Index | Files

package tracing

import "github.com/cockroachdb/cockroach/pkg/util/tracing"

Index

Package Files

annotate.go format.go recorded_span.pb.go shadow.go tags.go test_utils.go tracer.go tracer_span.go

Constants

const (
    // TagPrefix is prefixed to all tags that should be output in SHOW TRACE.
    TagPrefix = "cockroach."
    // StatTagPrefix is prefixed to all stats output in span tags.
    StatTagPrefix = TagPrefix + "stat."
)
const Snowball = "sb"

Snowball is set as Baggage on traces which are used for snowball tracing.

Variables

var (
    ErrInvalidLengthRecordedSpan = fmt.Errorf("proto: negative length found during unmarshaling")
    ErrIntOverflowRecordedSpan   = fmt.Errorf("proto: integer overflow")
)
var Recordable opentracing.StartSpanOption = recordableOption{}

Recordable is a StartSpanOption that forces creation of a real span.

When tracing is disabled all spans are noopSpans; these spans aren't capable of recording, so this option should be passed to StartSpan if the caller wants to be able to call StartRecording on the resulting span.

func AnnotateTrace Uses

func AnnotateTrace()

AnnotateTrace adds an annotation to the golang executation tracer by calling a no-op cgo function.

func ChildSpan Uses

func ChildSpan(ctx context.Context, opName string) (context.Context, opentracing.Span)

ChildSpan opens a span as a child of the current span in the context (if there is one). The span's tags are inherited from the ctx's log tags automatically.

Returns the new context and the new span (if any). The span should be closed via FinishSpan.

func ChildSpanSeparateRecording Uses

func ChildSpanSeparateRecording(
    ctx context.Context, opName string,
) (context.Context, opentracing.Span)

ChildSpanSeparateRecording is like ChildSpan but the new span has separate recording (see StartChildSpan).

func ContextWithRecordingSpan Uses

func ContextWithRecordingSpan(
    ctx context.Context, opName string,
) (retCtx context.Context, getRecording func() []RecordedSpan, cancel func())

ContextWithRecordingSpan returns a context with an embedded trace span which returns its contents when getRecording is called and must be stopped by calling the cancel method when done with the context (getRecording() needs to be called before cancel()).

Note that to convert the recorded spans into text, you can use FormatRecordedSpans. Tests can also use FindMsgInRecording().

func EnsureChildSpan Uses

func EnsureChildSpan(
    ctx context.Context, tracer opentracing.Tracer, name string,
) (context.Context, opentracing.Span)

EnsureChildSpan is the same as EnsureContext, except it creates a child span for the input context if the input context already has an active trace.

The caller is responsible for closing the span (via Span.Finish).

func EnsureContext Uses

func EnsureContext(
    ctx context.Context, tracer opentracing.Tracer, opName string,
) (context.Context, func())

EnsureContext checks whether the given context.Context contains a Span. If not, it creates one using the provided Tracer and wraps it in the returned Span. The returned closure must be called after the request has been fully processed.

Note that, if there's already a span in the context, this method does nothing even if the current context's log tags are different from that span's tags.

func FindMsgInRecording Uses

func FindMsgInRecording(recording []RecordedSpan, msg string) int

FindMsgInRecording returns the index of the first span containing msg in its logs, or -1 if no span is found.

func FinishSpan Uses

func FinishSpan(span opentracing.Span)

FinishSpan closes the given span (if not nil). It is a convenience wrapper for span.Finish() which tolerates nil spans.

func ForkCtxSpan Uses

func ForkCtxSpan(ctx context.Context, opName string) (context.Context, opentracing.Span)

ForkCtxSpan checks if ctx has a Span open; if it does, it creates a new Span that "follows from" the original Span. This allows the resulting context to be used in an async task that might outlive the original operation.

Returns the new context and the new span (if any). The span should be closed via FinishSpan.

See also ChildSpan() for a "parent-child relationship".

func FormatRecordedSpans Uses

func FormatRecordedSpans(spans []RecordedSpan) string

FormatRecordedSpans formats the given spans for human consumption, showing the relationship using nesting and times as both relative to the previous event and cumulative.

TODO(andrei): this should be unified with SessionTracing.GenerateSessionTraceVTable.

func ImportRemoteSpans Uses

func ImportRemoteSpans(os opentracing.Span, remoteSpans []RecordedSpan) error

ImportRemoteSpans adds RecordedSpan data to the recording of the given span; these spans will be part of the result of GetRecording. Used to import recorded traces from other nodes.

func IsBlackHoleSpan Uses

func IsBlackHoleSpan(s opentracing.Span) bool

IsBlackHoleSpan returns true if events for this span are just dropped. This is the case when tracing is disabled and we're not recording. Tracing clients can use this method to figure out if they can short-circuit some tracing-related work that would be discarded anyway.

func IsNoopContext Uses

func IsNoopContext(spanCtx opentracing.SpanContext) bool

IsNoopContext returns true if the span context is from a "no-op" span. If this is true, any span derived from this context will be a "black hole span".

func IsRecordable Uses

func IsRecordable(os opentracing.Span) bool

IsRecordable returns true if {Start,Stop}Recording() can be called on this span.

In other words, this tests if the span is our custom type, and not a noopSpan or anything else.

func IsRecording Uses

func IsRecording(s opentracing.Span) bool

IsRecording returns true if the span is recording its events.

func LogTags Uses

func LogTags(tags *logtags.Buffer) opentracing.StartSpanOption

LogTags returns a StartSpanOption that sets the span tags to the given log tags.

func LogTagsFromCtx Uses

func LogTagsFromCtx(ctx context.Context) opentracing.StartSpanOption

LogTagsFromCtx returns a StartSpanOption that sets the span tags to the log tags in the context.

func RegisterTagRemapping Uses

func RegisterTagRemapping(logTag, spanTag string)

RegisterTagRemapping sets the span tag name that corresponds to the given log tag name. Should be called as part of an init() function.

func SetSpanStats Uses

func SetSpanStats(os opentracing.Span, stats SpanStats)

SetSpanStats sets the stats on a span. stats.Stats() will also be added to the span tags.

func StartChildSpan Uses

func StartChildSpan(
    opName string, parentSpan opentracing.Span, logTags *logtags.Buffer, separateRecording bool,
) opentracing.Span

StartChildSpan creates a child span of the given parent span. This is functionally equivalent to: parentSpan.Tracer().(*Tracer).StartSpan(opName, opentracing.ChildOf(parentSpan.Context())) Compared to that, it's more efficient, particularly in terms of memory allocations; among others, it saves the call to parentSpan.Context.

This only works for creating children of local parents (i.e. the caller needs to have a reference to the parent span).

If separateRecording is true and the parent span is recording, we start a new recording for the child span. If separateRecording is false (the default), then the child span will be part of the same recording.

func StartRecording Uses

func StartRecording(os opentracing.Span, recType RecordingType)

StartRecording enables recording on the span. Events from this point forward are recorded; also, all direct and indirect child spans started from now on will be part of the same recording.

Recording is not supported by noop spans; to ensure a real span is always created, use the Recordable option to StartSpan.

If recording was already started on this span (either directly or because a parent span is recording), the old recording is lost.

func StartSnowballTrace Uses

func StartSnowballTrace(
    ctx context.Context, tracer opentracing.Tracer, opName string,
) (context.Context, opentracing.Span, error)

StartSnowballTrace takes in a context and returns a derived one with a "snowball span" in it. The caller takes ownership of this span from the returned context and is in charge of Finish()ing it. The span has recording enabled.

TODO(andrei): remove this method once EXPLAIN(TRACE) is gone.

func StopRecording Uses

func StopRecording(os opentracing.Span)

StopRecording disables recording on this span. Child spans that were created since recording was started will continue to record until they finish.

Calling this after StartRecording is not required; the recording will go away when all the spans finish.

StopRecording() can be called on a Finish()ed span.

func TestingCheckRecordedSpans Uses

func TestingCheckRecordedSpans(recSpans []RecordedSpan, expected string) error

TestingCheckRecordedSpans checks whether a recording looks like an expected one represented by a string with one line per expected span and one line per expected event (i.e. log message).

Use with something like:

	 if err := TestingCheckRecordedSpans(tracing.GetRecording(span), `
    span root:
      event: a
      event: c
    span child:
      event: [ambient] b
  `); err != nil {
  	t.Fatal(err)
  }

The event lines can (and generally should) omit the file:line part that they might contain (depending on the level at which they were logged).

Note: this test function is in this file because it needs to be used by both tests in the tracing package and tests outside of it, and the function itself depends on tracing.

type RecordableOpt Uses

type RecordableOpt bool

RecordableOpt specifies whether a root span should be recordable.

const (
    // RecordableSpan means that the root span will be recordable. This means that
    // a real span will be created (and so it carries a cost).
    RecordableSpan RecordableOpt = true
    // NonRecordableSpan means that the root span will not be recordable. This
    // means that the static noop span might be returned.
    NonRecordableSpan RecordableOpt = false
)

type RecordedSpan Uses

type RecordedSpan struct {
    // ID of the trace; spans that are part of the same hierarchy share
    // the same trace ID.
    TraceID uint64 `protobuf:"varint,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"`
    // ID of the span.
    SpanID uint64 `protobuf:"varint,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"`
    // Span ID of the parent span.
    ParentSpanID uint64 `protobuf:"varint,3,opt,name=parent_span_id,json=parentSpanId,proto3" json:"parent_span_id,omitempty"`
    // Operation name.
    Operation string `protobuf:"bytes,4,opt,name=operation,proto3" json:"operation,omitempty"`
    // Baggage items get passed from parent to child spans (even through gRPC).
    // Notably, snowball tracing uses a special `sb` baggage item.
    Baggage map[string]string `protobuf:"bytes,5,rep,name=baggage,proto3" json:"baggage,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
    // Tags associated with the span.
    Tags map[string]string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
    // Time when the span was started.
    StartTime time.Time `protobuf:"bytes,7,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
    // Duration in nanoseconds; 0 if the span is not finished.
    Duration time.Duration `protobuf:"bytes,8,opt,name=duration,proto3,stdduration" json:"duration"`
    // Events logged in the span.
    Logs []RecordedSpan_LogRecord `protobuf:"bytes,9,rep,name=logs,proto3" json:"logs"`
    // Stats collected in this span.
    Stats *types.Any `protobuf:"bytes,10,opt,name=stats,proto3" json:"stats,omitempty"`
}

RecordedSpan is a span that is part of a recording. It can be transferred over the wire for snowball tracing.

func GetRecording Uses

func GetRecording(os opentracing.Span) []RecordedSpan

GetRecording retrieves the current recording, if the span has recording enabled. This can be called while spans that are part of the record are still open; it can run concurrently with operations on those spans.

func (*RecordedSpan) Descriptor Uses

func (*RecordedSpan) Descriptor() ([]byte, []int)

func (*RecordedSpan) Marshal Uses

func (m *RecordedSpan) Marshal() (dAtA []byte, err error)

func (*RecordedSpan) MarshalTo Uses

func (m *RecordedSpan) MarshalTo(dAtA []byte) (int, error)

func (*RecordedSpan) ProtoMessage Uses

func (*RecordedSpan) ProtoMessage()

func (*RecordedSpan) Reset Uses

func (m *RecordedSpan) Reset()

func (*RecordedSpan) Size Uses

func (m *RecordedSpan) Size() (n int)

func (*RecordedSpan) String Uses

func (m *RecordedSpan) String() string

func (*RecordedSpan) Unmarshal Uses

func (m *RecordedSpan) Unmarshal(dAtA []byte) error

func (*RecordedSpan) XXX_DiscardUnknown Uses

func (m *RecordedSpan) XXX_DiscardUnknown()

func (*RecordedSpan) XXX_Marshal Uses

func (m *RecordedSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*RecordedSpan) XXX_Merge Uses

func (dst *RecordedSpan) XXX_Merge(src proto.Message)

func (*RecordedSpan) XXX_Size Uses

func (m *RecordedSpan) XXX_Size() int

func (*RecordedSpan) XXX_Unmarshal Uses

func (m *RecordedSpan) XXX_Unmarshal(b []byte) error

type RecordedSpan_LogRecord Uses

type RecordedSpan_LogRecord struct {
    // Time of the log record.
    Time time.Time `protobuf:"bytes,1,opt,name=time,proto3,stdtime" json:"time"`
    // Fields with values converted to strings.
    Fields []RecordedSpan_LogRecord_Field `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields"`
}

func (*RecordedSpan_LogRecord) Descriptor Uses

func (*RecordedSpan_LogRecord) Descriptor() ([]byte, []int)

func (*RecordedSpan_LogRecord) Marshal Uses

func (m *RecordedSpan_LogRecord) Marshal() (dAtA []byte, err error)

func (*RecordedSpan_LogRecord) MarshalTo Uses

func (m *RecordedSpan_LogRecord) MarshalTo(dAtA []byte) (int, error)

func (*RecordedSpan_LogRecord) ProtoMessage Uses

func (*RecordedSpan_LogRecord) ProtoMessage()

func (*RecordedSpan_LogRecord) Reset Uses

func (m *RecordedSpan_LogRecord) Reset()

func (*RecordedSpan_LogRecord) Size Uses

func (m *RecordedSpan_LogRecord) Size() (n int)

func (*RecordedSpan_LogRecord) String Uses

func (m *RecordedSpan_LogRecord) String() string

func (*RecordedSpan_LogRecord) Unmarshal Uses

func (m *RecordedSpan_LogRecord) Unmarshal(dAtA []byte) error

func (*RecordedSpan_LogRecord) XXX_DiscardUnknown Uses

func (m *RecordedSpan_LogRecord) XXX_DiscardUnknown()

func (*RecordedSpan_LogRecord) XXX_Marshal Uses

func (m *RecordedSpan_LogRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*RecordedSpan_LogRecord) XXX_Merge Uses

func (dst *RecordedSpan_LogRecord) XXX_Merge(src proto.Message)

func (*RecordedSpan_LogRecord) XXX_Size Uses

func (m *RecordedSpan_LogRecord) XXX_Size() int

func (*RecordedSpan_LogRecord) XXX_Unmarshal Uses

func (m *RecordedSpan_LogRecord) XXX_Unmarshal(b []byte) error

type RecordedSpan_LogRecord_Field Uses

type RecordedSpan_LogRecord_Field struct {
    Key   string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
    Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}

func (*RecordedSpan_LogRecord_Field) Descriptor Uses

func (*RecordedSpan_LogRecord_Field) Descriptor() ([]byte, []int)

func (*RecordedSpan_LogRecord_Field) Marshal Uses

func (m *RecordedSpan_LogRecord_Field) Marshal() (dAtA []byte, err error)

func (*RecordedSpan_LogRecord_Field) MarshalTo Uses

func (m *RecordedSpan_LogRecord_Field) MarshalTo(dAtA []byte) (int, error)

func (*RecordedSpan_LogRecord_Field) ProtoMessage Uses

func (*RecordedSpan_LogRecord_Field) ProtoMessage()

func (*RecordedSpan_LogRecord_Field) Reset Uses

func (m *RecordedSpan_LogRecord_Field) Reset()

func (*RecordedSpan_LogRecord_Field) Size Uses

func (m *RecordedSpan_LogRecord_Field) Size() (n int)

func (*RecordedSpan_LogRecord_Field) String Uses

func (m *RecordedSpan_LogRecord_Field) String() string

func (*RecordedSpan_LogRecord_Field) Unmarshal Uses

func (m *RecordedSpan_LogRecord_Field) Unmarshal(dAtA []byte) error

func (*RecordedSpan_LogRecord_Field) XXX_DiscardUnknown Uses

func (m *RecordedSpan_LogRecord_Field) XXX_DiscardUnknown()

func (*RecordedSpan_LogRecord_Field) XXX_Marshal Uses

func (m *RecordedSpan_LogRecord_Field) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*RecordedSpan_LogRecord_Field) XXX_Merge Uses

func (dst *RecordedSpan_LogRecord_Field) XXX_Merge(src proto.Message)

func (*RecordedSpan_LogRecord_Field) XXX_Size Uses

func (m *RecordedSpan_LogRecord_Field) XXX_Size() int

func (*RecordedSpan_LogRecord_Field) XXX_Unmarshal Uses

func (m *RecordedSpan_LogRecord_Field) XXX_Unmarshal(b []byte) error

type RecordingType Uses

type RecordingType int

RecordingType is the type of recording that a span might be performing.

const (
    // NoRecording means that the span isn't recording.
    NoRecording RecordingType = iota
    // SnowballRecording means that remote child spans (generally opened through
    // RPCs) are also recorded.
    SnowballRecording
    // SingleNodeRecording means that only spans on the current node are recorded.
    SingleNodeRecording
)

type SpanStats Uses

type SpanStats interface {
    proto.Message
    // Stats returns the stats that the object represents as a map from stat name
    // to value to be added to span tags. The keys will be prefixed with
    // StatTagPrefix.
    Stats() map[string]string
}

SpanStats are stats that can be added to a span.

type Tracer Uses

type Tracer struct {
    // contains filtered or unexported fields
}

Tracer is our own custom implementation of opentracing.Tracer. It supports:

- forwarding events to x/net/trace instances

- recording traces. Recording is started automatically for spans that have
  the Snowball baggage and can be started explicitly as well. Recorded
  events can be retrieved at any time.

- lightstep traces. This is implemented by maintaining a "shadow" lightstep
  span inside each of our spans.

Even when tracing is disabled, we still use this Tracer (with x/net/trace and lightstep disabled) because of its recording capability (snowball tracing needs to work in all cases).

Tracer is currently stateless so we could have a single instance; however, this won't be the case if the cluster settings move away from using global state.

func NewTracer Uses

func NewTracer() *Tracer

NewTracer creates a Tracer. It initially tries to run with minimal overhead and collects essentially nothing; use Configure() to enable various tracing backends.

func (*Tracer) AlwaysTrace Uses

func (t *Tracer) AlwaysTrace() bool

AlwaysTrace returns true if operations should be traced regardless of the context.

func (*Tracer) Close Uses

func (t *Tracer) Close()

Close cleans up any resources associated with a Tracer.

func (*Tracer) Configure Uses

func (t *Tracer) Configure(sv *settings.Values)

Configure sets up the Tracer according to the cluster settings (and keeps it updated if they change).

func (*Tracer) Extract Uses

func (t *Tracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error)

Extract is part of the opentracing.Tracer interface. It always returns a valid context, even in error cases (this is assumed by the grpc-opentracing interceptor).

func (*Tracer) Inject Uses

func (t *Tracer) Inject(
    osc opentracing.SpanContext, format interface{}, carrier interface{},
) error

Inject is part of the opentracing.Tracer interface.

func (*Tracer) SetForceRealSpans Uses

func (t *Tracer) SetForceRealSpans(v bool) bool

SetForceRealSpans sets forceRealSpans option to v and returns the previous value.

func (*Tracer) StartRootSpan Uses

func (t *Tracer) StartRootSpan(
    opName string, logTags *logtags.Buffer, recordable RecordableOpt,
) opentracing.Span

StartRootSpan creates a root span. This is functionally equivalent to: parentSpan.Tracer().(*Tracer).StartSpan(opName, LogTags(...), [Recordable]) Compared to that, it's more efficient, particularly in terms of memory allocations because the opentracing.StartSpanOption interface is not used.

logTags can be nil.

func (*Tracer) StartSpan Uses

func (t *Tracer) StartSpan(
    operationName string, opts ...opentracing.StartSpanOption,
) opentracing.Span

StartSpan is part of the opentracing.Tracer interface.

Avoid using this method in favor of Tracer.StartRootSpan() or tracing.StartChildSpan() (or higher-level methods like EnsureContext() or AmbientContext.AnnotateCtxWithSpan()) when possible. Those are more efficient because they don't have to use the StartSpanOption interface and so a bunch of allocations are avoided. However, we need to implement this standard StartSpan() too because grpc integrates with a generic opentracing.Tracer.

Package tracing imports 31 packages (graph) and is imported by 76 packages. Updated 2019-07-10. Refresh now. Tools for package owners.