span.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. // Copyright The 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. package trace // import "go.opentelemetry.io/otel/sdk/trace"
  15. import (
  16. "context"
  17. "fmt"
  18. "reflect"
  19. "runtime"
  20. rt "runtime/trace"
  21. "strings"
  22. "sync"
  23. "time"
  24. "unicode/utf8"
  25. "go.opentelemetry.io/otel/attribute"
  26. "go.opentelemetry.io/otel/codes"
  27. "go.opentelemetry.io/otel/sdk/instrumentation"
  28. "go.opentelemetry.io/otel/sdk/internal"
  29. "go.opentelemetry.io/otel/sdk/resource"
  30. semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
  31. "go.opentelemetry.io/otel/trace"
  32. )
  33. // ReadOnlySpan allows reading information from the data structure underlying a
  34. // trace.Span. It is used in places where reading information from a span is
  35. // necessary but changing the span isn't necessary or allowed.
  36. //
  37. // Warning: methods may be added to this interface in minor releases.
  38. type ReadOnlySpan interface {
  39. // Name returns the name of the span.
  40. Name() string
  41. // SpanContext returns the unique SpanContext that identifies the span.
  42. SpanContext() trace.SpanContext
  43. // Parent returns the unique SpanContext that identifies the parent of the
  44. // span if one exists. If the span has no parent the returned SpanContext
  45. // will be invalid.
  46. Parent() trace.SpanContext
  47. // SpanKind returns the role the span plays in a Trace.
  48. SpanKind() trace.SpanKind
  49. // StartTime returns the time the span started recording.
  50. StartTime() time.Time
  51. // EndTime returns the time the span stopped recording. It will be zero if
  52. // the span has not ended.
  53. EndTime() time.Time
  54. // Attributes returns the defining attributes of the span.
  55. // The order of the returned attributes is not guaranteed to be stable across invocations.
  56. Attributes() []attribute.KeyValue
  57. // Links returns all the links the span has to other spans.
  58. Links() []Link
  59. // Events returns all the events that occurred within in the spans
  60. // lifetime.
  61. Events() []Event
  62. // Status returns the spans status.
  63. Status() Status
  64. // InstrumentationScope returns information about the instrumentation
  65. // scope that created the span.
  66. InstrumentationScope() instrumentation.Scope
  67. // InstrumentationLibrary returns information about the instrumentation
  68. // library that created the span.
  69. // Deprecated: please use InstrumentationScope instead.
  70. InstrumentationLibrary() instrumentation.Library
  71. // Resource returns information about the entity that produced the span.
  72. Resource() *resource.Resource
  73. // DroppedAttributes returns the number of attributes dropped by the span
  74. // due to limits being reached.
  75. DroppedAttributes() int
  76. // DroppedLinks returns the number of links dropped by the span due to
  77. // limits being reached.
  78. DroppedLinks() int
  79. // DroppedEvents returns the number of events dropped by the span due to
  80. // limits being reached.
  81. DroppedEvents() int
  82. // ChildSpanCount returns the count of spans that consider the span a
  83. // direct parent.
  84. ChildSpanCount() int
  85. // A private method to prevent users implementing the
  86. // interface and so future additions to it will not
  87. // violate compatibility.
  88. private()
  89. }
  90. // ReadWriteSpan exposes the same methods as trace.Span and in addition allows
  91. // reading information from the underlying data structure.
  92. // This interface exposes the union of the methods of trace.Span (which is a
  93. // "write-only" span) and ReadOnlySpan. New methods for writing or reading span
  94. // information should be added under trace.Span or ReadOnlySpan, respectively.
  95. //
  96. // Warning: methods may be added to this interface in minor releases.
  97. type ReadWriteSpan interface {
  98. trace.Span
  99. ReadOnlySpan
  100. }
  101. // recordingSpan is an implementation of the OpenTelemetry Span API
  102. // representing the individual component of a trace that is sampled.
  103. type recordingSpan struct {
  104. // mu protects the contents of this span.
  105. mu sync.Mutex
  106. // parent holds the parent span of this span as a trace.SpanContext.
  107. parent trace.SpanContext
  108. // spanKind represents the kind of this span as a trace.SpanKind.
  109. spanKind trace.SpanKind
  110. // name is the name of this span.
  111. name string
  112. // startTime is the time at which this span was started.
  113. startTime time.Time
  114. // endTime is the time at which this span was ended. It contains the zero
  115. // value of time.Time until the span is ended.
  116. endTime time.Time
  117. // status is the status of this span.
  118. status Status
  119. // childSpanCount holds the number of child spans created for this span.
  120. childSpanCount int
  121. // spanContext holds the SpanContext of this span.
  122. spanContext trace.SpanContext
  123. // attributes is a collection of user provided key/values. The collection
  124. // is constrained by a configurable maximum held by the parent
  125. // TracerProvider. When additional attributes are added after this maximum
  126. // is reached these attributes the user is attempting to add are dropped.
  127. // This dropped number of attributes is tracked and reported in the
  128. // ReadOnlySpan exported when the span ends.
  129. attributes []attribute.KeyValue
  130. droppedAttributes int
  131. // events are stored in FIFO queue capped by configured limit.
  132. events evictedQueue
  133. // links are stored in FIFO queue capped by configured limit.
  134. links evictedQueue
  135. // executionTracerTaskEnd ends the execution tracer span.
  136. executionTracerTaskEnd func()
  137. // tracer is the SDK tracer that created this span.
  138. tracer *tracer
  139. }
  140. var _ ReadWriteSpan = (*recordingSpan)(nil)
  141. var _ runtimeTracer = (*recordingSpan)(nil)
  142. // SpanContext returns the SpanContext of this span.
  143. func (s *recordingSpan) SpanContext() trace.SpanContext {
  144. if s == nil {
  145. return trace.SpanContext{}
  146. }
  147. return s.spanContext
  148. }
  149. // IsRecording returns if this span is being recorded. If this span has ended
  150. // this will return false.
  151. func (s *recordingSpan) IsRecording() bool {
  152. if s == nil {
  153. return false
  154. }
  155. s.mu.Lock()
  156. defer s.mu.Unlock()
  157. return s.endTime.IsZero()
  158. }
  159. // SetStatus sets the status of the Span in the form of a code and a
  160. // description, overriding previous values set. The description is only
  161. // included in the set status when the code is for an error. If this span is
  162. // not being recorded than this method does nothing.
  163. func (s *recordingSpan) SetStatus(code codes.Code, description string) {
  164. if !s.IsRecording() {
  165. return
  166. }
  167. s.mu.Lock()
  168. defer s.mu.Unlock()
  169. if s.status.Code > code {
  170. return
  171. }
  172. status := Status{Code: code}
  173. if code == codes.Error {
  174. status.Description = description
  175. }
  176. s.status = status
  177. }
  178. // SetAttributes sets attributes of this span.
  179. //
  180. // If a key from attributes already exists the value associated with that key
  181. // will be overwritten with the value contained in attributes.
  182. //
  183. // If this span is not being recorded than this method does nothing.
  184. //
  185. // If adding attributes to the span would exceed the maximum amount of
  186. // attributes the span is configured to have, the last added attributes will
  187. // be dropped.
  188. func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) {
  189. if !s.IsRecording() {
  190. return
  191. }
  192. s.mu.Lock()
  193. defer s.mu.Unlock()
  194. limit := s.tracer.provider.spanLimits.AttributeCountLimit
  195. if limit == 0 {
  196. // No attributes allowed.
  197. s.droppedAttributes += len(attributes)
  198. return
  199. }
  200. // If adding these attributes could exceed the capacity of s perform a
  201. // de-duplication and truncation while adding to avoid over allocation.
  202. if limit > 0 && len(s.attributes)+len(attributes) > limit {
  203. s.addOverCapAttrs(limit, attributes)
  204. return
  205. }
  206. // Otherwise, add without deduplication. When attributes are read they
  207. // will be deduplicated, optimizing the operation.
  208. for _, a := range attributes {
  209. if !a.Valid() {
  210. // Drop all invalid attributes.
  211. s.droppedAttributes++
  212. continue
  213. }
  214. a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)
  215. s.attributes = append(s.attributes, a)
  216. }
  217. }
  218. // addOverCapAttrs adds the attributes attrs to the span s while
  219. // de-duplicating the attributes of s and attrs and dropping attributes that
  220. // exceed the limit.
  221. //
  222. // This method assumes s.mu.Lock is held by the caller.
  223. //
  224. // This method should only be called when there is a possibility that adding
  225. // attrs to s will exceed the limit. Otherwise, attrs should be added to s
  226. // without checking for duplicates and all retrieval methods of the attributes
  227. // for s will de-duplicate as needed.
  228. //
  229. // This method assumes limit is a value > 0. The argument should be validated
  230. // by the caller.
  231. func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) {
  232. // In order to not allocate more capacity to s.attributes than needed,
  233. // prune and truncate this addition of attributes while adding.
  234. // Do not set a capacity when creating this map. Benchmark testing has
  235. // showed this to only add unused memory allocations in general use.
  236. exists := make(map[attribute.Key]int)
  237. s.dedupeAttrsFromRecord(&exists)
  238. // Now that s.attributes is deduplicated, adding unique attributes up to
  239. // the capacity of s will not over allocate s.attributes.
  240. for _, a := range attrs {
  241. if !a.Valid() {
  242. // Drop all invalid attributes.
  243. s.droppedAttributes++
  244. continue
  245. }
  246. if idx, ok := exists[a.Key]; ok {
  247. // Perform all updates before dropping, even when at capacity.
  248. s.attributes[idx] = a
  249. continue
  250. }
  251. if len(s.attributes) >= limit {
  252. // Do not just drop all of the remaining attributes, make sure
  253. // updates are checked and performed.
  254. s.droppedAttributes++
  255. } else {
  256. a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)
  257. s.attributes = append(s.attributes, a)
  258. exists[a.Key] = len(s.attributes) - 1
  259. }
  260. }
  261. }
  262. // truncateAttr returns a truncated version of attr. Only string and string
  263. // slice attribute values are truncated. String values are truncated to at
  264. // most a length of limit. Each string slice value is truncated in this fashion
  265. // (the slice length itself is unaffected).
  266. //
  267. // No truncation is performed for a negative limit.
  268. func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue {
  269. if limit < 0 {
  270. return attr
  271. }
  272. switch attr.Value.Type() {
  273. case attribute.STRING:
  274. if v := attr.Value.AsString(); len(v) > limit {
  275. return attr.Key.String(safeTruncate(v, limit))
  276. }
  277. case attribute.STRINGSLICE:
  278. v := attr.Value.AsStringSlice()
  279. for i := range v {
  280. if len(v[i]) > limit {
  281. v[i] = safeTruncate(v[i], limit)
  282. }
  283. }
  284. return attr.Key.StringSlice(v)
  285. }
  286. return attr
  287. }
  288. // safeTruncate truncates the string and guarantees valid UTF-8 is returned.
  289. func safeTruncate(input string, limit int) string {
  290. if trunc, ok := safeTruncateValidUTF8(input, limit); ok {
  291. return trunc
  292. }
  293. trunc, _ := safeTruncateValidUTF8(strings.ToValidUTF8(input, ""), limit)
  294. return trunc
  295. }
  296. // safeTruncateValidUTF8 returns a copy of the input string safely truncated to
  297. // limit. The truncation is ensured to occur at the bounds of complete UTF-8
  298. // characters. If invalid encoding of UTF-8 is encountered, input is returned
  299. // with false, otherwise, the truncated input will be returned with true.
  300. func safeTruncateValidUTF8(input string, limit int) (string, bool) {
  301. for cnt := 0; cnt <= limit; {
  302. r, size := utf8.DecodeRuneInString(input[cnt:])
  303. if r == utf8.RuneError {
  304. return input, false
  305. }
  306. if cnt+size > limit {
  307. return input[:cnt], true
  308. }
  309. cnt += size
  310. }
  311. return input, true
  312. }
  313. // End ends the span. This method does nothing if the span is already ended or
  314. // is not being recorded.
  315. //
  316. // The only SpanOption currently supported is WithTimestamp which will set the
  317. // end time for a Span's life-cycle.
  318. //
  319. // If this method is called while panicking an error event is added to the
  320. // Span before ending it and the panic is continued.
  321. func (s *recordingSpan) End(options ...trace.SpanEndOption) {
  322. // Do not start by checking if the span is being recorded which requires
  323. // acquiring a lock. Make a minimal check that the span is not nil.
  324. if s == nil {
  325. return
  326. }
  327. // Store the end time as soon as possible to avoid artificially increasing
  328. // the span's duration in case some operation below takes a while.
  329. et := internal.MonotonicEndTime(s.startTime)
  330. // Do relative expensive check now that we have an end time and see if we
  331. // need to do any more processing.
  332. if !s.IsRecording() {
  333. return
  334. }
  335. config := trace.NewSpanEndConfig(options...)
  336. if recovered := recover(); recovered != nil {
  337. // Record but don't stop the panic.
  338. defer panic(recovered)
  339. opts := []trace.EventOption{
  340. trace.WithAttributes(
  341. semconv.ExceptionType(typeStr(recovered)),
  342. semconv.ExceptionMessage(fmt.Sprint(recovered)),
  343. ),
  344. }
  345. if config.StackTrace() {
  346. opts = append(opts, trace.WithAttributes(
  347. semconv.ExceptionStacktrace(recordStackTrace()),
  348. ))
  349. }
  350. s.addEvent(semconv.ExceptionEventName, opts...)
  351. }
  352. if s.executionTracerTaskEnd != nil {
  353. s.executionTracerTaskEnd()
  354. }
  355. s.mu.Lock()
  356. // Setting endTime to non-zero marks the span as ended and not recording.
  357. if config.Timestamp().IsZero() {
  358. s.endTime = et
  359. } else {
  360. s.endTime = config.Timestamp()
  361. }
  362. s.mu.Unlock()
  363. sps := s.tracer.provider.getSpanProcessors()
  364. if len(sps) == 0 {
  365. return
  366. }
  367. snap := s.snapshot()
  368. for _, sp := range sps {
  369. sp.sp.OnEnd(snap)
  370. }
  371. }
  372. // RecordError will record err as a span event for this span. An additional call to
  373. // SetStatus is required if the Status of the Span should be set to Error, this method
  374. // does not change the Span status. If this span is not being recorded or err is nil
  375. // than this method does nothing.
  376. func (s *recordingSpan) RecordError(err error, opts ...trace.EventOption) {
  377. if s == nil || err == nil || !s.IsRecording() {
  378. return
  379. }
  380. opts = append(opts, trace.WithAttributes(
  381. semconv.ExceptionType(typeStr(err)),
  382. semconv.ExceptionMessage(err.Error()),
  383. ))
  384. c := trace.NewEventConfig(opts...)
  385. if c.StackTrace() {
  386. opts = append(opts, trace.WithAttributes(
  387. semconv.ExceptionStacktrace(recordStackTrace()),
  388. ))
  389. }
  390. s.addEvent(semconv.ExceptionEventName, opts...)
  391. }
  392. func typeStr(i interface{}) string {
  393. t := reflect.TypeOf(i)
  394. if t.PkgPath() == "" && t.Name() == "" {
  395. // Likely a builtin type.
  396. return t.String()
  397. }
  398. return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name())
  399. }
  400. func recordStackTrace() string {
  401. stackTrace := make([]byte, 2048)
  402. n := runtime.Stack(stackTrace, false)
  403. return string(stackTrace[0:n])
  404. }
  405. // AddEvent adds an event with the provided name and options. If this span is
  406. // not being recorded than this method does nothing.
  407. func (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) {
  408. if !s.IsRecording() {
  409. return
  410. }
  411. s.addEvent(name, o...)
  412. }
  413. func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) {
  414. c := trace.NewEventConfig(o...)
  415. e := Event{Name: name, Attributes: c.Attributes(), Time: c.Timestamp()}
  416. // Discard attributes over limit.
  417. limit := s.tracer.provider.spanLimits.AttributePerEventCountLimit
  418. if limit == 0 {
  419. // Drop all attributes.
  420. e.DroppedAttributeCount = len(e.Attributes)
  421. e.Attributes = nil
  422. } else if limit > 0 && len(e.Attributes) > limit {
  423. // Drop over capacity.
  424. e.DroppedAttributeCount = len(e.Attributes) - limit
  425. e.Attributes = e.Attributes[:limit]
  426. }
  427. s.mu.Lock()
  428. s.events.add(e)
  429. s.mu.Unlock()
  430. }
  431. // SetName sets the name of this span. If this span is not being recorded than
  432. // this method does nothing.
  433. func (s *recordingSpan) SetName(name string) {
  434. if !s.IsRecording() {
  435. return
  436. }
  437. s.mu.Lock()
  438. defer s.mu.Unlock()
  439. s.name = name
  440. }
  441. // Name returns the name of this span.
  442. func (s *recordingSpan) Name() string {
  443. s.mu.Lock()
  444. defer s.mu.Unlock()
  445. return s.name
  446. }
  447. // Name returns the SpanContext of this span's parent span.
  448. func (s *recordingSpan) Parent() trace.SpanContext {
  449. s.mu.Lock()
  450. defer s.mu.Unlock()
  451. return s.parent
  452. }
  453. // SpanKind returns the SpanKind of this span.
  454. func (s *recordingSpan) SpanKind() trace.SpanKind {
  455. s.mu.Lock()
  456. defer s.mu.Unlock()
  457. return s.spanKind
  458. }
  459. // StartTime returns the time this span started.
  460. func (s *recordingSpan) StartTime() time.Time {
  461. s.mu.Lock()
  462. defer s.mu.Unlock()
  463. return s.startTime
  464. }
  465. // EndTime returns the time this span ended. For spans that have not yet
  466. // ended, the returned value will be the zero value of time.Time.
  467. func (s *recordingSpan) EndTime() time.Time {
  468. s.mu.Lock()
  469. defer s.mu.Unlock()
  470. return s.endTime
  471. }
  472. // Attributes returns the attributes of this span.
  473. //
  474. // The order of the returned attributes is not guaranteed to be stable.
  475. func (s *recordingSpan) Attributes() []attribute.KeyValue {
  476. s.mu.Lock()
  477. defer s.mu.Unlock()
  478. s.dedupeAttrs()
  479. return s.attributes
  480. }
  481. // dedupeAttrs deduplicates the attributes of s to fit capacity.
  482. //
  483. // This method assumes s.mu.Lock is held by the caller.
  484. func (s *recordingSpan) dedupeAttrs() {
  485. // Do not set a capacity when creating this map. Benchmark testing has
  486. // showed this to only add unused memory allocations in general use.
  487. exists := make(map[attribute.Key]int)
  488. s.dedupeAttrsFromRecord(&exists)
  489. }
  490. // dedupeAttrsFromRecord deduplicates the attributes of s to fit capacity
  491. // using record as the record of unique attribute keys to their index.
  492. //
  493. // This method assumes s.mu.Lock is held by the caller.
  494. func (s *recordingSpan) dedupeAttrsFromRecord(record *map[attribute.Key]int) {
  495. // Use the fact that slices share the same backing array.
  496. unique := s.attributes[:0]
  497. for _, a := range s.attributes {
  498. if idx, ok := (*record)[a.Key]; ok {
  499. unique[idx] = a
  500. } else {
  501. unique = append(unique, a)
  502. (*record)[a.Key] = len(unique) - 1
  503. }
  504. }
  505. // s.attributes have element types of attribute.KeyValue. These types are
  506. // not pointers and they themselves do not contain pointer fields,
  507. // therefore the duplicate values do not need to be zeroed for them to be
  508. // garbage collected.
  509. s.attributes = unique
  510. }
  511. // Links returns the links of this span.
  512. func (s *recordingSpan) Links() []Link {
  513. s.mu.Lock()
  514. defer s.mu.Unlock()
  515. if len(s.links.queue) == 0 {
  516. return []Link{}
  517. }
  518. return s.interfaceArrayToLinksArray()
  519. }
  520. // Events returns the events of this span.
  521. func (s *recordingSpan) Events() []Event {
  522. s.mu.Lock()
  523. defer s.mu.Unlock()
  524. if len(s.events.queue) == 0 {
  525. return []Event{}
  526. }
  527. return s.interfaceArrayToEventArray()
  528. }
  529. // Status returns the status of this span.
  530. func (s *recordingSpan) Status() Status {
  531. s.mu.Lock()
  532. defer s.mu.Unlock()
  533. return s.status
  534. }
  535. // InstrumentationScope returns the instrumentation.Scope associated with
  536. // the Tracer that created this span.
  537. func (s *recordingSpan) InstrumentationScope() instrumentation.Scope {
  538. s.mu.Lock()
  539. defer s.mu.Unlock()
  540. return s.tracer.instrumentationScope
  541. }
  542. // InstrumentationLibrary returns the instrumentation.Library associated with
  543. // the Tracer that created this span.
  544. func (s *recordingSpan) InstrumentationLibrary() instrumentation.Library {
  545. s.mu.Lock()
  546. defer s.mu.Unlock()
  547. return s.tracer.instrumentationScope
  548. }
  549. // Resource returns the Resource associated with the Tracer that created this
  550. // span.
  551. func (s *recordingSpan) Resource() *resource.Resource {
  552. s.mu.Lock()
  553. defer s.mu.Unlock()
  554. return s.tracer.provider.resource
  555. }
  556. func (s *recordingSpan) addLink(link trace.Link) {
  557. if !s.IsRecording() || !link.SpanContext.IsValid() {
  558. return
  559. }
  560. l := Link{SpanContext: link.SpanContext, Attributes: link.Attributes}
  561. // Discard attributes over limit.
  562. limit := s.tracer.provider.spanLimits.AttributePerLinkCountLimit
  563. if limit == 0 {
  564. // Drop all attributes.
  565. l.DroppedAttributeCount = len(l.Attributes)
  566. l.Attributes = nil
  567. } else if limit > 0 && len(l.Attributes) > limit {
  568. l.DroppedAttributeCount = len(l.Attributes) - limit
  569. l.Attributes = l.Attributes[:limit]
  570. }
  571. s.mu.Lock()
  572. s.links.add(l)
  573. s.mu.Unlock()
  574. }
  575. // DroppedAttributes returns the number of attributes dropped by the span
  576. // due to limits being reached.
  577. func (s *recordingSpan) DroppedAttributes() int {
  578. s.mu.Lock()
  579. defer s.mu.Unlock()
  580. return s.droppedAttributes
  581. }
  582. // DroppedLinks returns the number of links dropped by the span due to limits
  583. // being reached.
  584. func (s *recordingSpan) DroppedLinks() int {
  585. s.mu.Lock()
  586. defer s.mu.Unlock()
  587. return s.links.droppedCount
  588. }
  589. // DroppedEvents returns the number of events dropped by the span due to
  590. // limits being reached.
  591. func (s *recordingSpan) DroppedEvents() int {
  592. s.mu.Lock()
  593. defer s.mu.Unlock()
  594. return s.events.droppedCount
  595. }
  596. // ChildSpanCount returns the count of spans that consider the span a
  597. // direct parent.
  598. func (s *recordingSpan) ChildSpanCount() int {
  599. s.mu.Lock()
  600. defer s.mu.Unlock()
  601. return s.childSpanCount
  602. }
  603. // TracerProvider returns a trace.TracerProvider that can be used to generate
  604. // additional Spans on the same telemetry pipeline as the current Span.
  605. func (s *recordingSpan) TracerProvider() trace.TracerProvider {
  606. return s.tracer.provider
  607. }
  608. // snapshot creates a read-only copy of the current state of the span.
  609. func (s *recordingSpan) snapshot() ReadOnlySpan {
  610. var sd snapshot
  611. s.mu.Lock()
  612. defer s.mu.Unlock()
  613. sd.endTime = s.endTime
  614. sd.instrumentationScope = s.tracer.instrumentationScope
  615. sd.name = s.name
  616. sd.parent = s.parent
  617. sd.resource = s.tracer.provider.resource
  618. sd.spanContext = s.spanContext
  619. sd.spanKind = s.spanKind
  620. sd.startTime = s.startTime
  621. sd.status = s.status
  622. sd.childSpanCount = s.childSpanCount
  623. if len(s.attributes) > 0 {
  624. s.dedupeAttrs()
  625. sd.attributes = s.attributes
  626. }
  627. sd.droppedAttributeCount = s.droppedAttributes
  628. if len(s.events.queue) > 0 {
  629. sd.events = s.interfaceArrayToEventArray()
  630. sd.droppedEventCount = s.events.droppedCount
  631. }
  632. if len(s.links.queue) > 0 {
  633. sd.links = s.interfaceArrayToLinksArray()
  634. sd.droppedLinkCount = s.links.droppedCount
  635. }
  636. return &sd
  637. }
  638. func (s *recordingSpan) interfaceArrayToLinksArray() []Link {
  639. linkArr := make([]Link, 0)
  640. for _, value := range s.links.queue {
  641. linkArr = append(linkArr, value.(Link))
  642. }
  643. return linkArr
  644. }
  645. func (s *recordingSpan) interfaceArrayToEventArray() []Event {
  646. eventArr := make([]Event, 0)
  647. for _, value := range s.events.queue {
  648. eventArr = append(eventArr, value.(Event))
  649. }
  650. return eventArr
  651. }
  652. func (s *recordingSpan) addChild() {
  653. if !s.IsRecording() {
  654. return
  655. }
  656. s.mu.Lock()
  657. s.childSpanCount++
  658. s.mu.Unlock()
  659. }
  660. func (*recordingSpan) private() {}
  661. // runtimeTrace starts a "runtime/trace".Task for the span and returns a
  662. // context containing the task.
  663. func (s *recordingSpan) runtimeTrace(ctx context.Context) context.Context {
  664. if !rt.IsEnabled() {
  665. // Avoid additional overhead if runtime/trace is not enabled.
  666. return ctx
  667. }
  668. nctx, task := rt.NewTask(ctx, s.name)
  669. s.mu.Lock()
  670. s.executionTracerTaskEnd = task.End
  671. s.mu.Unlock()
  672. return nctx
  673. }
  674. // nonRecordingSpan is a minimal implementation of the OpenTelemetry Span API
  675. // that wraps a SpanContext. It performs no operations other than to return
  676. // the wrapped SpanContext or TracerProvider that created it.
  677. type nonRecordingSpan struct {
  678. // tracer is the SDK tracer that created this span.
  679. tracer *tracer
  680. sc trace.SpanContext
  681. }
  682. var _ trace.Span = nonRecordingSpan{}
  683. // SpanContext returns the wrapped SpanContext.
  684. func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
  685. // IsRecording always returns false.
  686. func (nonRecordingSpan) IsRecording() bool { return false }
  687. // SetStatus does nothing.
  688. func (nonRecordingSpan) SetStatus(codes.Code, string) {}
  689. // SetError does nothing.
  690. func (nonRecordingSpan) SetError(bool) {}
  691. // SetAttributes does nothing.
  692. func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
  693. // End does nothing.
  694. func (nonRecordingSpan) End(...trace.SpanEndOption) {}
  695. // RecordError does nothing.
  696. func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
  697. // AddEvent does nothing.
  698. func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
  699. // SetName does nothing.
  700. func (nonRecordingSpan) SetName(string) {}
  701. // TracerProvider returns the trace.TracerProvider that provided the Tracer
  702. // that created this span.
  703. func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
  704. func isRecording(s SamplingResult) bool {
  705. return s.Decision == RecordOnly || s.Decision == RecordAndSample
  706. }
  707. func isSampled(s SamplingResult) bool {
  708. return s.Decision == RecordAndSample
  709. }
  710. // Status is the classified state of a Span.
  711. type Status struct {
  712. // Code is an identifier of a Spans state classification.
  713. Code codes.Code
  714. // Description is a user hint about why that status was set. It is only
  715. // applicable when Code is Error.
  716. Description string
  717. }