github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tracer/exptel/span.go (about)

     1  // Copyright 2019, OpenTelemetry Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package exptel
    16  
    17  import (
    18  	"time"
    19  
    20  	sdktrace "go.opentelemetry.io/otel/sdk/trace"
    21  )
    22  
    23  // SpanKind represents the role of a Span inside a Trace. Often, this defines how a Span
    24  // will be processed and visualized by various backends.
    25  type SpanKind int
    26  
    27  // ExperimentalTelemetrySpan contains all the information collected by a span.
    28  type ExperimentalTelemetrySpan struct {
    29  	SpanContext  SpanContext
    30  	ParentSpanID SpanID
    31  	SpanKind     SpanKind
    32  	Name         string
    33  	StartTime    time.Time
    34  	// The wall clock time of EndTime will be adjusted to always be offset
    35  	// from StartTime by the duration of the span.
    36  	EndTime                  time.Time
    37  	Attributes               []KeyValue
    38  	MessageEvents            []Event
    39  	Links                    []Link
    40  	Status                   Code
    41  	HasRemoteParent          bool
    42  	DroppedAttributeCount    int
    43  	DroppedMessageEventCount int
    44  	DroppedLinkCount         int
    45  
    46  	// ChildSpanCount holds the number of child span created for this span.
    47  	ChildSpanCount int
    48  }
    49  
    50  // NewSpanFromOtel converts an OpenTelemetry span to a type suitable for JSON marshaling for usage with `experimental_telemetry_cmd`.
    51  //
    52  // This format corresponds to the JSON marshaling from opentelemetry-go v0.2.0. See the package docs for more details.
    53  //
    54  // spanNamePrefix can be used to provide a prefix for the outgoing span name to mimic old opentelemetry-go behavior
    55  // which would prepend the tracer name to each span. (See https://github.com/open-telemetry/opentelemetry-go/pull/430).
    56  func NewSpanFromOtel(sd sdktrace.ReadOnlySpan, spanNamePrefix string) ExperimentalTelemetrySpan {
    57  	name := sd.Name()
    58  	if spanNamePrefix != "" && name != "" {
    59  		name = spanNamePrefix + name
    60  	}
    61  
    62  	return ExperimentalTelemetrySpan{
    63  		SpanContext:              NewSpanContextFromOtel(sd.SpanContext()),
    64  		ParentSpanID:             SpanID(sd.Parent().SpanID()),
    65  		SpanKind:                 SpanKind(sd.SpanKind()),
    66  		Name:                     name,
    67  		StartTime:                sd.StartTime(),
    68  		EndTime:                  sd.EndTime(),
    69  		Attributes:               NewKeyValuesFromOtel(sd.Attributes()),
    70  		MessageEvents:            NewEventsFromOtel(sd.Events()),
    71  		Links:                    NewLinksFromOtel(sd.Links()),
    72  		Status:                   Code(sd.Status().Code),
    73  		HasRemoteParent:          sd.Parent().IsRemote(),
    74  		DroppedAttributeCount:    sd.DroppedAttributes(),
    75  		DroppedMessageEventCount: sd.DroppedEvents(),
    76  		DroppedLinkCount:         sd.DroppedLinks(),
    77  		ChildSpanCount:           sd.ChildSpanCount(),
    78  	}
    79  }
    80  
    81  type Code uint32
    82  
    83  // Event is used to describe an Event with a message string and set of
    84  // Attributes.
    85  type Event struct {
    86  	// Message describes the Event.
    87  	Message string
    88  
    89  	// Attributes contains a list of keyvalue pairs.
    90  	Attributes []KeyValue
    91  
    92  	// Time is the time at which this event was recorded.
    93  	Time time.Time
    94  }
    95  
    96  func NewEventsFromOtel(e []sdktrace.Event) []Event {
    97  	if e == nil {
    98  		return nil
    99  	}
   100  
   101  	out := make([]Event, len(e))
   102  	for i := range e {
   103  		out[i] = Event{
   104  			Message:    e[i].Name,
   105  			Attributes: NewKeyValuesFromOtel(e[i].Attributes),
   106  			Time:       e[i].Time,
   107  		}
   108  	}
   109  	return out
   110  }
   111  
   112  // Link is used to establish relationship between two spans within the same Trace or
   113  // across different Traces. Few examples of Link usage.
   114  //  1. Batch Processing: A batch of elements may contain elements associated with one
   115  //     or more traces/spans. Since there can only be one parent SpanContext, Link is
   116  //     used to keep reference to SpanContext of all elements in the batch.
   117  //  2. Public Endpoint: A SpanContext in incoming client request on a public endpoint
   118  //     is untrusted from service provider perspective. In such case it is advisable to
   119  //     start a new trace with appropriate sampling decision.
   120  //     However, it is desirable to associate incoming SpanContext to new trace initiated
   121  //     on service provider side so two traces (from Client and from Service Provider) can
   122  //     be correlated.
   123  type Link struct {
   124  	SpanContext
   125  	Attributes []KeyValue
   126  }
   127  
   128  func NewLinksFromOtel(l []sdktrace.Link) []Link {
   129  	if l == nil {
   130  		return nil
   131  	}
   132  
   133  	out := make([]Link, len(l))
   134  	for i := range l {
   135  		out[i] = Link{
   136  			SpanContext: NewSpanContextFromOtel(l[i].SpanContext),
   137  			Attributes:  NewKeyValuesFromOtel(l[i].Attributes),
   138  		}
   139  	}
   140  	return out
   141  }