span.go 23 KB

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