feat(telemetry): instrument inference duration and frame age
This commit is contained in:
		
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/trace/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/trace/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										297
									
								
								vendor/go.opentelemetry.io/otel/trace/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								vendor/go.opentelemetry.io/otel/trace/config.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,297 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TracerConfig is a group of options for a Tracer.
 | 
			
		||||
type TracerConfig struct {
 | 
			
		||||
	instrumentationVersion string
 | 
			
		||||
	// Schema URL of the telemetry emitted by the Tracer.
 | 
			
		||||
	schemaURL string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentationVersion returns the version of the library providing instrumentation.
 | 
			
		||||
func (t *TracerConfig) InstrumentationVersion() string {
 | 
			
		||||
	return t.instrumentationVersion
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.
 | 
			
		||||
func (t *TracerConfig) SchemaURL() string {
 | 
			
		||||
	return t.schemaURL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewTracerConfig applies all the options to a returned TracerConfig.
 | 
			
		||||
func NewTracerConfig(options ...TracerOption) TracerConfig {
 | 
			
		||||
	var config TracerConfig
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		option.apply(&config)
 | 
			
		||||
	}
 | 
			
		||||
	return config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TracerOption applies an option to a TracerConfig.
 | 
			
		||||
type TracerOption interface {
 | 
			
		||||
	apply(*TracerConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type tracerOptionFunc func(*TracerConfig)
 | 
			
		||||
 | 
			
		||||
func (fn tracerOptionFunc) apply(cfg *TracerConfig) {
 | 
			
		||||
	fn(cfg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanConfig is a group of options for a Span.
 | 
			
		||||
type SpanConfig struct {
 | 
			
		||||
	attributes []attribute.KeyValue
 | 
			
		||||
	timestamp  time.Time
 | 
			
		||||
	links      []Link
 | 
			
		||||
	newRoot    bool
 | 
			
		||||
	spanKind   SpanKind
 | 
			
		||||
	stackTrace bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Attributes describe the associated qualities of a Span.
 | 
			
		||||
func (cfg *SpanConfig) Attributes() []attribute.KeyValue {
 | 
			
		||||
	return cfg.attributes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Timestamp is a time in a Span life-cycle.
 | 
			
		||||
func (cfg *SpanConfig) Timestamp() time.Time {
 | 
			
		||||
	return cfg.timestamp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StackTrace checks whether stack trace capturing is enabled.
 | 
			
		||||
func (cfg *SpanConfig) StackTrace() bool {
 | 
			
		||||
	return cfg.stackTrace
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Links are the associations a Span has with other Spans.
 | 
			
		||||
func (cfg *SpanConfig) Links() []Link {
 | 
			
		||||
	return cfg.links
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewRoot identifies a Span as the root Span for a new trace. This is
 | 
			
		||||
// commonly used when an existing trace crosses trust boundaries and the
 | 
			
		||||
// remote parent span context should be ignored for security.
 | 
			
		||||
func (cfg *SpanConfig) NewRoot() bool {
 | 
			
		||||
	return cfg.newRoot
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanKind is the role a Span has in a trace.
 | 
			
		||||
func (cfg *SpanConfig) SpanKind() SpanKind {
 | 
			
		||||
	return cfg.spanKind
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSpanStartConfig applies all the options to a returned SpanConfig.
 | 
			
		||||
// No validation is performed on the returned SpanConfig (e.g. no uniqueness
 | 
			
		||||
// checking or bounding of data), it is left to the SDK to perform this
 | 
			
		||||
// action.
 | 
			
		||||
func NewSpanStartConfig(options ...SpanStartOption) SpanConfig {
 | 
			
		||||
	var c SpanConfig
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		option.applySpanStart(&c)
 | 
			
		||||
	}
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSpanEndConfig applies all the options to a returned SpanConfig.
 | 
			
		||||
// No validation is performed on the returned SpanConfig (e.g. no uniqueness
 | 
			
		||||
// checking or bounding of data), it is left to the SDK to perform this
 | 
			
		||||
// action.
 | 
			
		||||
func NewSpanEndConfig(options ...SpanEndOption) SpanConfig {
 | 
			
		||||
	var c SpanConfig
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		option.applySpanEnd(&c)
 | 
			
		||||
	}
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanStartOption applies an option to a SpanConfig. These options are applicable
 | 
			
		||||
// only when the span is created
 | 
			
		||||
type SpanStartOption interface {
 | 
			
		||||
	applySpanStart(*SpanConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type spanOptionFunc func(*SpanConfig)
 | 
			
		||||
 | 
			
		||||
func (fn spanOptionFunc) applySpanStart(cfg *SpanConfig) {
 | 
			
		||||
	fn(cfg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanEndOption applies an option to a SpanConfig. These options are
 | 
			
		||||
// applicable only when the span is ended.
 | 
			
		||||
type SpanEndOption interface {
 | 
			
		||||
	applySpanEnd(*SpanConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EventConfig is a group of options for an Event.
 | 
			
		||||
type EventConfig struct {
 | 
			
		||||
	attributes []attribute.KeyValue
 | 
			
		||||
	timestamp  time.Time
 | 
			
		||||
	stackTrace bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Attributes describe the associated qualities of an Event.
 | 
			
		||||
func (cfg *EventConfig) Attributes() []attribute.KeyValue {
 | 
			
		||||
	return cfg.attributes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Timestamp is a time in an Event life-cycle.
 | 
			
		||||
func (cfg *EventConfig) Timestamp() time.Time {
 | 
			
		||||
	return cfg.timestamp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StackTrace checks whether stack trace capturing is enabled.
 | 
			
		||||
func (cfg *EventConfig) StackTrace() bool {
 | 
			
		||||
	return cfg.stackTrace
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEventConfig applies all the EventOptions to a returned EventConfig. If no
 | 
			
		||||
// timestamp option is passed, the returned EventConfig will have a Timestamp
 | 
			
		||||
// set to the call time, otherwise no validation is performed on the returned
 | 
			
		||||
// EventConfig.
 | 
			
		||||
func NewEventConfig(options ...EventOption) EventConfig {
 | 
			
		||||
	var c EventConfig
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		option.applyEvent(&c)
 | 
			
		||||
	}
 | 
			
		||||
	if c.timestamp.IsZero() {
 | 
			
		||||
		c.timestamp = time.Now()
 | 
			
		||||
	}
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EventOption applies span event options to an EventConfig.
 | 
			
		||||
type EventOption interface {
 | 
			
		||||
	applyEvent(*EventConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanOption are options that can be used at both the beginning and end of a span.
 | 
			
		||||
type SpanOption interface {
 | 
			
		||||
	SpanStartOption
 | 
			
		||||
	SpanEndOption
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanStartEventOption are options that can be used at the start of a span, or with an event.
 | 
			
		||||
type SpanStartEventOption interface {
 | 
			
		||||
	SpanStartOption
 | 
			
		||||
	EventOption
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanEndEventOption are options that can be used at the end of a span, or with an event.
 | 
			
		||||
type SpanEndEventOption interface {
 | 
			
		||||
	SpanEndOption
 | 
			
		||||
	EventOption
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type attributeOption []attribute.KeyValue
 | 
			
		||||
 | 
			
		||||
func (o attributeOption) applySpan(c *SpanConfig) {
 | 
			
		||||
	c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
 | 
			
		||||
}
 | 
			
		||||
func (o attributeOption) applySpanStart(c *SpanConfig) { o.applySpan(c) }
 | 
			
		||||
func (o attributeOption) applyEvent(c *EventConfig) {
 | 
			
		||||
	c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ SpanStartEventOption = attributeOption{}
 | 
			
		||||
 | 
			
		||||
// WithAttributes adds the attributes related to a span life-cycle event.
 | 
			
		||||
// These attributes are used to describe the work a Span represents when this
 | 
			
		||||
// option is provided to a Span's start or end events. Otherwise, these
 | 
			
		||||
// attributes provide additional information about the event being recorded
 | 
			
		||||
// (e.g. error, state change, processing progress, system event).
 | 
			
		||||
//
 | 
			
		||||
// If multiple of these options are passed the attributes of each successive
 | 
			
		||||
// option will extend the attributes instead of overwriting. There is no
 | 
			
		||||
// guarantee of uniqueness in the resulting attributes.
 | 
			
		||||
func WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption {
 | 
			
		||||
	return attributeOption(attributes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanEventOption are options that can be used with an event or a span.
 | 
			
		||||
type SpanEventOption interface {
 | 
			
		||||
	SpanOption
 | 
			
		||||
	EventOption
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type timestampOption time.Time
 | 
			
		||||
 | 
			
		||||
func (o timestampOption) applySpan(c *SpanConfig)      { c.timestamp = time.Time(o) }
 | 
			
		||||
func (o timestampOption) applySpanStart(c *SpanConfig) { o.applySpan(c) }
 | 
			
		||||
func (o timestampOption) applySpanEnd(c *SpanConfig)   { o.applySpan(c) }
 | 
			
		||||
func (o timestampOption) applyEvent(c *EventConfig)    { c.timestamp = time.Time(o) }
 | 
			
		||||
 | 
			
		||||
var _ SpanEventOption = timestampOption{}
 | 
			
		||||
 | 
			
		||||
// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g.
 | 
			
		||||
// started, stopped, errored).
 | 
			
		||||
func WithTimestamp(t time.Time) SpanEventOption {
 | 
			
		||||
	return timestampOption(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type stackTraceOption bool
 | 
			
		||||
 | 
			
		||||
func (o stackTraceOption) applyEvent(c *EventConfig)  { c.stackTrace = bool(o) }
 | 
			
		||||
func (o stackTraceOption) applySpan(c *SpanConfig)    { c.stackTrace = bool(o) }
 | 
			
		||||
func (o stackTraceOption) applySpanEnd(c *SpanConfig) { o.applySpan(c) }
 | 
			
		||||
 | 
			
		||||
// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false).
 | 
			
		||||
func WithStackTrace(b bool) SpanEndEventOption {
 | 
			
		||||
	return stackTraceOption(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithLinks adds links to a Span. The links are added to the existing Span
 | 
			
		||||
// links, i.e. this does not overwrite. Links with invalid span context are ignored.
 | 
			
		||||
func WithLinks(links ...Link) SpanStartOption {
 | 
			
		||||
	return spanOptionFunc(func(cfg *SpanConfig) {
 | 
			
		||||
		cfg.links = append(cfg.links, links...)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithNewRoot specifies that the Span should be treated as a root Span. Any
 | 
			
		||||
// existing parent span context will be ignored when defining the Span's trace
 | 
			
		||||
// identifiers.
 | 
			
		||||
func WithNewRoot() SpanStartOption {
 | 
			
		||||
	return spanOptionFunc(func(cfg *SpanConfig) {
 | 
			
		||||
		cfg.newRoot = true
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithSpanKind sets the SpanKind of a Span.
 | 
			
		||||
func WithSpanKind(kind SpanKind) SpanStartOption {
 | 
			
		||||
	return spanOptionFunc(func(cfg *SpanConfig) {
 | 
			
		||||
		cfg.spanKind = kind
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithInstrumentationVersion sets the instrumentation version.
 | 
			
		||||
func WithInstrumentationVersion(version string) TracerOption {
 | 
			
		||||
	return tracerOptionFunc(func(cfg *TracerConfig) {
 | 
			
		||||
		cfg.instrumentationVersion = version
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithSchemaURL sets the schema URL for the Tracer.
 | 
			
		||||
func WithSchemaURL(schemaURL string) TracerOption {
 | 
			
		||||
	return tracerOptionFunc(func(cfg *TracerConfig) {
 | 
			
		||||
		cfg.schemaURL = schemaURL
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								vendor/go.opentelemetry.io/otel/trace/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/go.opentelemetry.io/otel/trace/context.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
 | 
			
		||||
import "context"
 | 
			
		||||
 | 
			
		||||
type traceContextKeyType int
 | 
			
		||||
 | 
			
		||||
const currentSpanKey traceContextKeyType = iota
 | 
			
		||||
 | 
			
		||||
// ContextWithSpan returns a copy of parent with span set as the current Span.
 | 
			
		||||
func ContextWithSpan(parent context.Context, span Span) context.Context {
 | 
			
		||||
	return context.WithValue(parent, currentSpanKey, span)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithSpanContext returns a copy of parent with sc as the current
 | 
			
		||||
// Span. The Span implementation that wraps sc is non-recording and performs
 | 
			
		||||
// no operations other than to return sc as the SpanContext from the
 | 
			
		||||
// SpanContext method.
 | 
			
		||||
func ContextWithSpanContext(parent context.Context, sc SpanContext) context.Context {
 | 
			
		||||
	return ContextWithSpan(parent, nonRecordingSpan{sc: sc})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContextWithRemoteSpanContext returns a copy of parent with rsc set explicly
 | 
			
		||||
// as a remote SpanContext and as the current Span. The Span implementation
 | 
			
		||||
// that wraps rsc is non-recording and performs no operations other than to
 | 
			
		||||
// return rsc as the SpanContext from the SpanContext method.
 | 
			
		||||
func ContextWithRemoteSpanContext(parent context.Context, rsc SpanContext) context.Context {
 | 
			
		||||
	return ContextWithSpanContext(parent, rsc.WithRemote(true))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanFromContext returns the current Span from ctx.
 | 
			
		||||
//
 | 
			
		||||
// If no Span is currently set in ctx an implementation of a Span that
 | 
			
		||||
// performs no operations is returned.
 | 
			
		||||
func SpanFromContext(ctx context.Context) Span {
 | 
			
		||||
	if ctx == nil {
 | 
			
		||||
		return noopSpan{}
 | 
			
		||||
	}
 | 
			
		||||
	if span, ok := ctx.Value(currentSpanKey).(Span); ok {
 | 
			
		||||
		return span
 | 
			
		||||
	}
 | 
			
		||||
	return noopSpan{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanContextFromContext returns the current Span's SpanContext.
 | 
			
		||||
func SpanContextFromContext(ctx context.Context) SpanContext {
 | 
			
		||||
	return SpanFromContext(ctx).SpanContext()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								vendor/go.opentelemetry.io/otel/trace/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								vendor/go.opentelemetry.io/otel/trace/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package trace provides an implementation of the tracing part of the
 | 
			
		||||
OpenTelemetry API.
 | 
			
		||||
 | 
			
		||||
To participate in distributed traces a Span needs to be created for the
 | 
			
		||||
operation being performed as part of a traced workflow. It its simplest form:
 | 
			
		||||
 | 
			
		||||
	var tracer trace.Tracer
 | 
			
		||||
 | 
			
		||||
	func init() {
 | 
			
		||||
		tracer = otel.Tracer("instrumentation/package/name")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	func operation(ctx context.Context) {
 | 
			
		||||
		var span trace.Span
 | 
			
		||||
		ctx, span = tracer.Start(ctx, "operation")
 | 
			
		||||
		defer span.End()
 | 
			
		||||
		// ...
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
A Tracer is unique to the instrumentation and is used to create Spans.
 | 
			
		||||
Instrumentation should be designed to accept a TracerProvider from which it
 | 
			
		||||
can create its own unique Tracer. Alternatively, the registered global
 | 
			
		||||
TracerProvider from the go.opentelemetry.io/otel package can be used as
 | 
			
		||||
a default.
 | 
			
		||||
 | 
			
		||||
	const (
 | 
			
		||||
		name    = "instrumentation/package/name"
 | 
			
		||||
		version = "0.1.0"
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	type Instrumentation struct {
 | 
			
		||||
		tracer trace.Tracer
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	func NewInstrumentation(tp trace.TracerProvider) *Instrumentation {
 | 
			
		||||
		if tp == nil {
 | 
			
		||||
			tp = otel.TracerProvider()
 | 
			
		||||
		}
 | 
			
		||||
		return &Instrumentation{
 | 
			
		||||
			tracer: tp.Tracer(name, trace.WithInstrumentationVersion(version)),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	func operation(ctx context.Context, inst *Instrumentation) {
 | 
			
		||||
		var span trace.Span
 | 
			
		||||
		ctx, span = inst.tracer.Start(ctx, "operation")
 | 
			
		||||
		defer span.End()
 | 
			
		||||
		// ...
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/go.opentelemetry.io/otel/trace/nonrecording.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/go.opentelemetry.io/otel/trace/nonrecording.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
 | 
			
		||||
// nonRecordingSpan is a minimal implementation of a Span that wraps a
 | 
			
		||||
// SpanContext. It performs no operations other than to return the wrapped
 | 
			
		||||
// SpanContext.
 | 
			
		||||
type nonRecordingSpan struct {
 | 
			
		||||
	noopSpan
 | 
			
		||||
 | 
			
		||||
	sc SpanContext
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanContext returns the wrapped SpanContext.
 | 
			
		||||
func (s nonRecordingSpan) SpanContext() SpanContext { return s.sc }
 | 
			
		||||
							
								
								
									
										89
									
								
								vendor/go.opentelemetry.io/otel/trace/noop.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vendor/go.opentelemetry.io/otel/trace/noop.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewNoopTracerProvider returns an implementation of TracerProvider that
 | 
			
		||||
// performs no operations. The Tracer and Spans created from the returned
 | 
			
		||||
// TracerProvider also perform no operations.
 | 
			
		||||
func NewNoopTracerProvider() TracerProvider {
 | 
			
		||||
	return noopTracerProvider{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type noopTracerProvider struct{}
 | 
			
		||||
 | 
			
		||||
var _ TracerProvider = noopTracerProvider{}
 | 
			
		||||
 | 
			
		||||
// Tracer returns noop implementation of Tracer.
 | 
			
		||||
func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer {
 | 
			
		||||
	return noopTracer{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// noopTracer is an implementation of Tracer that preforms no operations.
 | 
			
		||||
type noopTracer struct{}
 | 
			
		||||
 | 
			
		||||
var _ Tracer = noopTracer{}
 | 
			
		||||
 | 
			
		||||
// Start carries forward a non-recording Span, if one is present in the context, otherwise it
 | 
			
		||||
// creates a no-op Span.
 | 
			
		||||
func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption) (context.Context, Span) {
 | 
			
		||||
	span := SpanFromContext(ctx)
 | 
			
		||||
	if _, ok := span.(nonRecordingSpan); !ok {
 | 
			
		||||
		// span is likely already a noopSpan, but let's be sure
 | 
			
		||||
		span = noopSpan{}
 | 
			
		||||
	}
 | 
			
		||||
	return ContextWithSpan(ctx, span), span
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// noopSpan is an implementation of Span that preforms no operations.
 | 
			
		||||
type noopSpan struct{}
 | 
			
		||||
 | 
			
		||||
var _ Span = noopSpan{}
 | 
			
		||||
 | 
			
		||||
// SpanContext returns an empty span context.
 | 
			
		||||
func (noopSpan) SpanContext() SpanContext { return SpanContext{} }
 | 
			
		||||
 | 
			
		||||
// IsRecording always returns false.
 | 
			
		||||
func (noopSpan) IsRecording() bool { return false }
 | 
			
		||||
 | 
			
		||||
// SetStatus does nothing.
 | 
			
		||||
func (noopSpan) SetStatus(codes.Code, string) {}
 | 
			
		||||
 | 
			
		||||
// SetError does nothing.
 | 
			
		||||
func (noopSpan) SetError(bool) {}
 | 
			
		||||
 | 
			
		||||
// SetAttributes does nothing.
 | 
			
		||||
func (noopSpan) SetAttributes(...attribute.KeyValue) {}
 | 
			
		||||
 | 
			
		||||
// End does nothing.
 | 
			
		||||
func (noopSpan) End(...SpanEndOption) {}
 | 
			
		||||
 | 
			
		||||
// RecordError does nothing.
 | 
			
		||||
func (noopSpan) RecordError(error, ...EventOption) {}
 | 
			
		||||
 | 
			
		||||
// AddEvent does nothing.
 | 
			
		||||
func (noopSpan) AddEvent(string, ...EventOption) {}
 | 
			
		||||
 | 
			
		||||
// SetName does nothing.
 | 
			
		||||
func (noopSpan) SetName(string) {}
 | 
			
		||||
 | 
			
		||||
// TracerProvider returns a no-op TracerProvider
 | 
			
		||||
func (noopSpan) TracerProvider() TracerProvider { return noopTracerProvider{} }
 | 
			
		||||
							
								
								
									
										519
									
								
								vendor/go.opentelemetry.io/otel/trace/trace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										519
									
								
								vendor/go.opentelemetry.io/otel/trace/trace.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,519 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// FlagsSampled is a bitmask with the sampled bit set. A SpanContext
 | 
			
		||||
	// with the sampling bit set means the span is sampled.
 | 
			
		||||
	FlagsSampled = TraceFlags(0x01)
 | 
			
		||||
 | 
			
		||||
	errInvalidHexID errorConst = "trace-id and span-id can only contain [0-9a-f] characters, all lowercase"
 | 
			
		||||
 | 
			
		||||
	errInvalidTraceIDLength errorConst = "hex encoded trace-id must have length equals to 32"
 | 
			
		||||
	errNilTraceID           errorConst = "trace-id can't be all zero"
 | 
			
		||||
 | 
			
		||||
	errInvalidSpanIDLength errorConst = "hex encoded span-id must have length equals to 16"
 | 
			
		||||
	errNilSpanID           errorConst = "span-id can't be all zero"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type errorConst string
 | 
			
		||||
 | 
			
		||||
func (e errorConst) Error() string {
 | 
			
		||||
	return string(e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceID is a unique identity of a trace.
 | 
			
		||||
// nolint:revive // revive complains about stutter of `trace.TraceID`.
 | 
			
		||||
type TraceID [16]byte
 | 
			
		||||
 | 
			
		||||
var nilTraceID TraceID
 | 
			
		||||
var _ json.Marshaler = nilTraceID
 | 
			
		||||
 | 
			
		||||
// IsValid checks whether the trace TraceID is valid. A valid trace ID does
 | 
			
		||||
// not consist of zeros only.
 | 
			
		||||
func (t TraceID) IsValid() bool {
 | 
			
		||||
	return !bytes.Equal(t[:], nilTraceID[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements a custom marshal function to encode TraceID
 | 
			
		||||
// as a hex string.
 | 
			
		||||
func (t TraceID) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(t.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the hex string representation form of a TraceID
 | 
			
		||||
func (t TraceID) String() string {
 | 
			
		||||
	return hex.EncodeToString(t[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanID is a unique identity of a span in a trace.
 | 
			
		||||
type SpanID [8]byte
 | 
			
		||||
 | 
			
		||||
var nilSpanID SpanID
 | 
			
		||||
var _ json.Marshaler = nilSpanID
 | 
			
		||||
 | 
			
		||||
// IsValid checks whether the SpanID is valid. A valid SpanID does not consist
 | 
			
		||||
// of zeros only.
 | 
			
		||||
func (s SpanID) IsValid() bool {
 | 
			
		||||
	return !bytes.Equal(s[:], nilSpanID[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements a custom marshal function to encode SpanID
 | 
			
		||||
// as a hex string.
 | 
			
		||||
func (s SpanID) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(s.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the hex string representation form of a SpanID
 | 
			
		||||
func (s SpanID) String() string {
 | 
			
		||||
	return hex.EncodeToString(s[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceIDFromHex returns a TraceID from a hex string if it is compliant with
 | 
			
		||||
// the W3C trace-context specification.  See more at
 | 
			
		||||
// https://www.w3.org/TR/trace-context/#trace-id
 | 
			
		||||
// nolint:revive // revive complains about stutter of `trace.TraceIDFromHex`.
 | 
			
		||||
func TraceIDFromHex(h string) (TraceID, error) {
 | 
			
		||||
	t := TraceID{}
 | 
			
		||||
	if len(h) != 32 {
 | 
			
		||||
		return t, errInvalidTraceIDLength
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := decodeHex(h, t[:]); err != nil {
 | 
			
		||||
		return t, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !t.IsValid() {
 | 
			
		||||
		return t, errNilTraceID
 | 
			
		||||
	}
 | 
			
		||||
	return t, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanIDFromHex returns a SpanID from a hex string if it is compliant
 | 
			
		||||
// with the w3c trace-context specification.
 | 
			
		||||
// See more at https://www.w3.org/TR/trace-context/#parent-id
 | 
			
		||||
func SpanIDFromHex(h string) (SpanID, error) {
 | 
			
		||||
	s := SpanID{}
 | 
			
		||||
	if len(h) != 16 {
 | 
			
		||||
		return s, errInvalidSpanIDLength
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := decodeHex(h, s[:]); err != nil {
 | 
			
		||||
		return s, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !s.IsValid() {
 | 
			
		||||
		return s, errNilSpanID
 | 
			
		||||
	}
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeHex(h string, b []byte) error {
 | 
			
		||||
	for _, r := range h {
 | 
			
		||||
		switch {
 | 
			
		||||
		case 'a' <= r && r <= 'f':
 | 
			
		||||
			continue
 | 
			
		||||
		case '0' <= r && r <= '9':
 | 
			
		||||
			continue
 | 
			
		||||
		default:
 | 
			
		||||
			return errInvalidHexID
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	decoded, err := hex.DecodeString(h)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copy(b, decoded)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceFlags contains flags that can be set on a SpanContext
 | 
			
		||||
type TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`.
 | 
			
		||||
 | 
			
		||||
// IsSampled returns if the sampling bit is set in the TraceFlags.
 | 
			
		||||
func (tf TraceFlags) IsSampled() bool {
 | 
			
		||||
	return tf&FlagsSampled == FlagsSampled
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithSampled sets the sampling bit in a new copy of the TraceFlags.
 | 
			
		||||
func (tf TraceFlags) WithSampled(sampled bool) TraceFlags {
 | 
			
		||||
	if sampled {
 | 
			
		||||
		return tf | FlagsSampled
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return tf &^ FlagsSampled
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements a custom marshal function to encode TraceFlags
 | 
			
		||||
// as a hex string.
 | 
			
		||||
func (tf TraceFlags) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(tf.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the hex string representation form of TraceFlags
 | 
			
		||||
func (tf TraceFlags) String() string {
 | 
			
		||||
	return hex.EncodeToString([]byte{byte(tf)}[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanContextConfig contains mutable fields usable for constructing
 | 
			
		||||
// an immutable SpanContext.
 | 
			
		||||
type SpanContextConfig struct {
 | 
			
		||||
	TraceID    TraceID
 | 
			
		||||
	SpanID     SpanID
 | 
			
		||||
	TraceFlags TraceFlags
 | 
			
		||||
	TraceState TraceState
 | 
			
		||||
	Remote     bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSpanContext constructs a SpanContext using values from the provided
 | 
			
		||||
// SpanContextConfig.
 | 
			
		||||
func NewSpanContext(config SpanContextConfig) SpanContext {
 | 
			
		||||
	return SpanContext{
 | 
			
		||||
		traceID:    config.TraceID,
 | 
			
		||||
		spanID:     config.SpanID,
 | 
			
		||||
		traceFlags: config.TraceFlags,
 | 
			
		||||
		traceState: config.TraceState,
 | 
			
		||||
		remote:     config.Remote,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanContext contains identifying trace information about a Span.
 | 
			
		||||
type SpanContext struct {
 | 
			
		||||
	traceID    TraceID
 | 
			
		||||
	spanID     SpanID
 | 
			
		||||
	traceFlags TraceFlags
 | 
			
		||||
	traceState TraceState
 | 
			
		||||
	remote     bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ json.Marshaler = SpanContext{}
 | 
			
		||||
 | 
			
		||||
// IsValid returns if the SpanContext is valid. A valid span context has a
 | 
			
		||||
// valid TraceID and SpanID.
 | 
			
		||||
func (sc SpanContext) IsValid() bool {
 | 
			
		||||
	return sc.HasTraceID() && sc.HasSpanID()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsRemote indicates whether the SpanContext represents a remotely-created Span.
 | 
			
		||||
func (sc SpanContext) IsRemote() bool {
 | 
			
		||||
	return sc.remote
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithRemote returns a copy of sc with the Remote property set to remote.
 | 
			
		||||
func (sc SpanContext) WithRemote(remote bool) SpanContext {
 | 
			
		||||
	return SpanContext{
 | 
			
		||||
		traceID:    sc.traceID,
 | 
			
		||||
		spanID:     sc.spanID,
 | 
			
		||||
		traceFlags: sc.traceFlags,
 | 
			
		||||
		traceState: sc.traceState,
 | 
			
		||||
		remote:     remote,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceID returns the TraceID from the SpanContext.
 | 
			
		||||
func (sc SpanContext) TraceID() TraceID {
 | 
			
		||||
	return sc.traceID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasTraceID checks if the SpanContext has a valid TraceID.
 | 
			
		||||
func (sc SpanContext) HasTraceID() bool {
 | 
			
		||||
	return sc.traceID.IsValid()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithTraceID returns a new SpanContext with the TraceID replaced.
 | 
			
		||||
func (sc SpanContext) WithTraceID(traceID TraceID) SpanContext {
 | 
			
		||||
	return SpanContext{
 | 
			
		||||
		traceID:    traceID,
 | 
			
		||||
		spanID:     sc.spanID,
 | 
			
		||||
		traceFlags: sc.traceFlags,
 | 
			
		||||
		traceState: sc.traceState,
 | 
			
		||||
		remote:     sc.remote,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanID returns the SpanID from the SpanContext.
 | 
			
		||||
func (sc SpanContext) SpanID() SpanID {
 | 
			
		||||
	return sc.spanID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasSpanID checks if the SpanContext has a valid SpanID.
 | 
			
		||||
func (sc SpanContext) HasSpanID() bool {
 | 
			
		||||
	return sc.spanID.IsValid()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithSpanID returns a new SpanContext with the SpanID replaced.
 | 
			
		||||
func (sc SpanContext) WithSpanID(spanID SpanID) SpanContext {
 | 
			
		||||
	return SpanContext{
 | 
			
		||||
		traceID:    sc.traceID,
 | 
			
		||||
		spanID:     spanID,
 | 
			
		||||
		traceFlags: sc.traceFlags,
 | 
			
		||||
		traceState: sc.traceState,
 | 
			
		||||
		remote:     sc.remote,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceFlags returns the flags from the SpanContext.
 | 
			
		||||
func (sc SpanContext) TraceFlags() TraceFlags {
 | 
			
		||||
	return sc.traceFlags
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsSampled returns if the sampling bit is set in the SpanContext's TraceFlags.
 | 
			
		||||
func (sc SpanContext) IsSampled() bool {
 | 
			
		||||
	return sc.traceFlags.IsSampled()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithTraceFlags returns a new SpanContext with the TraceFlags replaced.
 | 
			
		||||
func (sc SpanContext) WithTraceFlags(flags TraceFlags) SpanContext {
 | 
			
		||||
	return SpanContext{
 | 
			
		||||
		traceID:    sc.traceID,
 | 
			
		||||
		spanID:     sc.spanID,
 | 
			
		||||
		traceFlags: flags,
 | 
			
		||||
		traceState: sc.traceState,
 | 
			
		||||
		remote:     sc.remote,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceState returns the TraceState from the SpanContext.
 | 
			
		||||
func (sc SpanContext) TraceState() TraceState {
 | 
			
		||||
	return sc.traceState
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithTraceState returns a new SpanContext with the TraceState replaced.
 | 
			
		||||
func (sc SpanContext) WithTraceState(state TraceState) SpanContext {
 | 
			
		||||
	return SpanContext{
 | 
			
		||||
		traceID:    sc.traceID,
 | 
			
		||||
		spanID:     sc.spanID,
 | 
			
		||||
		traceFlags: sc.traceFlags,
 | 
			
		||||
		traceState: state,
 | 
			
		||||
		remote:     sc.remote,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equal is a predicate that determines whether two SpanContext values are equal.
 | 
			
		||||
func (sc SpanContext) Equal(other SpanContext) bool {
 | 
			
		||||
	return sc.traceID == other.traceID &&
 | 
			
		||||
		sc.spanID == other.spanID &&
 | 
			
		||||
		sc.traceFlags == other.traceFlags &&
 | 
			
		||||
		sc.traceState.String() == other.traceState.String() &&
 | 
			
		||||
		sc.remote == other.remote
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements a custom marshal function to encode a SpanContext.
 | 
			
		||||
func (sc SpanContext) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(SpanContextConfig{
 | 
			
		||||
		TraceID:    sc.traceID,
 | 
			
		||||
		SpanID:     sc.spanID,
 | 
			
		||||
		TraceFlags: sc.traceFlags,
 | 
			
		||||
		TraceState: sc.traceState,
 | 
			
		||||
		Remote:     sc.remote,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Span is the individual component of a trace. It represents a single named
 | 
			
		||||
// and timed operation of a workflow that is traced. A Tracer is used to
 | 
			
		||||
// create a Span and it is then up to the operation the Span represents to
 | 
			
		||||
// properly end the Span when the operation itself ends.
 | 
			
		||||
//
 | 
			
		||||
// Warning: methods may be added to this interface in minor releases.
 | 
			
		||||
type Span interface {
 | 
			
		||||
	// End completes the Span. The Span is considered complete and ready to be
 | 
			
		||||
	// delivered through the rest of the telemetry pipeline after this method
 | 
			
		||||
	// is called. Therefore, updates to the Span are not allowed after this
 | 
			
		||||
	// method has been called.
 | 
			
		||||
	End(options ...SpanEndOption)
 | 
			
		||||
 | 
			
		||||
	// AddEvent adds an event with the provided name and options.
 | 
			
		||||
	AddEvent(name string, options ...EventOption)
 | 
			
		||||
 | 
			
		||||
	// IsRecording returns the recording state of the Span. It will return
 | 
			
		||||
	// true if the Span is active and events can be recorded.
 | 
			
		||||
	IsRecording() bool
 | 
			
		||||
 | 
			
		||||
	// RecordError will record err as an exception span event for this span. An
 | 
			
		||||
	// additional call to SetStatus is required if the Status of the Span should
 | 
			
		||||
	// be set to Error, as this method does not change the Span status. If this
 | 
			
		||||
	// span is not being recorded or err is nil then this method does nothing.
 | 
			
		||||
	RecordError(err error, options ...EventOption)
 | 
			
		||||
 | 
			
		||||
	// SpanContext returns the SpanContext of the Span. The returned SpanContext
 | 
			
		||||
	// is usable even after the End method has been called for the Span.
 | 
			
		||||
	SpanContext() SpanContext
 | 
			
		||||
 | 
			
		||||
	// SetStatus sets the status of the Span in the form of a code and a
 | 
			
		||||
	// description, overriding previous values set. The description is only
 | 
			
		||||
	// included in a status when the code is for an error.
 | 
			
		||||
	SetStatus(code codes.Code, description string)
 | 
			
		||||
 | 
			
		||||
	// SetName sets the Span name.
 | 
			
		||||
	SetName(name string)
 | 
			
		||||
 | 
			
		||||
	// SetAttributes sets kv as attributes of the Span. If a key from kv
 | 
			
		||||
	// already exists for an attribute of the Span it will be overwritten with
 | 
			
		||||
	// the value contained in kv.
 | 
			
		||||
	SetAttributes(kv ...attribute.KeyValue)
 | 
			
		||||
 | 
			
		||||
	// TracerProvider returns a TracerProvider that can be used to generate
 | 
			
		||||
	// additional Spans on the same telemetry pipeline as the current Span.
 | 
			
		||||
	TracerProvider() TracerProvider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Link is the relationship between two Spans. The relationship can be within
 | 
			
		||||
// the same Trace or across different Traces.
 | 
			
		||||
//
 | 
			
		||||
// For example, a Link is used in the following situations:
 | 
			
		||||
//
 | 
			
		||||
//   1. Batch Processing: A batch of operations may contain operations
 | 
			
		||||
//      associated with one or more traces/spans. Since there can only be one
 | 
			
		||||
//      parent SpanContext, a Link is used to keep reference to the
 | 
			
		||||
//      SpanContext of all operations in the batch.
 | 
			
		||||
//   2. Public Endpoint: A SpanContext for an in incoming client request on a
 | 
			
		||||
//      public endpoint should be considered untrusted. In such a case, a new
 | 
			
		||||
//      trace with its own identity and sampling decision needs to be created,
 | 
			
		||||
//      but this new trace needs to be related to the original trace in some
 | 
			
		||||
//      form. A Link is used to keep reference to the original SpanContext and
 | 
			
		||||
//      track the relationship.
 | 
			
		||||
type Link struct {
 | 
			
		||||
	// SpanContext of the linked Span.
 | 
			
		||||
	SpanContext SpanContext
 | 
			
		||||
 | 
			
		||||
	// Attributes describe the aspects of the link.
 | 
			
		||||
	Attributes []attribute.KeyValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LinkFromContext returns a link encapsulating the SpanContext in the provided ctx.
 | 
			
		||||
func LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link {
 | 
			
		||||
	return Link{
 | 
			
		||||
		SpanContext: SpanContextFromContext(ctx),
 | 
			
		||||
		Attributes:  attrs,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SpanKind is the role a Span plays in a Trace.
 | 
			
		||||
type SpanKind int
 | 
			
		||||
 | 
			
		||||
// As a convenience, these match the proto definition, see
 | 
			
		||||
// https://github.com/open-telemetry/opentelemetry-proto/blob/30d237e1ff3ab7aa50e0922b5bebdd93505090af/opentelemetry/proto/trace/v1/trace.proto#L101-L129
 | 
			
		||||
//
 | 
			
		||||
// The unspecified value is not a valid `SpanKind`. Use `ValidateSpanKind()`
 | 
			
		||||
// to coerce a span kind to a valid value.
 | 
			
		||||
const (
 | 
			
		||||
	// SpanKindUnspecified is an unspecified SpanKind and is not a valid
 | 
			
		||||
	// SpanKind. SpanKindUnspecified should be replaced with SpanKindInternal
 | 
			
		||||
	// if it is received.
 | 
			
		||||
	SpanKindUnspecified SpanKind = 0
 | 
			
		||||
	// SpanKindInternal is a SpanKind for a Span that represents an internal
 | 
			
		||||
	// operation within an application.
 | 
			
		||||
	SpanKindInternal SpanKind = 1
 | 
			
		||||
	// SpanKindServer is a SpanKind for a Span that represents the operation
 | 
			
		||||
	// of handling a request from a client.
 | 
			
		||||
	SpanKindServer SpanKind = 2
 | 
			
		||||
	// SpanKindClient is a SpanKind for a Span that represents the operation
 | 
			
		||||
	// of client making a request to a server.
 | 
			
		||||
	SpanKindClient SpanKind = 3
 | 
			
		||||
	// SpanKindProducer is a SpanKind for a Span that represents the operation
 | 
			
		||||
	// of a producer sending a message to a message broker. Unlike
 | 
			
		||||
	// SpanKindClient and SpanKindServer, there is often no direct
 | 
			
		||||
	// relationship between this kind of Span and a SpanKindConsumer kind. A
 | 
			
		||||
	// SpanKindProducer Span will end once the message is accepted by the
 | 
			
		||||
	// message broker which might not overlap with the processing of that
 | 
			
		||||
	// message.
 | 
			
		||||
	SpanKindProducer SpanKind = 4
 | 
			
		||||
	// SpanKindConsumer is a SpanKind for a Span that represents the operation
 | 
			
		||||
	// of a consumer receiving a message from a message broker. Like
 | 
			
		||||
	// SpanKindProducer Spans, there is often no direct relationship between
 | 
			
		||||
	// this Span and the Span that produced the message.
 | 
			
		||||
	SpanKindConsumer SpanKind = 5
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ValidateSpanKind returns a valid span kind value.  This will coerce
 | 
			
		||||
// invalid values into the default value, SpanKindInternal.
 | 
			
		||||
func ValidateSpanKind(spanKind SpanKind) SpanKind {
 | 
			
		||||
	switch spanKind {
 | 
			
		||||
	case SpanKindInternal,
 | 
			
		||||
		SpanKindServer,
 | 
			
		||||
		SpanKindClient,
 | 
			
		||||
		SpanKindProducer,
 | 
			
		||||
		SpanKindConsumer:
 | 
			
		||||
		// valid
 | 
			
		||||
		return spanKind
 | 
			
		||||
	default:
 | 
			
		||||
		return SpanKindInternal
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the specified name of the SpanKind in lower-case.
 | 
			
		||||
func (sk SpanKind) String() string {
 | 
			
		||||
	switch sk {
 | 
			
		||||
	case SpanKindInternal:
 | 
			
		||||
		return "internal"
 | 
			
		||||
	case SpanKindServer:
 | 
			
		||||
		return "server"
 | 
			
		||||
	case SpanKindClient:
 | 
			
		||||
		return "client"
 | 
			
		||||
	case SpanKindProducer:
 | 
			
		||||
		return "producer"
 | 
			
		||||
	case SpanKindConsumer:
 | 
			
		||||
		return "consumer"
 | 
			
		||||
	default:
 | 
			
		||||
		return "unspecified"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tracer is the creator of Spans.
 | 
			
		||||
//
 | 
			
		||||
// Warning: methods may be added to this interface in minor releases.
 | 
			
		||||
type Tracer interface {
 | 
			
		||||
	// Start creates a span and a context.Context containing the newly-created span.
 | 
			
		||||
	//
 | 
			
		||||
	// If the context.Context provided in `ctx` contains a Span then the newly-created
 | 
			
		||||
	// Span will be a child of that span, otherwise it will be a root span. This behavior
 | 
			
		||||
	// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the
 | 
			
		||||
	// newly-created Span to be a root span even if `ctx` contains a Span.
 | 
			
		||||
	//
 | 
			
		||||
	// When creating a Span it is recommended to provide all known span attributes using
 | 
			
		||||
	// the `WithAttributes()` SpanOption as samplers will only have access to the
 | 
			
		||||
	// attributes provided when a Span is created.
 | 
			
		||||
	//
 | 
			
		||||
	// Any Span that is created MUST also be ended. This is the responsibility of the user.
 | 
			
		||||
	// Implementations of this API may leak memory or other resources if Spans are not ended.
 | 
			
		||||
	Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TracerProvider provides access to instrumentation Tracers.
 | 
			
		||||
//
 | 
			
		||||
// Warning: methods may be added to this interface in minor releases.
 | 
			
		||||
type TracerProvider interface {
 | 
			
		||||
	// Tracer creates an implementation of the Tracer interface.
 | 
			
		||||
	// The instrumentationName must be the name of the library providing
 | 
			
		||||
	// instrumentation. This name may be the same as the instrumented code
 | 
			
		||||
	// only if that code provides built-in instrumentation. If the
 | 
			
		||||
	// instrumentationName is empty, then a implementation defined default
 | 
			
		||||
	// name will be used instead.
 | 
			
		||||
	//
 | 
			
		||||
	// This method must be concurrency safe.
 | 
			
		||||
	Tracer(instrumentationName string, opts ...TracerOption) Tracer
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										217
									
								
								vendor/go.opentelemetry.io/otel/trace/tracestate.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								vendor/go.opentelemetry.io/otel/trace/tracestate.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,217 @@
 | 
			
		||||
// Copyright The OpenTelemetry Authors
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package trace // import "go.opentelemetry.io/otel/trace"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	maxListMembers = 32
 | 
			
		||||
 | 
			
		||||
	listDelimiter = ","
 | 
			
		||||
 | 
			
		||||
	// based on the W3C Trace Context specification, see
 | 
			
		||||
	// https://www.w3.org/TR/trace-context-1/#tracestate-header
 | 
			
		||||
	noTenantKeyFormat   = `[a-z][_0-9a-z\-\*\/]{0,255}`
 | 
			
		||||
	withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
 | 
			
		||||
	valueFormat         = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
 | 
			
		||||
 | 
			
		||||
	keyRe    = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`)
 | 
			
		||||
	valueRe  = regexp.MustCompile(`^(` + valueFormat + `)$`)
 | 
			
		||||
	memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
 | 
			
		||||
 | 
			
		||||
	errInvalidKey    errorConst = "invalid tracestate key"
 | 
			
		||||
	errInvalidValue  errorConst = "invalid tracestate value"
 | 
			
		||||
	errInvalidMember errorConst = "invalid tracestate list-member"
 | 
			
		||||
	errMemberNumber  errorConst = "too many list-members in tracestate"
 | 
			
		||||
	errDuplicate     errorConst = "duplicate list-member in tracestate"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type member struct {
 | 
			
		||||
	Key   string
 | 
			
		||||
	Value string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newMember(key, value string) (member, error) {
 | 
			
		||||
	if !keyRe.MatchString(key) {
 | 
			
		||||
		return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
 | 
			
		||||
	}
 | 
			
		||||
	if !valueRe.MatchString(value) {
 | 
			
		||||
		return member{}, fmt.Errorf("%w: %s", errInvalidValue, value)
 | 
			
		||||
	}
 | 
			
		||||
	return member{Key: key, Value: value}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseMemeber(m string) (member, error) {
 | 
			
		||||
	matches := memberRe.FindStringSubmatch(m)
 | 
			
		||||
	if len(matches) != 5 {
 | 
			
		||||
		return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return member{
 | 
			
		||||
		Key:   matches[1],
 | 
			
		||||
		Value: matches[4],
 | 
			
		||||
	}, nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String encodes member into a string compliant with the W3C Trace Context
 | 
			
		||||
// specification.
 | 
			
		||||
func (m member) String() string {
 | 
			
		||||
	return fmt.Sprintf("%s=%s", m.Key, m.Value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TraceState provides additional vendor-specific trace identification
 | 
			
		||||
// information across different distributed tracing systems. It represents an
 | 
			
		||||
// immutable list consisting of key/value pairs, each pair is referred to as a
 | 
			
		||||
// list-member.
 | 
			
		||||
//
 | 
			
		||||
// TraceState conforms to the W3C Trace Context specification
 | 
			
		||||
// (https://www.w3.org/TR/trace-context-1). All operations that create or copy
 | 
			
		||||
// a TraceState do so by validating all input and will only produce TraceState
 | 
			
		||||
// that conform to the specification. Specifically, this means that all
 | 
			
		||||
// list-member's key/value pairs are valid, no duplicate list-members exist,
 | 
			
		||||
// and the maximum number of list-members (32) is not exceeded.
 | 
			
		||||
type TraceState struct { //nolint:revive // revive complains about stutter of `trace.TraceState`
 | 
			
		||||
	// list is the members in order.
 | 
			
		||||
	list []member
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ json.Marshaler = TraceState{}
 | 
			
		||||
 | 
			
		||||
// ParseTraceState attempts to decode a TraceState from the passed
 | 
			
		||||
// string. It returns an error if the input is invalid according to the W3C
 | 
			
		||||
// Trace Context specification.
 | 
			
		||||
func ParseTraceState(tracestate string) (TraceState, error) {
 | 
			
		||||
	if tracestate == "" {
 | 
			
		||||
		return TraceState{}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wrapErr := func(err error) error {
 | 
			
		||||
		return fmt.Errorf("failed to parse tracestate: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var members []member
 | 
			
		||||
	found := make(map[string]struct{})
 | 
			
		||||
	for _, memberStr := range strings.Split(tracestate, listDelimiter) {
 | 
			
		||||
		if len(memberStr) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m, err := parseMemeber(memberStr)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return TraceState{}, wrapErr(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if _, ok := found[m.Key]; ok {
 | 
			
		||||
			return TraceState{}, wrapErr(errDuplicate)
 | 
			
		||||
		}
 | 
			
		||||
		found[m.Key] = struct{}{}
 | 
			
		||||
 | 
			
		||||
		members = append(members, m)
 | 
			
		||||
		if n := len(members); n > maxListMembers {
 | 
			
		||||
			return TraceState{}, wrapErr(errMemberNumber)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TraceState{list: members}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON marshals the TraceState into JSON.
 | 
			
		||||
func (ts TraceState) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	return json.Marshal(ts.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String encodes the TraceState into a string compliant with the W3C
 | 
			
		||||
// Trace Context specification. The returned string will be invalid if the
 | 
			
		||||
// TraceState contains any invalid members.
 | 
			
		||||
func (ts TraceState) String() string {
 | 
			
		||||
	members := make([]string, len(ts.list))
 | 
			
		||||
	for i, m := range ts.list {
 | 
			
		||||
		members[i] = m.String()
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(members, listDelimiter)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get returns the value paired with key from the corresponding TraceState
 | 
			
		||||
// list-member if it exists, otherwise an empty string is returned.
 | 
			
		||||
func (ts TraceState) Get(key string) string {
 | 
			
		||||
	for _, member := range ts.list {
 | 
			
		||||
		if member.Key == key {
 | 
			
		||||
			return member.Value
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Insert adds a new list-member defined by the key/value pair to the
 | 
			
		||||
// TraceState. If a list-member already exists for the given key, that
 | 
			
		||||
// list-member's value is updated. The new or updated list-member is always
 | 
			
		||||
// moved to the beginning of the TraceState as specified by the W3C Trace
 | 
			
		||||
// Context specification.
 | 
			
		||||
//
 | 
			
		||||
// If key or value are invalid according to the W3C Trace Context
 | 
			
		||||
// specification an error is returned with the original TraceState.
 | 
			
		||||
//
 | 
			
		||||
// If adding a new list-member means the TraceState would have more members
 | 
			
		||||
// than is allowed an error is returned instead with the original TraceState.
 | 
			
		||||
func (ts TraceState) Insert(key, value string) (TraceState, error) {
 | 
			
		||||
	m, err := newMember(key, value)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ts, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cTS := ts.Delete(key)
 | 
			
		||||
	if cTS.Len()+1 > maxListMembers {
 | 
			
		||||
		// TODO (MrAlias): When the second version of the Trace Context
 | 
			
		||||
		// specification is published this needs to not return an error.
 | 
			
		||||
		// Instead it should drop the "right-most" member and insert the new
 | 
			
		||||
		// member at the front.
 | 
			
		||||
		//
 | 
			
		||||
		// https://github.com/w3c/trace-context/pull/448
 | 
			
		||||
		return ts, fmt.Errorf("failed to insert: %w", errMemberNumber)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cTS.list = append(cTS.list, member{})
 | 
			
		||||
	copy(cTS.list[1:], cTS.list)
 | 
			
		||||
	cTS.list[0] = m
 | 
			
		||||
 | 
			
		||||
	return cTS, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete returns a copy of the TraceState with the list-member identified by
 | 
			
		||||
// key removed.
 | 
			
		||||
func (ts TraceState) Delete(key string) TraceState {
 | 
			
		||||
	members := make([]member, ts.Len())
 | 
			
		||||
	copy(members, ts.list)
 | 
			
		||||
	for i, member := range ts.list {
 | 
			
		||||
		if member.Key == key {
 | 
			
		||||
			members = append(members[:i], members[i+1:]...)
 | 
			
		||||
			// TraceState should contain no duplicate members.
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return TraceState{list: members}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Len returns the number of list-members in the TraceState.
 | 
			
		||||
func (ts TraceState) Len() int {
 | 
			
		||||
	return len(ts.list)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user