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 }