mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 20:59:58 +00:00
TUN-5989: Add in-memory otlp exporter
This commit is contained in:
41
vendor/go.opentelemetry.io/contrib/propagators/Jaeger/context.go
generated
vendored
Normal file
41
vendor/go.opentelemetry.io/contrib/propagators/Jaeger/context.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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 jaeger
|
||||
|
||||
import "context"
|
||||
|
||||
type jaegerKeyType int
|
||||
|
||||
const (
|
||||
debugKey jaegerKeyType = iota
|
||||
)
|
||||
|
||||
// withDebug returns a copy of parent with debug set as the debug flag value .
|
||||
func withDebug(parent context.Context, debug bool) context.Context {
|
||||
return context.WithValue(parent, debugKey, debug)
|
||||
}
|
||||
|
||||
// debugFromContext returns the debug value stored in ctx.
|
||||
//
|
||||
// If no debug value is stored in ctx false is returned.
|
||||
func debugFromContext(ctx context.Context) bool {
|
||||
if ctx == nil {
|
||||
return false
|
||||
}
|
||||
if debug, ok := ctx.Value(debugKey).(bool); ok {
|
||||
return debug
|
||||
}
|
||||
return false
|
||||
}
|
17
vendor/go.opentelemetry.io/contrib/propagators/Jaeger/doc.go
generated
vendored
Normal file
17
vendor/go.opentelemetry.io/contrib/propagators/Jaeger/doc.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// 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.
|
||||
|
||||
// This package implements the Jaeger propagator specification as defined
|
||||
// at https://www.jaegertracing.io/docs/1.18/client-libraries/#propagation-format
|
||||
package jaeger // import "go.opentelemetry.io/contrib/propagators/jaeger"
|
161
vendor/go.opentelemetry.io/contrib/propagators/Jaeger/jaeger_propagator.go
generated
vendored
Normal file
161
vendor/go.opentelemetry.io/contrib/propagators/Jaeger/jaeger_propagator.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
// 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 jaeger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
jaegerHeader = "uber-trace-id"
|
||||
separator = ":"
|
||||
traceID64bitsWidth = 64 / 4
|
||||
traceID128bitsWidth = 128 / 4
|
||||
spanIDWidth = 64 / 4
|
||||
|
||||
traceIDPadding = "0000000000000000"
|
||||
|
||||
flagsDebug = 0x02
|
||||
flagsSampled = 0x01
|
||||
flagsNotSampled = 0x00
|
||||
|
||||
deprecatedParentSpanID = "0"
|
||||
)
|
||||
|
||||
var (
|
||||
empty = trace.SpanContext{}
|
||||
|
||||
errMalformedTraceContextVal = errors.New("header value of uber-trace-id should contain four different part separated by : ")
|
||||
errInvalidTraceIDLength = errors.New("invalid trace id length, must be either 16 or 32")
|
||||
errMalformedTraceID = errors.New("cannot decode trace id from header, should be a string of hex, lowercase trace id can't be all zero")
|
||||
errInvalidSpanIDLength = errors.New("invalid span id length, must be 16")
|
||||
errMalformedSpanID = errors.New("cannot decode span id from header, should be a string of hex, lowercase span id can't be all zero")
|
||||
errMalformedFlag = errors.New("cannot decode flag")
|
||||
)
|
||||
|
||||
// Jaeger propagator serializes SpanContext to/from Jaeger Headers
|
||||
//
|
||||
// Jaeger format:
|
||||
//
|
||||
// uber-trace-id: {trace-id}:{span-id}:{parent-span-id}:{flags}
|
||||
type Jaeger struct{}
|
||||
|
||||
var _ propagation.TextMapPropagator = &Jaeger{}
|
||||
|
||||
// Inject injects a context to the carrier following jaeger format.
|
||||
// The parent span ID is set to an dummy parent span id as the most implementations do.
|
||||
func (jaeger Jaeger) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
|
||||
sc := trace.SpanFromContext(ctx).SpanContext()
|
||||
headers := []string{}
|
||||
if !sc.TraceID().IsValid() || !sc.SpanID().IsValid() {
|
||||
return
|
||||
}
|
||||
headers = append(headers, sc.TraceID().String(), sc.SpanID().String(), deprecatedParentSpanID)
|
||||
if debugFromContext(ctx) {
|
||||
headers = append(headers, fmt.Sprintf("%x", flagsDebug|flagsSampled))
|
||||
} else if sc.IsSampled() {
|
||||
headers = append(headers, fmt.Sprintf("%x", flagsSampled))
|
||||
} else {
|
||||
headers = append(headers, fmt.Sprintf("%x", flagsNotSampled))
|
||||
}
|
||||
|
||||
carrier.Set(jaegerHeader, strings.Join(headers, separator))
|
||||
}
|
||||
|
||||
// Extract extracts a context from the carrier if it contains Jaeger headers.
|
||||
func (jaeger Jaeger) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
|
||||
// extract tracing information
|
||||
if h := carrier.Get(jaegerHeader); h != "" {
|
||||
ctx, sc, err := extract(ctx, h)
|
||||
if err == nil && sc.IsValid() {
|
||||
return trace.ContextWithRemoteSpanContext(ctx, sc)
|
||||
}
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
func extract(ctx context.Context, headerVal string) (context.Context, trace.SpanContext, error) {
|
||||
var (
|
||||
scc = trace.SpanContextConfig{}
|
||||
err error
|
||||
)
|
||||
|
||||
parts := strings.Split(headerVal, separator)
|
||||
if len(parts) != 4 {
|
||||
return ctx, empty, errMalformedTraceContextVal
|
||||
}
|
||||
|
||||
// extract trace ID
|
||||
if parts[0] != "" {
|
||||
id := parts[0]
|
||||
if len(id) != traceID128bitsWidth && len(id) != traceID64bitsWidth {
|
||||
return ctx, empty, errInvalidTraceIDLength
|
||||
}
|
||||
// padding when length is 16
|
||||
if len(id) == traceID64bitsWidth {
|
||||
id = traceIDPadding + id
|
||||
}
|
||||
scc.TraceID, err = trace.TraceIDFromHex(id)
|
||||
if err != nil {
|
||||
return ctx, empty, errMalformedTraceID
|
||||
}
|
||||
}
|
||||
|
||||
// extract span ID
|
||||
if parts[1] != "" {
|
||||
id := parts[1]
|
||||
if len(id) != spanIDWidth {
|
||||
return ctx, empty, errInvalidSpanIDLength
|
||||
}
|
||||
scc.SpanID, err = trace.SpanIDFromHex(id)
|
||||
if err != nil {
|
||||
return ctx, empty, errMalformedSpanID
|
||||
}
|
||||
}
|
||||
|
||||
// skip third part as it is deprecated
|
||||
|
||||
// extract flag
|
||||
if parts[3] != "" {
|
||||
flagStr := parts[3]
|
||||
flag, err := strconv.ParseInt(flagStr, 16, 64)
|
||||
if err != nil {
|
||||
return ctx, empty, errMalformedFlag
|
||||
}
|
||||
if flag&flagsSampled == flagsSampled {
|
||||
// if sample bit is set, we check if debug bit is also set
|
||||
if flag&flagsDebug == flagsDebug {
|
||||
scc.TraceFlags |= trace.FlagsSampled
|
||||
ctx = withDebug(ctx, true)
|
||||
} else {
|
||||
scc.TraceFlags |= trace.FlagsSampled
|
||||
}
|
||||
}
|
||||
// ignore other bit, including firehose since we don't have corresponding flag in trace context.
|
||||
}
|
||||
return ctx, trace.NewSpanContext(scc), nil
|
||||
}
|
||||
|
||||
func (jaeger Jaeger) Fields() []string {
|
||||
return []string{jaegerHeader}
|
||||
}
|
201
vendor/go.opentelemetry.io/contrib/propagators/LICENSE
generated
vendored
Normal file
201
vendor/go.opentelemetry.io/contrib/propagators/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.
|
3
vendor/go.opentelemetry.io/otel/.gitattributes
generated
vendored
Normal file
3
vendor/go.opentelemetry.io/otel/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
* text=auto eol=lf
|
||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
20
vendor/go.opentelemetry.io/otel/.gitignore
generated
vendored
Normal file
20
vendor/go.opentelemetry.io/otel/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
.tools/
|
||||
.idea/
|
||||
.vscode/
|
||||
*.iml
|
||||
*.so
|
||||
coverage.*
|
||||
|
||||
gen/
|
||||
|
||||
/example/fib/fib
|
||||
/example/jaeger/jaeger
|
||||
/example/namedtracer/namedtracer
|
||||
/example/opencensus/opencensus
|
||||
/example/passthrough/passthrough
|
||||
/example/prometheus/prometheus
|
||||
/example/zipkin/zipkin
|
||||
/example/otel-collector/otel-collector
|
3
vendor/go.opentelemetry.io/otel/.gitmodules
generated
vendored
Normal file
3
vendor/go.opentelemetry.io/otel/.gitmodules
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "opentelemetry-proto"]
|
||||
path = exporters/otlp/internal/opentelemetry-proto
|
||||
url = https://github.com/open-telemetry/opentelemetry-proto
|
47
vendor/go.opentelemetry.io/otel/.golangci.yml
generated
vendored
Normal file
47
vendor/go.opentelemetry.io/otel/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# See https://github.com/golangci/golangci-lint#config-file
|
||||
run:
|
||||
issues-exit-code: 1 #Default
|
||||
tests: true #Default
|
||||
|
||||
linters:
|
||||
# Disable everything by default so upgrades to not include new "default
|
||||
# enabled" linters.
|
||||
disable-all: true
|
||||
# Specifically enable linters we want to use.
|
||||
enable:
|
||||
- deadcode
|
||||
- errcheck
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- revive
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
# helpers in tests often (rightfully) pass a *testing.T as their first argument
|
||||
- path: _test\.go
|
||||
text: "context.Context should be the first parameter of a function"
|
||||
linters:
|
||||
- revive
|
||||
# Yes, they are, but it's okay in a test
|
||||
- path: _test\.go
|
||||
text: "exported func.*returns unexported type.*which can be annoying to use"
|
||||
linters:
|
||||
- revive
|
||||
|
||||
linters-settings:
|
||||
misspell:
|
||||
locale: US
|
||||
ignore-words:
|
||||
- cancelled
|
||||
goimports:
|
||||
local-prefixes: go.opentelemetry.io
|
20
vendor/go.opentelemetry.io/otel/.markdown-link.json
generated
vendored
Normal file
20
vendor/go.opentelemetry.io/otel/.markdown-link.json
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"ignorePatterns": [
|
||||
{
|
||||
"pattern": "^http(s)?://localhost"
|
||||
}
|
||||
],
|
||||
"replacementPatterns": [
|
||||
{
|
||||
"pattern": "^/registry",
|
||||
"replacement": "https://opentelemetry.io/registry"
|
||||
},
|
||||
{
|
||||
"pattern": "^/docs/",
|
||||
"replacement": "https://opentelemetry.io/docs/"
|
||||
}
|
||||
],
|
||||
"retryOn429": true,
|
||||
"retryCount": 5,
|
||||
"fallbackRetryDelay": "30s"
|
||||
}
|
29
vendor/go.opentelemetry.io/otel/.markdownlint.yaml
generated
vendored
Normal file
29
vendor/go.opentelemetry.io/otel/.markdownlint.yaml
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Default state for all rules
|
||||
default: true
|
||||
|
||||
# ul-style
|
||||
MD004: false
|
||||
|
||||
# hard-tabs
|
||||
MD010: false
|
||||
|
||||
# line-length
|
||||
MD013: false
|
||||
|
||||
# no-duplicate-header
|
||||
MD024:
|
||||
siblings_only: true
|
||||
|
||||
#single-title
|
||||
MD025: false
|
||||
|
||||
# ol-prefix
|
||||
MD029:
|
||||
style: ordered
|
||||
|
||||
# no-inline-html
|
||||
MD033: false
|
||||
|
||||
# fenced-code-language
|
||||
MD040: false
|
||||
|
1860
vendor/go.opentelemetry.io/otel/CHANGELOG.md
generated
vendored
Normal file
1860
vendor/go.opentelemetry.io/otel/CHANGELOG.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
vendor/go.opentelemetry.io/otel/CODEOWNERS
generated
vendored
Normal file
17
vendor/go.opentelemetry.io/otel/CODEOWNERS
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#####################################################
|
||||
#
|
||||
# List of approvers for this repository
|
||||
#
|
||||
#####################################################
|
||||
#
|
||||
# Learn about membership in OpenTelemetry community:
|
||||
# https://github.com/open-telemetry/community/blob/main/community-membership.md
|
||||
#
|
||||
#
|
||||
# Learn about CODEOWNERS file format:
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
#
|
||||
|
||||
* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod @pellared @hanyuancheung
|
||||
|
||||
CODEOWNERS @MrAlias @Aneurysm9 @MadVikingGod
|
522
vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
generated
vendored
Normal file
522
vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,522 @@
|
||||
# Contributing to opentelemetry-go
|
||||
|
||||
The Go special interest group (SIG) meets regularly. See the
|
||||
OpenTelemetry
|
||||
[community](https://github.com/open-telemetry/community#golang-sdk)
|
||||
repo for information on this and other language SIGs.
|
||||
|
||||
See the [public meeting
|
||||
notes](https://docs.google.com/document/d/1A63zSWX0x2CyCK_LoNhmQC4rqhLpYXJzXbEPDUQ2n6w/edit#heading=h.9tngw7jdwd6b)
|
||||
for a summary description of past meetings. To request edit access,
|
||||
join the meeting or get in touch on
|
||||
[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).
|
||||
|
||||
## Development
|
||||
|
||||
You can view and edit the source code by cloning this repository:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/open-telemetry/opentelemetry-go.git
|
||||
```
|
||||
|
||||
Run `make test` to run the tests instead of `go test`.
|
||||
|
||||
There are some generated files checked into the repo. To make sure
|
||||
that the generated files are up-to-date, run `make` (or `make
|
||||
precommit` - the `precommit` target is the default).
|
||||
|
||||
The `precommit` target also fixes the formatting of the code and
|
||||
checks the status of the go module files.
|
||||
|
||||
If after running `make precommit` the output of `git status` contains
|
||||
`nothing to commit, working tree clean` then it means that everything
|
||||
is up-to-date and properly formatted.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
### How to Send Pull Requests
|
||||
|
||||
Everyone is welcome to contribute code to `opentelemetry-go` via
|
||||
GitHub pull requests (PRs).
|
||||
|
||||
To create a new PR, fork the project in GitHub and clone the upstream
|
||||
repo:
|
||||
|
||||
```sh
|
||||
go get -d go.opentelemetry.io/otel
|
||||
```
|
||||
|
||||
(This may print some warning about "build constraints exclude all Go
|
||||
files", just ignore it.)
|
||||
|
||||
This will put the project in `${GOPATH}/src/go.opentelemetry.io/otel`. You
|
||||
can alternatively use `git` directly with:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/open-telemetry/opentelemetry-go
|
||||
```
|
||||
|
||||
(Note that `git clone` is *not* using the `go.opentelemetry.io/otel` name -
|
||||
that name is a kind of a redirector to GitHub that `go get` can
|
||||
understand, but `git` does not.)
|
||||
|
||||
This would put the project in the `opentelemetry-go` directory in
|
||||
current working directory.
|
||||
|
||||
Enter the newly created directory and add your fork as a new remote:
|
||||
|
||||
```sh
|
||||
git remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-go
|
||||
```
|
||||
|
||||
Check out a new branch, make modifications, run linters and tests, update
|
||||
`CHANGELOG.md`, and push the branch to your fork:
|
||||
|
||||
```sh
|
||||
git checkout -b <YOUR_BRANCH_NAME>
|
||||
# edit files
|
||||
# update changelog
|
||||
make precommit
|
||||
git add -p
|
||||
git commit
|
||||
git push <YOUR_FORK> <YOUR_BRANCH_NAME>
|
||||
```
|
||||
|
||||
Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull
|
||||
request ID to the entry you added to `CHANGELOG.md`.
|
||||
|
||||
### How to Receive Comments
|
||||
|
||||
* If the PR is not ready for review, please put `[WIP]` in the title,
|
||||
tag it as `work-in-progress`, or mark it as
|
||||
[`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
|
||||
* Make sure CLA is signed and CI is clear.
|
||||
|
||||
### How to Get PRs Merged
|
||||
|
||||
A PR is considered to be **ready to merge** when:
|
||||
|
||||
* It has received two approvals from Collaborators/Maintainers (at
|
||||
different companies). This is not enforced through technical means
|
||||
and a PR may be **ready to merge** with a single approval if the change
|
||||
and its approach have been discussed and consensus reached.
|
||||
* Feedback has been addressed.
|
||||
* Any substantive changes to your PR will require that you clear any prior
|
||||
Approval reviews, this includes changes resulting from other feedback. Unless
|
||||
the approver explicitly stated that their approval will persist across
|
||||
changes it should be assumed that the PR needs their review again. Other
|
||||
project members (e.g. approvers, maintainers) can help with this if there are
|
||||
any questions or if you forget to clear reviews.
|
||||
* It has been open for review for at least one working day. This gives
|
||||
people reasonable time to review.
|
||||
* Trivial changes (typo, cosmetic, doc, etc.) do not have to wait for
|
||||
one day and may be merged with a single Maintainer's approval.
|
||||
* `CHANGELOG.md` has been updated to reflect what has been
|
||||
added, changed, removed, or fixed.
|
||||
* `README.md` has been updated if necessary.
|
||||
* Urgent fix can take exception as long as it has been actively
|
||||
communicated.
|
||||
|
||||
Any Maintainer can merge the PR once it is **ready to merge**.
|
||||
|
||||
## Design Choices
|
||||
|
||||
As with other OpenTelemetry clients, opentelemetry-go follows the
|
||||
[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification).
|
||||
|
||||
It's especially valuable to read through the [library
|
||||
guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md).
|
||||
|
||||
### Focus on Capabilities, Not Structure Compliance
|
||||
|
||||
OpenTelemetry is an evolving specification, one where the desires and
|
||||
use cases are clear, but the method to satisfy those uses cases are
|
||||
not.
|
||||
|
||||
As such, Contributions should provide functionality and behavior that
|
||||
conforms to the specification, but the interface and structure is
|
||||
flexible.
|
||||
|
||||
It is preferable to have contributions follow the idioms of the
|
||||
language rather than conform to specific API names or argument
|
||||
patterns in the spec.
|
||||
|
||||
For a deeper discussion, see
|
||||
[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165).
|
||||
|
||||
## Documentation
|
||||
|
||||
Each non-example Go Module should have its own `README.md` containing:
|
||||
|
||||
- A pkg.go.dev badge which can be generated [here](https://pkg.go.dev/badge/).
|
||||
- Brief description.
|
||||
- Installation instructions (and requirements if applicable).
|
||||
- Hyperlink to an example. Depending on the component the example can be:
|
||||
- An `example_test.go` like [here](exporters/stdout/stdouttrace/example_test.go).
|
||||
- A sample Go application with its own `README.md`, like [here](example/zipkin).
|
||||
- Additional documentation sections such us:
|
||||
- Configuration,
|
||||
- Contributing,
|
||||
- References.
|
||||
|
||||
[Here](exporters/jaeger/README.md) is an example of a concise `README.md`.
|
||||
|
||||
Moreover, it should be possible to navigate to any `README.md` from the
|
||||
root `README.md`.
|
||||
|
||||
## Style Guide
|
||||
|
||||
One of the primary goals of this project is that it is actually used by
|
||||
developers. With this goal in mind the project strives to build
|
||||
user-friendly and idiomatic Go code adhering to the Go community's best
|
||||
practices.
|
||||
|
||||
For a non-comprehensive but foundational overview of these best practices
|
||||
the [Effective Go](https://golang.org/doc/effective_go.html) documentation
|
||||
is an excellent starting place.
|
||||
|
||||
As a convenience for developers building this project the `make precommit`
|
||||
will format, lint, validate, and in some cases fix the changes you plan to
|
||||
submit. This check will need to pass for your changes to be able to be
|
||||
merged.
|
||||
|
||||
In addition to idiomatic Go, the project has adopted certain standards for
|
||||
implementations of common patterns. These standards should be followed as a
|
||||
default, and if they are not followed documentation needs to be included as
|
||||
to the reasons why.
|
||||
|
||||
### Configuration
|
||||
|
||||
When creating an instantiation function for a complex `type T struct`, it is
|
||||
useful to allow variable number of options to be applied. However, the strong
|
||||
type system of Go restricts the function design options. There are a few ways
|
||||
to solve this problem, but we have landed on the following design.
|
||||
|
||||
#### `config`
|
||||
|
||||
Configuration should be held in a `struct` named `config`, or prefixed with
|
||||
specific type name this Configuration applies to if there are multiple
|
||||
`config` in the package. This type must contain configuration options.
|
||||
|
||||
```go
|
||||
// config contains configuration options for a thing.
|
||||
type config struct {
|
||||
// options ...
|
||||
}
|
||||
```
|
||||
|
||||
In general the `config` type will not need to be used externally to the
|
||||
package and should be unexported. If, however, it is expected that the user
|
||||
will likely want to build custom options for the configuration, the `config`
|
||||
should be exported. Please, include in the documentation for the `config`
|
||||
how the user can extend the configuration.
|
||||
|
||||
It is important that internal `config` are not shared across package boundaries.
|
||||
Meaning a `config` from one package should not be directly used by another. The
|
||||
one exception is the API packages. The configs from the base API, eg.
|
||||
`go.opentelemetry.io/otel/trace.TracerConfig` and
|
||||
`go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed
|
||||
by the SDK therefor it is expected that these are exported.
|
||||
|
||||
When a config is exported we want to maintain forward and backward
|
||||
compatibility, to achieve this no fields should be exported but should
|
||||
instead be accessed by methods.
|
||||
|
||||
Optionally, it is common to include a `newConfig` function (with the same
|
||||
naming scheme). This function wraps any defaults setting and looping over
|
||||
all options to create a configured `config`.
|
||||
|
||||
```go
|
||||
// newConfig returns an appropriately configured config.
|
||||
func newConfig(options ...Option) config {
|
||||
// Set default values for config.
|
||||
config := config{/* […] */}
|
||||
for _, option := range options {
|
||||
config = option.apply(config)
|
||||
}
|
||||
// Preform any validation here.
|
||||
return config
|
||||
}
|
||||
```
|
||||
|
||||
If validation of the `config` options is also preformed this can return an
|
||||
error as well that is expected to be handled by the instantiation function
|
||||
or propagated to the user.
|
||||
|
||||
Given the design goal of not having the user need to work with the `config`,
|
||||
the `newConfig` function should also be unexported.
|
||||
|
||||
#### `Option`
|
||||
|
||||
To set the value of the options a `config` contains, a corresponding
|
||||
`Option` interface type should be used.
|
||||
|
||||
```go
|
||||
type Option interface {
|
||||
apply(config) config
|
||||
}
|
||||
```
|
||||
|
||||
Having `apply` unexported makes sure that it will not be used externally.
|
||||
Moreover, the interface becomes sealed so the user cannot easily implement
|
||||
the interface on its own.
|
||||
|
||||
The `apply` method should return a modified version of the passed config.
|
||||
This approach, instead of passing a pointer, is used to prevent the config from being allocated to the heap.
|
||||
|
||||
The name of the interface should be prefixed in the same way the
|
||||
corresponding `config` is (if at all).
|
||||
|
||||
#### Options
|
||||
|
||||
All user configurable options for a `config` must have a related unexported
|
||||
implementation of the `Option` interface and an exported configuration
|
||||
function that wraps this implementation.
|
||||
|
||||
The wrapping function name should be prefixed with `With*` (or in the
|
||||
special case of a boolean options `Without*`) and should have the following
|
||||
function signature.
|
||||
|
||||
```go
|
||||
func With*(…) Option { … }
|
||||
```
|
||||
|
||||
##### `bool` Options
|
||||
|
||||
```go
|
||||
type defaultFalseOption bool
|
||||
|
||||
func (o defaultFalseOption) apply(c config) config {
|
||||
c.Bool = bool(o)
|
||||
return c
|
||||
}
|
||||
|
||||
// WithOption sets a T to have an option included.
|
||||
func WithOption() Option {
|
||||
return defaultFalseOption(true)
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
type defaultTrueOption bool
|
||||
|
||||
func (o defaultTrueOption) apply(c config) config {
|
||||
c.Bool = bool(o)
|
||||
return c
|
||||
}
|
||||
|
||||
// WithoutOption sets a T to have Bool option excluded.
|
||||
func WithoutOption() Option {
|
||||
return defaultTrueOption(false)
|
||||
}
|
||||
```
|
||||
|
||||
##### Declared Type Options
|
||||
|
||||
```go
|
||||
type myTypeOption struct {
|
||||
MyType MyType
|
||||
}
|
||||
|
||||
func (o myTypeOption) apply(c config) config {
|
||||
c.MyType = o.MyType
|
||||
return c
|
||||
}
|
||||
|
||||
// WithMyType sets T to have include MyType.
|
||||
func WithMyType(t MyType) Option {
|
||||
return myTypeOption{t}
|
||||
}
|
||||
```
|
||||
|
||||
##### Functional Options
|
||||
|
||||
```go
|
||||
type optionFunc func(config) config
|
||||
|
||||
func (fn optionFunc) apply(c config) config {
|
||||
return fn(c)
|
||||
}
|
||||
|
||||
// WithMyType sets t as MyType.
|
||||
func WithMyType(t MyType) Option {
|
||||
return optionFunc(func(c config) config {
|
||||
c.MyType = t
|
||||
return c
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
#### Instantiation
|
||||
|
||||
Using this configuration pattern to configure instantiation with a `NewT`
|
||||
function.
|
||||
|
||||
```go
|
||||
func NewT(options ...Option) T {…}
|
||||
```
|
||||
|
||||
Any required parameters can be declared before the variadic `options`.
|
||||
|
||||
#### Dealing with Overlap
|
||||
|
||||
Sometimes there are multiple complex `struct` that share common
|
||||
configuration and also have distinct configuration. To avoid repeated
|
||||
portions of `config`s, a common `config` can be used with the union of
|
||||
options being handled with the `Option` interface.
|
||||
|
||||
For example.
|
||||
|
||||
```go
|
||||
// config holds options for all animals.
|
||||
type config struct {
|
||||
Weight float64
|
||||
Color string
|
||||
MaxAltitude float64
|
||||
}
|
||||
|
||||
// DogOption apply Dog specific options.
|
||||
type DogOption interface {
|
||||
applyDog(config) config
|
||||
}
|
||||
|
||||
// BirdOption apply Bird specific options.
|
||||
type BirdOption interface {
|
||||
applyBird(config) config
|
||||
}
|
||||
|
||||
// Option apply options for all animals.
|
||||
type Option interface {
|
||||
BirdOption
|
||||
DogOption
|
||||
}
|
||||
|
||||
type weightOption float64
|
||||
|
||||
func (o weightOption) applyDog(c config) config {
|
||||
c.Weight = float64(o)
|
||||
return c
|
||||
}
|
||||
|
||||
func (o weightOption) applyBird(c config) config {
|
||||
c.Weight = float64(o)
|
||||
return c
|
||||
}
|
||||
|
||||
func WithWeight(w float64) Option { return weightOption(w) }
|
||||
|
||||
type furColorOption string
|
||||
|
||||
func (o furColorOption) applyDog(c config) config {
|
||||
c.Color = string(o)
|
||||
return c
|
||||
}
|
||||
|
||||
func WithFurColor(c string) DogOption { return furColorOption(c) }
|
||||
|
||||
type maxAltitudeOption float64
|
||||
|
||||
func (o maxAltitudeOption) applyBird(c config) config {
|
||||
c.MaxAltitude = float64(o)
|
||||
return c
|
||||
}
|
||||
|
||||
func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) }
|
||||
|
||||
func NewDog(name string, o ...DogOption) Dog {…}
|
||||
func NewBird(name string, o ...BirdOption) Bird {…}
|
||||
```
|
||||
|
||||
### Interfaces
|
||||
|
||||
To allow other developers to better comprehend the code, it is important
|
||||
to ensure it is sufficiently documented. One simple measure that contributes
|
||||
to this aim is self-documenting by naming method parameters. Therefore,
|
||||
where appropriate, methods of every exported interface type should have
|
||||
their parameters appropriately named.
|
||||
|
||||
#### Interface Stability
|
||||
|
||||
All exported stable interfaces that include the following warning in their
|
||||
doumentation are allowed to be extended with additional methods.
|
||||
|
||||
> Warning: methods may be added to this interface in minor releases.
|
||||
|
||||
Otherwise, stable interfaces MUST NOT be modified.
|
||||
|
||||
If new functionality is needed for an interface that cannot be changed it MUST
|
||||
be added by including an additional interface. That added interface can be a
|
||||
simple interface for the specific functionality that you want to add or it can
|
||||
be a super-set of the original interface. For example, if you wanted to a
|
||||
`Close` method to the `Exporter` interface:
|
||||
|
||||
```go
|
||||
type Exporter interface {
|
||||
Export()
|
||||
}
|
||||
```
|
||||
|
||||
A new interface, `Closer`, can be added:
|
||||
|
||||
```go
|
||||
type Closer interface {
|
||||
Close()
|
||||
}
|
||||
```
|
||||
|
||||
Code that is passed the `Exporter` interface can now check to see if the passed
|
||||
value also satisfies the new interface. E.g.
|
||||
|
||||
```go
|
||||
func caller(e Exporter) {
|
||||
/* ... */
|
||||
if c, ok := e.(Closer); ok {
|
||||
c.Close()
|
||||
}
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, a new type that is the super-set of an `Exporter` can be created.
|
||||
|
||||
```go
|
||||
type ClosingExporter struct {
|
||||
Exporter
|
||||
Close()
|
||||
}
|
||||
```
|
||||
|
||||
This new type can be used similar to the simple interface above in that a
|
||||
passed `Exporter` type can be asserted to satisfy the `ClosingExporter` type
|
||||
and the `Close` method called.
|
||||
|
||||
This super-set approach can be useful if there is explicit behavior that needs
|
||||
to be coupled with the original type and passed as a unified type to a new
|
||||
function, but, because of this coupling, it also limits the applicability of
|
||||
the added functionality. If there exist other interfaces where this
|
||||
functionality should be added, each one will need their own super-set
|
||||
interfaces and will duplicate the pattern. For this reason, the simple targeted
|
||||
interface that defines the specific functionality should be preferred.
|
||||
|
||||
## Approvers and Maintainers
|
||||
|
||||
Approvers:
|
||||
|
||||
- [Evan Torrie](https://github.com/evantorrie), Verizon Media
|
||||
- [Josh MacDonald](https://github.com/jmacd), LightStep
|
||||
- [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics
|
||||
- [David Ashpole](https://github.com/dashpole), Google
|
||||
- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
|
||||
- [Robert Pająk](https://github.com/pellared), Splunk
|
||||
- [Chester Cheung](https://github.com/hanyuancheung), Tencent
|
||||
|
||||
Maintainers:
|
||||
|
||||
- [Aaron Clawson](https://github.com/MadVikingGod), LightStep
|
||||
- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
|
||||
- [Tyler Yahn](https://github.com/MrAlias), Splunk
|
||||
|
||||
### Become an Approver or a Maintainer
|
||||
|
||||
See the [community membership document in OpenTelemetry community
|
||||
repo](https://github.com/open-telemetry/community/blob/main/community-membership.md).
|
201
vendor/go.opentelemetry.io/otel/LICENSE
generated
vendored
Normal file
201
vendor/go.opentelemetry.io/otel/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.
|
209
vendor/go.opentelemetry.io/otel/Makefile
generated
vendored
Normal file
209
vendor/go.opentelemetry.io/otel/Makefile
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
# 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.
|
||||
|
||||
TOOLS_MOD_DIR := ./internal/tools
|
||||
|
||||
ALL_DOCS := $(shell find . -name '*.md' -type f | sort)
|
||||
ALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)
|
||||
OTEL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(ALL_GO_MOD_DIRS))
|
||||
ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example|^$(TOOLS_MOD_DIR)' | sort)
|
||||
|
||||
GO = go
|
||||
TIMEOUT = 60
|
||||
|
||||
.DEFAULT_GOAL := precommit
|
||||
|
||||
.PHONY: precommit ci
|
||||
precommit: dependabot-generate license-check misspell go-mod-tidy golangci-lint-fix test-default
|
||||
ci: dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage
|
||||
|
||||
# Tools
|
||||
|
||||
TOOLS = $(CURDIR)/.tools
|
||||
|
||||
$(TOOLS):
|
||||
@mkdir -p $@
|
||||
$(TOOLS)/%: | $(TOOLS)
|
||||
cd $(TOOLS_MOD_DIR) && \
|
||||
$(GO) build -o $@ $(PACKAGE)
|
||||
|
||||
MULTIMOD = $(TOOLS)/multimod
|
||||
$(TOOLS)/multimod: PACKAGE=go.opentelemetry.io/build-tools/multimod
|
||||
|
||||
SEMCONVGEN = $(TOOLS)/semconvgen
|
||||
$(TOOLS)/semconvgen: PACKAGE=go.opentelemetry.io/build-tools/semconvgen
|
||||
|
||||
CROSSLINK = $(TOOLS)/crosslink
|
||||
$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink
|
||||
|
||||
DBOTCONF = $(TOOLS)/dbotconf
|
||||
$(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/build-tools/dbotconf
|
||||
|
||||
GOLANGCI_LINT = $(TOOLS)/golangci-lint
|
||||
$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
|
||||
MISSPELL = $(TOOLS)/misspell
|
||||
$(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell
|
||||
|
||||
GOCOVMERGE = $(TOOLS)/gocovmerge
|
||||
$(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge
|
||||
|
||||
STRINGER = $(TOOLS)/stringer
|
||||
$(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer
|
||||
|
||||
PORTO = $(TOOLS)/porto
|
||||
$(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto
|
||||
|
||||
GOJQ = $(TOOLS)/gojq
|
||||
$(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq
|
||||
|
||||
.PHONY: tools
|
||||
tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD)
|
||||
|
||||
# Build
|
||||
|
||||
.PHONY: generate build
|
||||
|
||||
generate: $(OTEL_GO_MOD_DIRS:%=generate/%)
|
||||
generate/%: DIR=$*
|
||||
generate/%: | $(STRINGER) $(PORTO)
|
||||
@echo "$(GO) generate $(DIR)/..." \
|
||||
&& cd $(DIR) \
|
||||
&& PATH="$(TOOLS):$${PATH}" $(GO) generate ./... && $(PORTO) -w .
|
||||
|
||||
build: generate $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%)
|
||||
build/%: DIR=$*
|
||||
build/%:
|
||||
@echo "$(GO) build $(DIR)/..." \
|
||||
&& cd $(DIR) \
|
||||
&& $(GO) build ./...
|
||||
|
||||
build-tests/%: DIR=$*
|
||||
build-tests/%:
|
||||
@echo "$(GO) build tests $(DIR)/..." \
|
||||
&& cd $(DIR) \
|
||||
&& $(GO) list ./... \
|
||||
| grep -v third_party \
|
||||
| xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null
|
||||
|
||||
# Tests
|
||||
|
||||
TEST_TARGETS := test-default test-bench test-short test-verbose test-race
|
||||
.PHONY: $(TEST_TARGETS) test
|
||||
test-default test-race: ARGS=-race
|
||||
test-bench: ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=.
|
||||
test-short: ARGS=-short
|
||||
test-verbose: ARGS=-v -race
|
||||
$(TEST_TARGETS): test
|
||||
test: $(OTEL_GO_MOD_DIRS:%=test/%)
|
||||
test/%: DIR=$*
|
||||
test/%:
|
||||
@echo "$(GO) test -timeout $(TIMEOUT)s $(ARGS) $(DIR)/..." \
|
||||
&& cd $(DIR) \
|
||||
&& $(GO) list ./... \
|
||||
| grep -v third_party \
|
||||
| xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS)
|
||||
|
||||
COVERAGE_MODE = atomic
|
||||
COVERAGE_PROFILE = coverage.out
|
||||
.PHONY: test-coverage
|
||||
test-coverage: | $(GOCOVMERGE)
|
||||
@set -e; \
|
||||
printf "" > coverage.txt; \
|
||||
for dir in $(ALL_COVERAGE_MOD_DIRS); do \
|
||||
echo "$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \
|
||||
(cd "$${dir}" && \
|
||||
$(GO) list ./... \
|
||||
| grep -v third_party \
|
||||
| xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \
|
||||
$(GO) tool cover -html=coverage.out -o coverage.html); \
|
||||
done; \
|
||||
$(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt
|
||||
|
||||
.PHONY: golangci-lint golangci-lint-fix
|
||||
golangci-lint-fix: ARGS=--fix
|
||||
golangci-lint-fix: golangci-lint
|
||||
golangci-lint: $(OTEL_GO_MOD_DIRS:%=golangci-lint/%)
|
||||
golangci-lint/%: DIR=$*
|
||||
golangci-lint/%: | $(GOLANGCI_LINT)
|
||||
@echo 'golangci-lint $(if $(ARGS),$(ARGS) ,)$(DIR)' \
|
||||
&& cd $(DIR) \
|
||||
&& $(GOLANGCI_LINT) run --allow-serial-runners $(ARGS)
|
||||
|
||||
.PHONY: crosslink
|
||||
crosslink: | $(CROSSLINK)
|
||||
@echo "cross-linking all go modules" \
|
||||
&& $(CROSSLINK)
|
||||
|
||||
.PHONY: go-mod-tidy
|
||||
go-mod-tidy: $(ALL_GO_MOD_DIRS:%=go-mod-tidy/%)
|
||||
go-mod-tidy/%: DIR=$*
|
||||
go-mod-tidy/%: | crosslink
|
||||
@echo "$(GO) mod tidy in $(DIR)" \
|
||||
&& cd $(DIR) \
|
||||
&& $(GO) mod tidy
|
||||
|
||||
.PHONY: lint-modules
|
||||
lint-modules: go-mod-tidy
|
||||
|
||||
.PHONY: lint
|
||||
lint: misspell lint-modules golangci-lint
|
||||
|
||||
.PHONY: vanity-import-check
|
||||
vanity-import-check: | $(PORTO)
|
||||
@$(PORTO) --include-internal -l .
|
||||
|
||||
.PHONY: misspell
|
||||
misspell: | $(MISSPELL)
|
||||
@$(MISSPELL) -w $(ALL_DOCS)
|
||||
|
||||
.PHONY: license-check
|
||||
license-check:
|
||||
@licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*') ; do \
|
||||
awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \
|
||||
done); \
|
||||
if [ -n "$${licRes}" ]; then \
|
||||
echo "license header checking failed:"; echo "$${licRes}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
DEPENDABOT_CONFIG = .github/dependabot.yml
|
||||
.PHONY: dependabot-check
|
||||
dependabot-check: | $(DBOTCONF)
|
||||
@$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || echo "(run: make dependabot-generate)"
|
||||
|
||||
.PHONY: dependabot-generate
|
||||
dependabot-generate: | $(DBOTCONF)
|
||||
@$(DBOTCONF) generate > $(DEPENDABOT_CONFIG)
|
||||
|
||||
.PHONY: check-clean-work-tree
|
||||
check-clean-work-tree:
|
||||
@if ! git diff --quiet; then \
|
||||
echo; \
|
||||
echo 'Working tree is not clean, did you forget to run "make precommit"?'; \
|
||||
echo; \
|
||||
git status; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: prerelease
|
||||
prerelease: | $(MULTIMOD)
|
||||
@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
|
||||
$(MULTIMOD) verify && $(MULTIMOD) prerelease -m ${MODSET}
|
||||
|
||||
COMMIT ?= "HEAD"
|
||||
.PHONY: add-tags
|
||||
add-tags: | $(MULTIMOD)
|
||||
@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
|
||||
$(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}
|
108
vendor/go.opentelemetry.io/otel/README.md
generated
vendored
Normal file
108
vendor/go.opentelemetry.io/otel/README.md
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
# OpenTelemetry-Go
|
||||
|
||||
[](https://github.com/open-telemetry/opentelemetry-go/actions?query=workflow%3Aci+branch%3Amain)
|
||||
[](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main)
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel)
|
||||
[](https://goreportcard.com/report/go.opentelemetry.io/otel)
|
||||
[](https://cloud-native.slack.com/archives/C01NPAXACKT)
|
||||
|
||||
OpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).
|
||||
It provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms.
|
||||
|
||||
## Project Status
|
||||
|
||||
| Signal | Status | Project |
|
||||
| ------- | ---------- | ------- |
|
||||
| Traces | Stable | N/A |
|
||||
| Metrics | Alpha | N/A |
|
||||
| Logs | Frozen [1] | N/A |
|
||||
|
||||
- [1]: The Logs signal development is halted for this project while we develop both Traces and Metrics.
|
||||
No Logs Pull Requests are currently being accepted.
|
||||
|
||||
Progress and status specific to this repository is tracked in our local
|
||||
[project boards](https://github.com/open-telemetry/opentelemetry-go/projects)
|
||||
and
|
||||
[milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).
|
||||
|
||||
Project versioning information and stability guarantees can be found in the
|
||||
[versioning documentation](./VERSIONING.md).
|
||||
|
||||
### Compatibility
|
||||
|
||||
OpenTelemetry-Go attempts to track the current supported versions of the
|
||||
[Go language](https://golang.org/doc/devel/release#policy). The release
|
||||
schedule after a new minor version of go is as follows:
|
||||
|
||||
- The first release or one month, which ever is sooner, will add build steps for the new go version.
|
||||
- The first release after three months will remove support for the oldest go version.
|
||||
|
||||
This project is tested on the following systems.
|
||||
|
||||
| OS | Go Version | Architecture |
|
||||
| ------- | ---------- | ------------ |
|
||||
| Ubuntu | 1.18 | amd64 |
|
||||
| Ubuntu | 1.17 | amd64 |
|
||||
| Ubuntu | 1.16 | amd64 |
|
||||
| Ubuntu | 1.18 | 386 |
|
||||
| Ubuntu | 1.17 | 386 |
|
||||
| Ubuntu | 1.16 | 386 |
|
||||
| MacOS | 1.18 | amd64 |
|
||||
| MacOS | 1.17 | amd64 |
|
||||
| MacOS | 1.16 | amd64 |
|
||||
| Windows | 1.18 | amd64 |
|
||||
| Windows | 1.17 | amd64 |
|
||||
| Windows | 1.16 | amd64 |
|
||||
| Windows | 1.18 | 386 |
|
||||
| Windows | 1.17 | 386 |
|
||||
| Windows | 1.16 | 386 |
|
||||
|
||||
While this project should work for other systems, no compatibility guarantees
|
||||
are made for those systems currently.
|
||||
|
||||
Go 1.18 was added in March of 2022.
|
||||
Go 1.16 will be removed around June 2022.
|
||||
|
||||
## Getting Started
|
||||
|
||||
You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/go/getting-started/).
|
||||
|
||||
OpenTelemetry's goal is to provide a single set of APIs to capture distributed
|
||||
traces and metrics from your application and send them to an observability
|
||||
platform. This project allows you to do just that for applications written in
|
||||
Go. There are two steps to this process: instrument your application, and
|
||||
configure an exporter.
|
||||
|
||||
### Instrumentation
|
||||
|
||||
To start capturing distributed traces and metric events from your application
|
||||
it first needs to be instrumented. The easiest way to do this is by using an
|
||||
instrumentation library for your code. Be sure to check out [the officially
|
||||
supported instrumentation
|
||||
libraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation).
|
||||
|
||||
If you need to extend the telemetry an instrumentation library provides or want
|
||||
to build your own instrumentation for your application directly you will need
|
||||
to use the
|
||||
[Go otel](https://pkg.go.dev/go.opentelemetry.io/otel)
|
||||
package. The included [examples](./example/) are a good way to see some
|
||||
practical uses of this process.
|
||||
|
||||
### Export
|
||||
|
||||
Now that your application is instrumented to collect telemetry, it needs an
|
||||
export pipeline to send that telemetry to an observability platform.
|
||||
|
||||
All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).
|
||||
|
||||
| Exporter | Metrics | Traces |
|
||||
| :-----------------------------------: | :-----: | :----: |
|
||||
| [Jaeger](./exporters/jaeger/) | | ✓ |
|
||||
| [OTLP](./exporters/otlp/) | ✓ | ✓ |
|
||||
| [Prometheus](./exporters/prometheus/) | ✓ | |
|
||||
| [stdout](./exporters/stdout/) | ✓ | ✓ |
|
||||
| [Zipkin](./exporters/zipkin/) | | ✓ |
|
||||
|
||||
## Contributing
|
||||
|
||||
See the [contributing documentation](CONTRIBUTING.md).
|
132
vendor/go.opentelemetry.io/otel/RELEASING.md
generated
vendored
Normal file
132
vendor/go.opentelemetry.io/otel/RELEASING.md
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
# Release Process
|
||||
|
||||
## Semantic Convention Generation
|
||||
|
||||
If a new version of the OpenTelemetry Specification has been released it will be necessary to generate a new
|
||||
semantic convention package from the YAML definitions in the specification repository. There is a `semconvgen` utility
|
||||
installed by `make tools` that can be used to generate the a package with the name matching the specification
|
||||
version number under the `semconv` package. This will ideally be done soon after the specification release is
|
||||
tagged. Make sure that the specification repo contains a checkout of the the latest tagged release so that the
|
||||
generated files match the released semantic conventions.
|
||||
|
||||
There are currently two categories of semantic conventions that must be generated, `resource` and `trace`.
|
||||
|
||||
```
|
||||
.tools/semconvgen -i /path/to/specification/repo/semantic_conventions/resource -t semconv/template.j2
|
||||
.tools/semconvgen -i /path/to/specification/repo/semantic_conventions/trace -t semconv/template.j2
|
||||
```
|
||||
|
||||
Using default values for all options other than `input` will result in using the `template.j2` template to
|
||||
generate `resource.go` and `trace.go` in `/path/to/otelgo/repo/semconv/<version>`.
|
||||
|
||||
There are several ancillary files that are not generated and should be copied into the new package from the
|
||||
prior package, with updates made as appropriate to canonical import path statements and constant values.
|
||||
These files include:
|
||||
|
||||
* doc.go
|
||||
* exception.go
|
||||
* http(_test)?.go
|
||||
* schema.go
|
||||
|
||||
Uses of the previous schema version in this repository should be updated to use the newly generated version.
|
||||
No tooling for this exists at present, so use find/replace in your editor of choice or craft a `grep | sed`
|
||||
pipeline if you like living on the edge.
|
||||
|
||||
## Pre-Release
|
||||
|
||||
First, decide which module sets will be released and update their versions
|
||||
in `versions.yaml`. Commit this change to a new branch.
|
||||
|
||||
Update go.mod for submodules to depend on the new release which will happen in the next step.
|
||||
|
||||
1. Run the `prerelease` make target. It creates a branch
|
||||
`prerelease_<module set>_<new tag>` that will contain all release changes.
|
||||
|
||||
```
|
||||
make prerelease MODSET=<module set>
|
||||
```
|
||||
|
||||
2. Verify the changes.
|
||||
|
||||
```
|
||||
git diff ...prerelease_<module set>_<new tag>
|
||||
```
|
||||
|
||||
This should have changed the version for all modules to be `<new tag>`.
|
||||
If these changes look correct, merge them into your pre-release branch:
|
||||
|
||||
```go
|
||||
git merge prerelease_<module set>_<new tag>
|
||||
```
|
||||
|
||||
3. Update the [Changelog](./CHANGELOG.md).
|
||||
- Make sure all relevant changes for this release are included and are in language that non-contributors to the project can understand.
|
||||
To verify this, you can look directly at the commits since the `<last tag>`.
|
||||
|
||||
```
|
||||
git --no-pager log --pretty=oneline "<last tag>..HEAD"
|
||||
```
|
||||
|
||||
- Move all the `Unreleased` changes into a new section following the title scheme (`[<new tag>] - <date of release>`).
|
||||
- Update all the appropriate links at the bottom.
|
||||
|
||||
4. Push the changes to upstream and create a Pull Request on GitHub.
|
||||
Be sure to include the curated changes from the [Changelog](./CHANGELOG.md) in the description.
|
||||
|
||||
## Tag
|
||||
|
||||
Once the Pull Request with all the version changes has been approved and merged it is time to tag the merged commit.
|
||||
|
||||
***IMPORTANT***: It is critical you use the same tag that you used in the Pre-Release step!
|
||||
Failure to do so will leave things in a broken state. As long as you do not
|
||||
change `versions.yaml` between pre-release and this step, things should be fine.
|
||||
|
||||
***IMPORTANT***: [There is currently no way to remove an incorrectly tagged version of a Go module](https://github.com/golang/go/issues/34189).
|
||||
It is critical you make sure the version you push upstream is correct.
|
||||
[Failure to do so will lead to minor emergencies and tough to work around](https://github.com/open-telemetry/opentelemetry-go/issues/331).
|
||||
|
||||
1. For each module set that will be released, run the `add-tags` make target
|
||||
using the `<commit-hash>` of the commit on the main branch for the merged Pull Request.
|
||||
|
||||
```
|
||||
make add-tags MODSET=<module set> COMMIT=<commit hash>
|
||||
```
|
||||
|
||||
It should only be necessary to provide an explicit `COMMIT` value if the
|
||||
current `HEAD` of your working directory is not the correct commit.
|
||||
|
||||
2. Push tags to the upstream remote (not your fork: `github.com/open-telemetry/opentelemetry-go.git`).
|
||||
Make sure you push all sub-modules as well.
|
||||
|
||||
```
|
||||
git push upstream <new tag>
|
||||
git push upstream <submodules-path/new tag>
|
||||
...
|
||||
```
|
||||
|
||||
## Release
|
||||
|
||||
Finally create a Release for the new `<new tag>` on GitHub.
|
||||
The release body should include all the release notes from the Changelog for this release.
|
||||
|
||||
## Verify Examples
|
||||
|
||||
After releasing verify that examples build outside of the repository.
|
||||
|
||||
```
|
||||
./verify_examples.sh
|
||||
```
|
||||
|
||||
The script copies examples into a different directory removes any `replace` declarations in `go.mod` and builds them.
|
||||
This ensures they build with the published release, not the local copy.
|
||||
|
||||
## Post-Release
|
||||
|
||||
### Contrib Repository
|
||||
|
||||
Once verified be sure to [make a release for the `contrib` repository](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md) that uses this release.
|
||||
|
||||
### Website Documentation
|
||||
|
||||
Update [the documentation](./website_docs) for [the OpenTelemetry website](https://opentelemetry.io/docs/go/).
|
||||
Importantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate.
|
224
vendor/go.opentelemetry.io/otel/VERSIONING.md
generated
vendored
Normal file
224
vendor/go.opentelemetry.io/otel/VERSIONING.md
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
# Versioning
|
||||
|
||||
This document describes the versioning policy for this repository. This policy
|
||||
is designed so the following goals can be achieved.
|
||||
|
||||
**Users are provided a codebase of value that is stable and secure.**
|
||||
|
||||
## Policy
|
||||
|
||||
* Versioning of this project will be idiomatic of a Go project using [Go
|
||||
modules](https://github.com/golang/go/wiki/Modules).
|
||||
* [Semantic import
|
||||
versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)
|
||||
will be used.
|
||||
* Versions will comply with [semver
|
||||
2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions.
|
||||
* New methods may be added to exported API interfaces. All exported
|
||||
interfaces that fall within this exception will include the following
|
||||
paragraph in their public documentation.
|
||||
|
||||
> Warning: methods may be added to this interface in minor releases.
|
||||
|
||||
* If a module is version `v2` or higher, the major version of the module
|
||||
must be included as a `/vN` at the end of the module paths used in
|
||||
`go.mod` files (e.g., `module go.opentelemetry.io/otel/v2`, `require
|
||||
go.opentelemetry.io/otel/v2 v2.0.1`) and in the package import path
|
||||
(e.g., `import "go.opentelemetry.io/otel/v2/trace"`). This includes the
|
||||
paths used in `go get` commands (e.g., `go get
|
||||
go.opentelemetry.io/otel/v2@v2.0.1`. Note there is both a `/v2` and a
|
||||
`@v2.0.1` in that example. One way to think about it is that the module
|
||||
name now includes the `/v2`, so include `/v2` whenever you are using the
|
||||
module name).
|
||||
* If a module is version `v0` or `v1`, do not include the major version in
|
||||
either the module path or the import path.
|
||||
* Modules will be used to encapsulate signals and components.
|
||||
* Experimental modules still under active development will be versioned at
|
||||
`v0` to imply the stability guarantee defined by
|
||||
[semver](https://semver.org/spec/v2.0.0.html#spec-item-4).
|
||||
|
||||
> Major version zero (0.y.z) is for initial development. Anything MAY
|
||||
> change at any time. The public API SHOULD NOT be considered stable.
|
||||
|
||||
* Mature modules for which we guarantee a stable public API will be versioned
|
||||
with a major version greater than `v0`.
|
||||
* The decision to make a module stable will be made on a case-by-case
|
||||
basis by the maintainers of this project.
|
||||
* Experimental modules will start their versioning at `v0.0.0` and will
|
||||
increment their minor version when backwards incompatible changes are
|
||||
released and increment their patch version when backwards compatible
|
||||
changes are released.
|
||||
* All stable modules that use the same major version number will use the
|
||||
same entire version number.
|
||||
* Stable modules may be released with an incremented minor or patch
|
||||
version even though that module has not been changed, but rather so
|
||||
that it will remain at the same version as other stable modules that
|
||||
did undergo change.
|
||||
* When an experimental module becomes stable a new stable module version
|
||||
will be released and will include this now stable module. The new
|
||||
stable module version will be an increment of the minor version number
|
||||
and will be applied to all existing stable modules as well as the newly
|
||||
stable module being released.
|
||||
* Versioning of the associated [contrib
|
||||
repository](https://github.com/open-telemetry/opentelemetry-go-contrib) of
|
||||
this project will be idiomatic of a Go project using [Go
|
||||
modules](https://github.com/golang/go/wiki/Modules).
|
||||
* [Semantic import
|
||||
versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)
|
||||
will be used.
|
||||
* Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html).
|
||||
* If a module is version `v2` or higher, the
|
||||
major version of the module must be included as a `/vN` at the end of the
|
||||
module paths used in `go.mod` files (e.g., `module
|
||||
go.opentelemetry.io/contrib/instrumentation/host/v2`, `require
|
||||
go.opentelemetry.io/contrib/instrumentation/host/v2 v2.0.1`) and in the
|
||||
package import path (e.g., `import
|
||||
"go.opentelemetry.io/contrib/instrumentation/host/v2"`). This includes
|
||||
the paths used in `go get` commands (e.g., `go get
|
||||
go.opentelemetry.io/contrib/instrumentation/host/v2@v2.0.1`. Note there
|
||||
is both a `/v2` and a `@v2.0.1` in that example. One way to think about
|
||||
it is that the module name now includes the `/v2`, so include `/v2`
|
||||
whenever you are using the module name).
|
||||
* If a module is version `v0` or `v1`, do not include the major version
|
||||
in either the module path or the import path.
|
||||
* In addition to public APIs, telemetry produced by stable instrumentation
|
||||
will remain stable and backwards compatible. This is to avoid breaking
|
||||
alerts and dashboard.
|
||||
* Modules will be used to encapsulate instrumentation, detectors, exporters,
|
||||
propagators, and any other independent sets of related components.
|
||||
* Experimental modules still under active development will be versioned at
|
||||
`v0` to imply the stability guarantee defined by
|
||||
[semver](https://semver.org/spec/v2.0.0.html#spec-item-4).
|
||||
|
||||
> Major version zero (0.y.z) is for initial development. Anything MAY
|
||||
> change at any time. The public API SHOULD NOT be considered stable.
|
||||
|
||||
* Mature modules for which we guarantee a stable public API and telemetry will
|
||||
be versioned with a major version greater than `v0`.
|
||||
* Experimental modules will start their versioning at `v0.0.0` and will
|
||||
increment their minor version when backwards incompatible changes are
|
||||
released and increment their patch version when backwards compatible
|
||||
changes are released.
|
||||
* Stable contrib modules cannot depend on experimental modules from this
|
||||
project.
|
||||
* All stable contrib modules of the same major version with this project
|
||||
will use the same entire version as this project.
|
||||
* Stable modules may be released with an incremented minor or patch
|
||||
version even though that module's code has not been changed. Instead
|
||||
the only change that will have been included is to have updated that
|
||||
modules dependency on this project's stable APIs.
|
||||
* When an experimental module in contrib becomes stable a new stable
|
||||
module version will be released and will include this now stable
|
||||
module. The new stable module version will be an increment of the minor
|
||||
version number and will be applied to all existing stable contrib
|
||||
modules, this project's modules, and the newly stable module being
|
||||
released.
|
||||
* Contrib modules will be kept up to date with this project's releases.
|
||||
* Due to the dependency contrib modules will implicitly have on this
|
||||
project's modules the release of stable contrib modules to match the
|
||||
released version number will be staggered after this project's release.
|
||||
There is no explicit time guarantee for how long after this projects
|
||||
release the contrib release will be. Effort should be made to keep them
|
||||
as close in time as possible.
|
||||
* No additional stable release in this project can be made until the
|
||||
contrib repository has a matching stable release.
|
||||
* No release can be made in the contrib repository after this project's
|
||||
stable release except for a stable release of the contrib repository.
|
||||
* GitHub releases will be made for all releases.
|
||||
* Go modules will be made available at Go package mirrors.
|
||||
|
||||
## Example Versioning Lifecycle
|
||||
|
||||
To better understand the implementation of the above policy the following
|
||||
example is provided. This project is simplified to include only the following
|
||||
modules and their versions:
|
||||
|
||||
* `otel`: `v0.14.0`
|
||||
* `otel/trace`: `v0.14.0`
|
||||
* `otel/metric`: `v0.14.0`
|
||||
* `otel/baggage`: `v0.14.0`
|
||||
* `otel/sdk/trace`: `v0.14.0`
|
||||
* `otel/sdk/metric`: `v0.14.0`
|
||||
|
||||
These modules have been developed to a point where the `otel/trace`,
|
||||
`otel/baggage`, and `otel/sdk/trace` modules have reached a point that they
|
||||
should be considered for a stable release. The `otel/metric` and
|
||||
`otel/sdk/metric` are still under active development and the `otel` module
|
||||
depends on both `otel/trace` and `otel/metric`.
|
||||
|
||||
The `otel` package is refactored to remove its dependencies on `otel/metric` so
|
||||
it can be released as stable as well. With that done the following release
|
||||
candidates are made:
|
||||
|
||||
* `otel`: `v1.0.0-RC1`
|
||||
* `otel/trace`: `v1.0.0-RC1`
|
||||
* `otel/baggage`: `v1.0.0-RC1`
|
||||
* `otel/sdk/trace`: `v1.0.0-RC1`
|
||||
|
||||
The `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`.
|
||||
|
||||
A few minor issues are discovered in the `otel/trace` package. These issues are
|
||||
resolved with some minor, but backwards incompatible, changes and are released
|
||||
as a second release candidate:
|
||||
|
||||
* `otel`: `v1.0.0-RC2`
|
||||
* `otel/trace`: `v1.0.0-RC2`
|
||||
* `otel/baggage`: `v1.0.0-RC2`
|
||||
* `otel/sdk/trace`: `v1.0.0-RC2`
|
||||
|
||||
Notice that all module version numbers are incremented to adhere to our
|
||||
versioning policy.
|
||||
|
||||
After these release candidates have been evaluated to satisfaction, they are
|
||||
released as version `v1.0.0`.
|
||||
|
||||
* `otel`: `v1.0.0`
|
||||
* `otel/trace`: `v1.0.0`
|
||||
* `otel/baggage`: `v1.0.0`
|
||||
* `otel/sdk/trace`: `v1.0.0`
|
||||
|
||||
Since both the `go` utility and the Go module system support [the semantic
|
||||
versioning definition of
|
||||
precedence](https://semver.org/spec/v2.0.0.html#spec-item-11), this release
|
||||
will correctly be interpreted as the successor to the previous release
|
||||
candidates.
|
||||
|
||||
Active development of this project continues. The `otel/metric` module now has
|
||||
backwards incompatible changes to its API that need to be released and the
|
||||
`otel/baggage` module has a minor bug fix that needs to be released. The
|
||||
following release is made:
|
||||
|
||||
* `otel`: `v1.0.1`
|
||||
* `otel/trace`: `v1.0.1`
|
||||
* `otel/metric`: `v0.15.0`
|
||||
* `otel/baggage`: `v1.0.1`
|
||||
* `otel/sdk/trace`: `v1.0.1`
|
||||
* `otel/sdk/metric`: `v0.15.0`
|
||||
|
||||
Notice that, again, all stable module versions are incremented in unison and
|
||||
the `otel/sdk/metric` package, which depends on the `otel/metric` package, also
|
||||
bumped its version. This bump of the `otel/sdk/metric` package makes sense
|
||||
given their coupling, though it is not explicitly required by our versioning
|
||||
policy.
|
||||
|
||||
As we progress, the `otel/metric` and `otel/sdk/metric` packages have reached a
|
||||
point where they should be evaluated for stability. The `otel` module is
|
||||
reintegrated with the `otel/metric` package and the following release is made:
|
||||
|
||||
* `otel`: `v1.1.0-RC1`
|
||||
* `otel/trace`: `v1.1.0-RC1`
|
||||
* `otel/metric`: `v1.1.0-RC1`
|
||||
* `otel/baggage`: `v1.1.0-RC1`
|
||||
* `otel/sdk/trace`: `v1.1.0-RC1`
|
||||
* `otel/sdk/metric`: `v1.1.0-RC1`
|
||||
|
||||
All the modules are evaluated and determined to a viable stable release. They
|
||||
are then released as version `v1.1.0` (the minor version is incremented to
|
||||
indicate the addition of new signal).
|
||||
|
||||
* `otel`: `v1.1.0`
|
||||
* `otel/trace`: `v1.1.0`
|
||||
* `otel/metric`: `v1.1.0`
|
||||
* `otel/baggage`: `v1.1.0`
|
||||
* `otel/sdk/trace`: `v1.1.0`
|
||||
* `otel/sdk/metric`: `v1.1.0`
|
16
vendor/go.opentelemetry.io/otel/attribute/doc.go
generated
vendored
Normal file
16
vendor/go.opentelemetry.io/otel/attribute/doc.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// 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 attribute provides key and value attributes.
|
||||
package attribute // import "go.opentelemetry.io/otel/attribute"
|
150
vendor/go.opentelemetry.io/otel/attribute/encoder.go
generated
vendored
Normal file
150
vendor/go.opentelemetry.io/otel/attribute/encoder.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
// 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 attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type (
|
||||
// Encoder is a mechanism for serializing a label set into a
|
||||
// specific string representation that supports caching, to
|
||||
// avoid repeated serialization. An example could be an
|
||||
// exporter encoding the label set into a wire representation.
|
||||
Encoder interface {
|
||||
// Encode returns the serialized encoding of the label
|
||||
// set using its Iterator. This result may be cached
|
||||
// by a attribute.Set.
|
||||
Encode(iterator Iterator) string
|
||||
|
||||
// ID returns a value that is unique for each class of
|
||||
// label encoder. Label encoders allocate these using
|
||||
// `NewEncoderID`.
|
||||
ID() EncoderID
|
||||
}
|
||||
|
||||
// EncoderID is used to identify distinct Encoder
|
||||
// implementations, for caching encoded results.
|
||||
EncoderID struct {
|
||||
value uint64
|
||||
}
|
||||
|
||||
// defaultLabelEncoder uses a sync.Pool of buffers to reduce
|
||||
// the number of allocations used in encoding labels. This
|
||||
// implementation encodes a comma-separated list of key=value,
|
||||
// with '/'-escaping of '=', ',', and '\'.
|
||||
defaultLabelEncoder struct {
|
||||
// pool is a pool of labelset builders. The buffers in this
|
||||
// pool grow to a size that most label encodings will not
|
||||
// allocate new memory.
|
||||
pool sync.Pool // *bytes.Buffer
|
||||
}
|
||||
)
|
||||
|
||||
// escapeChar is used to ensure uniqueness of the label encoding where
|
||||
// keys or values contain either '=' or ','. Since there is no parser
|
||||
// needed for this encoding and its only requirement is to be unique,
|
||||
// this choice is arbitrary. Users will see these in some exporters
|
||||
// (e.g., stdout), so the backslash ('\') is used as a conventional choice.
|
||||
const escapeChar = '\\'
|
||||
|
||||
var (
|
||||
_ Encoder = &defaultLabelEncoder{}
|
||||
|
||||
// encoderIDCounter is for generating IDs for other label
|
||||
// encoders.
|
||||
encoderIDCounter uint64
|
||||
|
||||
defaultEncoderOnce sync.Once
|
||||
defaultEncoderID = NewEncoderID()
|
||||
defaultEncoderInstance *defaultLabelEncoder
|
||||
)
|
||||
|
||||
// NewEncoderID returns a unique label encoder ID. It should be
|
||||
// called once per each type of label encoder. Preferably in init() or
|
||||
// in var definition.
|
||||
func NewEncoderID() EncoderID {
|
||||
return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}
|
||||
}
|
||||
|
||||
// DefaultEncoder returns a label encoder that encodes labels
|
||||
// in such a way that each escaped label's key is followed by an equal
|
||||
// sign and then by an escaped label's value. All key-value pairs are
|
||||
// separated by a comma.
|
||||
//
|
||||
// Escaping is done by prepending a backslash before either a
|
||||
// backslash, equal sign or a comma.
|
||||
func DefaultEncoder() Encoder {
|
||||
defaultEncoderOnce.Do(func() {
|
||||
defaultEncoderInstance = &defaultLabelEncoder{
|
||||
pool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &bytes.Buffer{}
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
return defaultEncoderInstance
|
||||
}
|
||||
|
||||
// Encode is a part of an implementation of the LabelEncoder
|
||||
// interface.
|
||||
func (d *defaultLabelEncoder) Encode(iter Iterator) string {
|
||||
buf := d.pool.Get().(*bytes.Buffer)
|
||||
defer d.pool.Put(buf)
|
||||
buf.Reset()
|
||||
|
||||
for iter.Next() {
|
||||
i, keyValue := iter.IndexedLabel()
|
||||
if i > 0 {
|
||||
_, _ = buf.WriteRune(',')
|
||||
}
|
||||
copyAndEscape(buf, string(keyValue.Key))
|
||||
|
||||
_, _ = buf.WriteRune('=')
|
||||
|
||||
if keyValue.Value.Type() == STRING {
|
||||
copyAndEscape(buf, keyValue.Value.AsString())
|
||||
} else {
|
||||
_, _ = buf.WriteString(keyValue.Value.Emit())
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// ID is a part of an implementation of the LabelEncoder interface.
|
||||
func (*defaultLabelEncoder) ID() EncoderID {
|
||||
return defaultEncoderID
|
||||
}
|
||||
|
||||
// copyAndEscape escapes `=`, `,` and its own escape character (`\`),
|
||||
// making the default encoding unique.
|
||||
func copyAndEscape(buf *bytes.Buffer, val string) {
|
||||
for _, ch := range val {
|
||||
switch ch {
|
||||
case '=', ',', escapeChar:
|
||||
buf.WriteRune(escapeChar)
|
||||
}
|
||||
buf.WriteRune(ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Valid returns true if this encoder ID was allocated by
|
||||
// `NewEncoderID`. Invalid encoder IDs will not be cached.
|
||||
func (id EncoderID) Valid() bool {
|
||||
return id.value != 0
|
||||
}
|
143
vendor/go.opentelemetry.io/otel/attribute/iterator.go
generated
vendored
Normal file
143
vendor/go.opentelemetry.io/otel/attribute/iterator.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// 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 attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
// Iterator allows iterating over the set of labels in order,
|
||||
// sorted by key.
|
||||
type Iterator struct {
|
||||
storage *Set
|
||||
idx int
|
||||
}
|
||||
|
||||
// MergeIterator supports iterating over two sets of labels while
|
||||
// eliminating duplicate values from the combined set. The first
|
||||
// iterator value takes precedence.
|
||||
type MergeIterator struct {
|
||||
one oneIterator
|
||||
two oneIterator
|
||||
current KeyValue
|
||||
}
|
||||
|
||||
type oneIterator struct {
|
||||
iter Iterator
|
||||
done bool
|
||||
label KeyValue
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next position. Returns false if there
|
||||
// are no more labels.
|
||||
func (i *Iterator) Next() bool {
|
||||
i.idx++
|
||||
return i.idx < i.Len()
|
||||
}
|
||||
|
||||
// Label returns current KeyValue. Must be called only after Next returns
|
||||
// true.
|
||||
func (i *Iterator) Label() KeyValue {
|
||||
kv, _ := i.storage.Get(i.idx)
|
||||
return kv
|
||||
}
|
||||
|
||||
// Attribute is a synonym for Label().
|
||||
func (i *Iterator) Attribute() KeyValue {
|
||||
return i.Label()
|
||||
}
|
||||
|
||||
// IndexedLabel returns current index and attribute. Must be called only
|
||||
// after Next returns true.
|
||||
func (i *Iterator) IndexedLabel() (int, KeyValue) {
|
||||
return i.idx, i.Label()
|
||||
}
|
||||
|
||||
// Len returns a number of labels in the iterator's `*Set`.
|
||||
func (i *Iterator) Len() int {
|
||||
return i.storage.Len()
|
||||
}
|
||||
|
||||
// ToSlice is a convenience function that creates a slice of labels
|
||||
// from the passed iterator. The iterator is set up to start from the
|
||||
// beginning before creating the slice.
|
||||
func (i *Iterator) ToSlice() []KeyValue {
|
||||
l := i.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
i.idx = -1
|
||||
slice := make([]KeyValue, 0, l)
|
||||
for i.Next() {
|
||||
slice = append(slice, i.Label())
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
||||
// NewMergeIterator returns a MergeIterator for merging two label sets
|
||||
// Duplicates are resolved by taking the value from the first set.
|
||||
func NewMergeIterator(s1, s2 *Set) MergeIterator {
|
||||
mi := MergeIterator{
|
||||
one: makeOne(s1.Iter()),
|
||||
two: makeOne(s2.Iter()),
|
||||
}
|
||||
return mi
|
||||
}
|
||||
|
||||
func makeOne(iter Iterator) oneIterator {
|
||||
oi := oneIterator{
|
||||
iter: iter,
|
||||
}
|
||||
oi.advance()
|
||||
return oi
|
||||
}
|
||||
|
||||
func (oi *oneIterator) advance() {
|
||||
if oi.done = !oi.iter.Next(); !oi.done {
|
||||
oi.label = oi.iter.Label()
|
||||
}
|
||||
}
|
||||
|
||||
// Next returns true if there is another label available.
|
||||
func (m *MergeIterator) Next() bool {
|
||||
if m.one.done && m.two.done {
|
||||
return false
|
||||
}
|
||||
if m.one.done {
|
||||
m.current = m.two.label
|
||||
m.two.advance()
|
||||
return true
|
||||
}
|
||||
if m.two.done {
|
||||
m.current = m.one.label
|
||||
m.one.advance()
|
||||
return true
|
||||
}
|
||||
if m.one.label.Key == m.two.label.Key {
|
||||
m.current = m.one.label // first iterator label value wins
|
||||
m.one.advance()
|
||||
m.two.advance()
|
||||
return true
|
||||
}
|
||||
if m.one.label.Key < m.two.label.Key {
|
||||
m.current = m.one.label
|
||||
m.one.advance()
|
||||
return true
|
||||
}
|
||||
m.current = m.two.label
|
||||
m.two.advance()
|
||||
return true
|
||||
}
|
||||
|
||||
// Label returns the current value after Next() returns true.
|
||||
func (m *MergeIterator) Label() KeyValue {
|
||||
return m.current
|
||||
}
|
134
vendor/go.opentelemetry.io/otel/attribute/key.go
generated
vendored
Normal file
134
vendor/go.opentelemetry.io/otel/attribute/key.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
// 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 attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
// Key represents the key part in key-value pairs. It's a string. The
|
||||
// allowed character set in the key depends on the use of the key.
|
||||
type Key string
|
||||
|
||||
// Bool creates a KeyValue instance with a BOOL Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- Bool(name, value).
|
||||
func (k Key) Bool(v bool) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: BoolValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// BoolSlice creates a KeyValue instance with a BOOLSLICE Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- BoolSlice(name, value).
|
||||
func (k Key) BoolSlice(v []bool) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: BoolSliceValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Int creates a KeyValue instance with an INT64 Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- Int(name, value).
|
||||
func (k Key) Int(v int) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: IntValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// IntSlice creates a KeyValue instance with an INT64SLICE Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- IntSlice(name, value).
|
||||
func (k Key) IntSlice(v []int) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: IntSliceValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Int64 creates a KeyValue instance with an INT64 Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- Int64(name, value).
|
||||
func (k Key) Int64(v int64) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: Int64Value(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Int64Slice creates a KeyValue instance with an INT64SLICE Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- Int64Slice(name, value).
|
||||
func (k Key) Int64Slice(v []int64) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: Int64SliceValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Float64 creates a KeyValue instance with a FLOAT64 Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- Float64(name, value).
|
||||
func (k Key) Float64(v float64) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: Float64Value(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- Float64(name, value).
|
||||
func (k Key) Float64Slice(v []float64) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: Float64SliceValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// String creates a KeyValue instance with a STRING Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- String(name, value).
|
||||
func (k Key) String(v string) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: StringValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// StringSlice creates a KeyValue instance with a STRINGSLICE Value.
|
||||
//
|
||||
// If creating both a key and value at the same time, use the provided
|
||||
// convenience function instead -- StringSlice(name, value).
|
||||
func (k Key) StringSlice(v []string) KeyValue {
|
||||
return KeyValue{
|
||||
Key: k,
|
||||
Value: StringSliceValue(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Defined returns true for non-empty keys.
|
||||
func (k Key) Defined() bool {
|
||||
return len(k) != 0
|
||||
}
|
86
vendor/go.opentelemetry.io/otel/attribute/kv.go
generated
vendored
Normal file
86
vendor/go.opentelemetry.io/otel/attribute/kv.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// 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 attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// KeyValue holds a key and value pair.
|
||||
type KeyValue struct {
|
||||
Key Key
|
||||
Value Value
|
||||
}
|
||||
|
||||
// Valid returns if kv is a valid OpenTelemetry attribute.
|
||||
func (kv KeyValue) Valid() bool {
|
||||
return kv.Key.Defined() && kv.Value.Type() != INVALID
|
||||
}
|
||||
|
||||
// Bool creates a KeyValue with a BOOL Value type.
|
||||
func Bool(k string, v bool) KeyValue {
|
||||
return Key(k).Bool(v)
|
||||
}
|
||||
|
||||
// BoolSlice creates a KeyValue with a BOOLSLICE Value type.
|
||||
func BoolSlice(k string, v []bool) KeyValue {
|
||||
return Key(k).BoolSlice(v)
|
||||
}
|
||||
|
||||
// Int creates a KeyValue with an INT64 Value type.
|
||||
func Int(k string, v int) KeyValue {
|
||||
return Key(k).Int(v)
|
||||
}
|
||||
|
||||
// IntSlice creates a KeyValue with an INT64SLICE Value type.
|
||||
func IntSlice(k string, v []int) KeyValue {
|
||||
return Key(k).IntSlice(v)
|
||||
}
|
||||
|
||||
// Int64 creates a KeyValue with an INT64 Value type.
|
||||
func Int64(k string, v int64) KeyValue {
|
||||
return Key(k).Int64(v)
|
||||
}
|
||||
|
||||
// Int64Slice creates a KeyValue with an INT64SLICE Value type.
|
||||
func Int64Slice(k string, v []int64) KeyValue {
|
||||
return Key(k).Int64Slice(v)
|
||||
}
|
||||
|
||||
// Float64 creates a KeyValue with a FLOAT64 Value type.
|
||||
func Float64(k string, v float64) KeyValue {
|
||||
return Key(k).Float64(v)
|
||||
}
|
||||
|
||||
// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type.
|
||||
func Float64Slice(k string, v []float64) KeyValue {
|
||||
return Key(k).Float64Slice(v)
|
||||
}
|
||||
|
||||
// String creates a KeyValue with a STRING Value type.
|
||||
func String(k, v string) KeyValue {
|
||||
return Key(k).String(v)
|
||||
}
|
||||
|
||||
// StringSlice creates a KeyValue with a STRINGSLICE Value type.
|
||||
func StringSlice(k string, v []string) KeyValue {
|
||||
return Key(k).StringSlice(v)
|
||||
}
|
||||
|
||||
// Stringer creates a new key-value pair with a passed name and a string
|
||||
// value generated by the passed Stringer interface.
|
||||
func Stringer(k string, v fmt.Stringer) KeyValue {
|
||||
return Key(k).String(v.String())
|
||||
}
|
435
vendor/go.opentelemetry.io/otel/attribute/set.go
generated
vendored
Normal file
435
vendor/go.opentelemetry.io/otel/attribute/set.go
generated
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
// 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 attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type (
|
||||
// Set is the representation for a distinct label set. It
|
||||
// manages an immutable set of labels, with an internal cache
|
||||
// for storing label encodings.
|
||||
//
|
||||
// This type supports the `Equivalent` method of comparison
|
||||
// using values of type `Distinct`.
|
||||
//
|
||||
// This type is used to implement:
|
||||
// 1. Metric labels
|
||||
// 2. Resource sets
|
||||
// 3. Correlation map (TODO)
|
||||
Set struct {
|
||||
equivalent Distinct
|
||||
}
|
||||
|
||||
// Distinct wraps a variable-size array of `KeyValue`,
|
||||
// constructed with keys in sorted order. This can be used as
|
||||
// a map key or for equality checking between Sets.
|
||||
Distinct struct {
|
||||
iface interface{}
|
||||
}
|
||||
|
||||
// Filter supports removing certain labels from label sets.
|
||||
// When the filter returns true, the label will be kept in
|
||||
// the filtered label set. When the filter returns false, the
|
||||
// label is excluded from the filtered label set, and the
|
||||
// label instead appears in the `removed` list of excluded labels.
|
||||
Filter func(KeyValue) bool
|
||||
|
||||
// Sortable implements `sort.Interface`, used for sorting
|
||||
// `KeyValue`. This is an exported type to support a
|
||||
// memory optimization. A pointer to one of these is needed
|
||||
// for the call to `sort.Stable()`, which the caller may
|
||||
// provide in order to avoid an allocation. See
|
||||
// `NewSetWithSortable()`.
|
||||
Sortable []KeyValue
|
||||
)
|
||||
|
||||
var (
|
||||
// keyValueType is used in `computeDistinctReflect`.
|
||||
keyValueType = reflect.TypeOf(KeyValue{})
|
||||
|
||||
// emptySet is returned for empty label sets.
|
||||
emptySet = &Set{
|
||||
equivalent: Distinct{
|
||||
iface: [0]KeyValue{},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// EmptySet returns a reference to a Set with no elements.
|
||||
//
|
||||
// This is a convenience provided for optimized calling utility.
|
||||
func EmptySet() *Set {
|
||||
return emptySet
|
||||
}
|
||||
|
||||
// reflect abbreviates `reflect.ValueOf`.
|
||||
func (d Distinct) reflect() reflect.Value {
|
||||
return reflect.ValueOf(d.iface)
|
||||
}
|
||||
|
||||
// Valid returns true if this value refers to a valid `*Set`.
|
||||
func (d Distinct) Valid() bool {
|
||||
return d.iface != nil
|
||||
}
|
||||
|
||||
// Len returns the number of labels in this set.
|
||||
func (l *Set) Len() int {
|
||||
if l == nil || !l.equivalent.Valid() {
|
||||
return 0
|
||||
}
|
||||
return l.equivalent.reflect().Len()
|
||||
}
|
||||
|
||||
// Get returns the KeyValue at ordered position `idx` in this set.
|
||||
func (l *Set) Get(idx int) (KeyValue, bool) {
|
||||
if l == nil {
|
||||
return KeyValue{}, false
|
||||
}
|
||||
value := l.equivalent.reflect()
|
||||
|
||||
if idx >= 0 && idx < value.Len() {
|
||||
// Note: The Go compiler successfully avoids an allocation for
|
||||
// the interface{} conversion here:
|
||||
return value.Index(idx).Interface().(KeyValue), true
|
||||
}
|
||||
|
||||
return KeyValue{}, false
|
||||
}
|
||||
|
||||
// Value returns the value of a specified key in this set.
|
||||
func (l *Set) Value(k Key) (Value, bool) {
|
||||
if l == nil {
|
||||
return Value{}, false
|
||||
}
|
||||
rValue := l.equivalent.reflect()
|
||||
vlen := rValue.Len()
|
||||
|
||||
idx := sort.Search(vlen, func(idx int) bool {
|
||||
return rValue.Index(idx).Interface().(KeyValue).Key >= k
|
||||
})
|
||||
if idx >= vlen {
|
||||
return Value{}, false
|
||||
}
|
||||
keyValue := rValue.Index(idx).Interface().(KeyValue)
|
||||
if k == keyValue.Key {
|
||||
return keyValue.Value, true
|
||||
}
|
||||
return Value{}, false
|
||||
}
|
||||
|
||||
// HasValue tests whether a key is defined in this set.
|
||||
func (l *Set) HasValue(k Key) bool {
|
||||
if l == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := l.Value(k)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Iter returns an iterator for visiting the labels in this set.
|
||||
func (l *Set) Iter() Iterator {
|
||||
return Iterator{
|
||||
storage: l,
|
||||
idx: -1,
|
||||
}
|
||||
}
|
||||
|
||||
// ToSlice returns the set of labels belonging to this set, sorted,
|
||||
// where keys appear no more than once.
|
||||
func (l *Set) ToSlice() []KeyValue {
|
||||
iter := l.Iter()
|
||||
return iter.ToSlice()
|
||||
}
|
||||
|
||||
// Equivalent returns a value that may be used as a map key. The
|
||||
// Distinct type guarantees that the result will equal the equivalent
|
||||
// Distinct value of any label set with the same elements as this,
|
||||
// where sets are made unique by choosing the last value in the input
|
||||
// for any given key.
|
||||
func (l *Set) Equivalent() Distinct {
|
||||
if l == nil || !l.equivalent.Valid() {
|
||||
return emptySet.equivalent
|
||||
}
|
||||
return l.equivalent
|
||||
}
|
||||
|
||||
// Equals returns true if the argument set is equivalent to this set.
|
||||
func (l *Set) Equals(o *Set) bool {
|
||||
return l.Equivalent() == o.Equivalent()
|
||||
}
|
||||
|
||||
// Encoded returns the encoded form of this set, according to
|
||||
// `encoder`.
|
||||
func (l *Set) Encoded(encoder Encoder) string {
|
||||
if l == nil || encoder == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return encoder.Encode(l.Iter())
|
||||
}
|
||||
|
||||
func empty() Set {
|
||||
return Set{
|
||||
equivalent: emptySet.equivalent,
|
||||
}
|
||||
}
|
||||
|
||||
// NewSet returns a new `Set`. See the documentation for
|
||||
// `NewSetWithSortableFiltered` for more details.
|
||||
//
|
||||
// Except for empty sets, this method adds an additional allocation
|
||||
// compared with calls that include a `*Sortable`.
|
||||
func NewSet(kvs ...KeyValue) Set {
|
||||
// Check for empty set.
|
||||
if len(kvs) == 0 {
|
||||
return empty()
|
||||
}
|
||||
s, _ := NewSetWithSortableFiltered(kvs, new(Sortable), nil)
|
||||
return s
|
||||
}
|
||||
|
||||
// NewSetWithSortable returns a new `Set`. See the documentation for
|
||||
// `NewSetWithSortableFiltered` for more details.
|
||||
//
|
||||
// This call includes a `*Sortable` option as a memory optimization.
|
||||
func NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set {
|
||||
// Check for empty set.
|
||||
if len(kvs) == 0 {
|
||||
return empty()
|
||||
}
|
||||
s, _ := NewSetWithSortableFiltered(kvs, tmp, nil)
|
||||
return s
|
||||
}
|
||||
|
||||
// NewSetWithFiltered returns a new `Set`. See the documentation for
|
||||
// `NewSetWithSortableFiltered` for more details.
|
||||
//
|
||||
// This call includes a `Filter` to include/exclude label keys from
|
||||
// the return value. Excluded keys are returned as a slice of label
|
||||
// values.
|
||||
func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
|
||||
// Check for empty set.
|
||||
if len(kvs) == 0 {
|
||||
return empty(), nil
|
||||
}
|
||||
return NewSetWithSortableFiltered(kvs, new(Sortable), filter)
|
||||
}
|
||||
|
||||
// NewSetWithSortableFiltered returns a new `Set`.
|
||||
//
|
||||
// Duplicate keys are eliminated by taking the last value. This
|
||||
// re-orders the input slice so that unique last-values are contiguous
|
||||
// at the end of the slice.
|
||||
//
|
||||
// This ensures the following:
|
||||
//
|
||||
// - Last-value-wins semantics
|
||||
// - Caller sees the reordering, but doesn't lose values
|
||||
// - Repeated call preserve last-value wins.
|
||||
//
|
||||
// Note that methods are defined on `*Set`, although this returns `Set`.
|
||||
// Callers can avoid memory allocations by:
|
||||
//
|
||||
// - allocating a `Sortable` for use as a temporary in this method
|
||||
// - allocating a `Set` for storing the return value of this
|
||||
// constructor.
|
||||
//
|
||||
// The result maintains a cache of encoded labels, by attribute.EncoderID.
|
||||
// This value should not be copied after its first use.
|
||||
//
|
||||
// The second `[]KeyValue` return value is a list of labels that were
|
||||
// excluded by the Filter (if non-nil).
|
||||
func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) {
|
||||
// Check for empty set.
|
||||
if len(kvs) == 0 {
|
||||
return empty(), nil
|
||||
}
|
||||
|
||||
*tmp = kvs
|
||||
|
||||
// Stable sort so the following de-duplication can implement
|
||||
// last-value-wins semantics.
|
||||
sort.Stable(tmp)
|
||||
|
||||
*tmp = nil
|
||||
|
||||
position := len(kvs) - 1
|
||||
offset := position - 1
|
||||
|
||||
// The requirements stated above require that the stable
|
||||
// result be placed in the end of the input slice, while
|
||||
// overwritten values are swapped to the beginning.
|
||||
//
|
||||
// De-duplicate with last-value-wins semantics. Preserve
|
||||
// duplicate values at the beginning of the input slice.
|
||||
for ; offset >= 0; offset-- {
|
||||
if kvs[offset].Key == kvs[position].Key {
|
||||
continue
|
||||
}
|
||||
position--
|
||||
kvs[offset], kvs[position] = kvs[position], kvs[offset]
|
||||
}
|
||||
if filter != nil {
|
||||
return filterSet(kvs[position:], filter)
|
||||
}
|
||||
return Set{
|
||||
equivalent: computeDistinct(kvs[position:]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// filterSet reorders `kvs` so that included keys are contiguous at
|
||||
// the end of the slice, while excluded keys precede the included keys.
|
||||
func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
|
||||
var excluded []KeyValue
|
||||
|
||||
// Move labels that do not match the filter so
|
||||
// they're adjacent before calling computeDistinct().
|
||||
distinctPosition := len(kvs)
|
||||
|
||||
// Swap indistinct keys forward and distinct keys toward the
|
||||
// end of the slice.
|
||||
offset := len(kvs) - 1
|
||||
for ; offset >= 0; offset-- {
|
||||
if filter(kvs[offset]) {
|
||||
distinctPosition--
|
||||
kvs[offset], kvs[distinctPosition] = kvs[distinctPosition], kvs[offset]
|
||||
continue
|
||||
}
|
||||
}
|
||||
excluded = kvs[:distinctPosition]
|
||||
|
||||
return Set{
|
||||
equivalent: computeDistinct(kvs[distinctPosition:]),
|
||||
}, excluded
|
||||
}
|
||||
|
||||
// Filter returns a filtered copy of this `Set`. See the
|
||||
// documentation for `NewSetWithSortableFiltered` for more details.
|
||||
func (l *Set) Filter(re Filter) (Set, []KeyValue) {
|
||||
if re == nil {
|
||||
return Set{
|
||||
equivalent: l.equivalent,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Note: This could be refactored to avoid the temporary slice
|
||||
// allocation, if it proves to be expensive.
|
||||
return filterSet(l.ToSlice(), re)
|
||||
}
|
||||
|
||||
// computeDistinct returns a `Distinct` using either the fixed- or
|
||||
// reflect-oriented code path, depending on the size of the input.
|
||||
// The input slice is assumed to already be sorted and de-duplicated.
|
||||
func computeDistinct(kvs []KeyValue) Distinct {
|
||||
iface := computeDistinctFixed(kvs)
|
||||
if iface == nil {
|
||||
iface = computeDistinctReflect(kvs)
|
||||
}
|
||||
return Distinct{
|
||||
iface: iface,
|
||||
}
|
||||
}
|
||||
|
||||
// computeDistinctFixed computes a `Distinct` for small slices. It
|
||||
// returns nil if the input is too large for this code path.
|
||||
func computeDistinctFixed(kvs []KeyValue) interface{} {
|
||||
switch len(kvs) {
|
||||
case 1:
|
||||
ptr := new([1]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 2:
|
||||
ptr := new([2]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 3:
|
||||
ptr := new([3]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 4:
|
||||
ptr := new([4]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 5:
|
||||
ptr := new([5]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 6:
|
||||
ptr := new([6]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 7:
|
||||
ptr := new([7]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 8:
|
||||
ptr := new([8]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 9:
|
||||
ptr := new([9]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
case 10:
|
||||
ptr := new([10]KeyValue)
|
||||
copy((*ptr)[:], kvs)
|
||||
return *ptr
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// computeDistinctReflect computes a `Distinct` using reflection,
|
||||
// works for any size input.
|
||||
func computeDistinctReflect(kvs []KeyValue) interface{} {
|
||||
at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()
|
||||
for i, keyValue := range kvs {
|
||||
*(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue
|
||||
}
|
||||
return at.Interface()
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of the `*Set`.
|
||||
func (l *Set) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(l.equivalent.iface)
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
||||
func (l Set) MarshalLog() interface{} {
|
||||
kvs := make(map[string]string)
|
||||
for _, kv := range l.ToSlice() {
|
||||
kvs[string(kv.Key)] = kv.Value.Emit()
|
||||
}
|
||||
return kvs
|
||||
}
|
||||
|
||||
// Len implements `sort.Interface`.
|
||||
func (l *Sortable) Len() int {
|
||||
return len(*l)
|
||||
}
|
||||
|
||||
// Swap implements `sort.Interface`.
|
||||
func (l *Sortable) Swap(i, j int) {
|
||||
(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
|
||||
}
|
||||
|
||||
// Less implements `sort.Interface`.
|
||||
func (l *Sortable) Less(i, j int) bool {
|
||||
return (*l)[i].Key < (*l)[j].Key
|
||||
}
|
31
vendor/go.opentelemetry.io/otel/attribute/type_string.go
generated
vendored
Normal file
31
vendor/go.opentelemetry.io/otel/attribute/type_string.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code generated by "stringer -type=Type"; DO NOT EDIT.
|
||||
|
||||
package attribute
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[INVALID-0]
|
||||
_ = x[BOOL-1]
|
||||
_ = x[INT64-2]
|
||||
_ = x[FLOAT64-3]
|
||||
_ = x[STRING-4]
|
||||
_ = x[BOOLSLICE-5]
|
||||
_ = x[INT64SLICE-6]
|
||||
_ = x[FLOAT64SLICE-7]
|
||||
_ = x[STRINGSLICE-8]
|
||||
}
|
||||
|
||||
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE"
|
||||
|
||||
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}
|
||||
|
||||
func (i Type) String() string {
|
||||
if i < 0 || i >= Type(len(_Type_index)-1) {
|
||||
return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Type_name[_Type_index[i]:_Type_index[i+1]]
|
||||
}
|
271
vendor/go.opentelemetry.io/otel/attribute/value.go
generated
vendored
Normal file
271
vendor/go.opentelemetry.io/otel/attribute/value.go
generated
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
// 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 attribute // import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"go.opentelemetry.io/otel/internal"
|
||||
)
|
||||
|
||||
//go:generate stringer -type=Type
|
||||
|
||||
// Type describes the type of the data Value holds.
|
||||
type Type int
|
||||
|
||||
// Value represents the value part in key-value pairs.
|
||||
type Value struct {
|
||||
vtype Type
|
||||
numeric uint64
|
||||
stringly string
|
||||
slice interface{}
|
||||
}
|
||||
|
||||
const (
|
||||
// INVALID is used for a Value with no value set.
|
||||
INVALID Type = iota
|
||||
// BOOL is a boolean Type Value.
|
||||
BOOL
|
||||
// INT64 is a 64-bit signed integral Type Value.
|
||||
INT64
|
||||
// FLOAT64 is a 64-bit floating point Type Value.
|
||||
FLOAT64
|
||||
// STRING is a string Type Value.
|
||||
STRING
|
||||
// BOOLSLICE is a slice of booleans Type Value.
|
||||
BOOLSLICE
|
||||
// INT64SLICE is a slice of 64-bit signed integral numbers Type Value.
|
||||
INT64SLICE
|
||||
// FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value.
|
||||
FLOAT64SLICE
|
||||
// STRINGSLICE is a slice of strings Type Value.
|
||||
STRINGSLICE
|
||||
)
|
||||
|
||||
// BoolValue creates a BOOL Value.
|
||||
func BoolValue(v bool) Value {
|
||||
return Value{
|
||||
vtype: BOOL,
|
||||
numeric: internal.BoolToRaw(v),
|
||||
}
|
||||
}
|
||||
|
||||
// BoolSliceValue creates a BOOLSLICE Value.
|
||||
func BoolSliceValue(v []bool) Value {
|
||||
cp := make([]bool, len(v))
|
||||
copy(cp, v)
|
||||
return Value{
|
||||
vtype: BOOLSLICE,
|
||||
slice: &cp,
|
||||
}
|
||||
}
|
||||
|
||||
// IntValue creates an INT64 Value.
|
||||
func IntValue(v int) Value {
|
||||
return Int64Value(int64(v))
|
||||
}
|
||||
|
||||
// IntSliceValue creates an INTSLICE Value.
|
||||
func IntSliceValue(v []int) Value {
|
||||
cp := make([]int64, 0, len(v))
|
||||
for _, i := range v {
|
||||
cp = append(cp, int64(i))
|
||||
}
|
||||
return Value{
|
||||
vtype: INT64SLICE,
|
||||
slice: &cp,
|
||||
}
|
||||
}
|
||||
|
||||
// Int64Value creates an INT64 Value.
|
||||
func Int64Value(v int64) Value {
|
||||
return Value{
|
||||
vtype: INT64,
|
||||
numeric: internal.Int64ToRaw(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Int64SliceValue creates an INT64SLICE Value.
|
||||
func Int64SliceValue(v []int64) Value {
|
||||
cp := make([]int64, len(v))
|
||||
copy(cp, v)
|
||||
return Value{
|
||||
vtype: INT64SLICE,
|
||||
slice: &cp,
|
||||
}
|
||||
}
|
||||
|
||||
// Float64Value creates a FLOAT64 Value.
|
||||
func Float64Value(v float64) Value {
|
||||
return Value{
|
||||
vtype: FLOAT64,
|
||||
numeric: internal.Float64ToRaw(v),
|
||||
}
|
||||
}
|
||||
|
||||
// Float64SliceValue creates a FLOAT64SLICE Value.
|
||||
func Float64SliceValue(v []float64) Value {
|
||||
cp := make([]float64, len(v))
|
||||
copy(cp, v)
|
||||
return Value{
|
||||
vtype: FLOAT64SLICE,
|
||||
slice: &cp,
|
||||
}
|
||||
}
|
||||
|
||||
// StringValue creates a STRING Value.
|
||||
func StringValue(v string) Value {
|
||||
return Value{
|
||||
vtype: STRING,
|
||||
stringly: v,
|
||||
}
|
||||
}
|
||||
|
||||
// StringSliceValue creates a STRINGSLICE Value.
|
||||
func StringSliceValue(v []string) Value {
|
||||
cp := make([]string, len(v))
|
||||
copy(cp, v)
|
||||
return Value{
|
||||
vtype: STRINGSLICE,
|
||||
slice: &cp,
|
||||
}
|
||||
}
|
||||
|
||||
// Type returns a type of the Value.
|
||||
func (v Value) Type() Type {
|
||||
return v.vtype
|
||||
}
|
||||
|
||||
// AsBool returns the bool value. Make sure that the Value's type is
|
||||
// BOOL.
|
||||
func (v Value) AsBool() bool {
|
||||
return internal.RawToBool(v.numeric)
|
||||
}
|
||||
|
||||
// AsBoolSlice returns the []bool value. Make sure that the Value's type is
|
||||
// BOOLSLICE.
|
||||
func (v Value) AsBoolSlice() []bool {
|
||||
if s, ok := v.slice.(*[]bool); ok {
|
||||
return *s
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsInt64 returns the int64 value. Make sure that the Value's type is
|
||||
// INT64.
|
||||
func (v Value) AsInt64() int64 {
|
||||
return internal.RawToInt64(v.numeric)
|
||||
}
|
||||
|
||||
// AsInt64Slice returns the []int64 value. Make sure that the Value's type is
|
||||
// INT64SLICE.
|
||||
func (v Value) AsInt64Slice() []int64 {
|
||||
if s, ok := v.slice.(*[]int64); ok {
|
||||
return *s
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsFloat64 returns the float64 value. Make sure that the Value's
|
||||
// type is FLOAT64.
|
||||
func (v Value) AsFloat64() float64 {
|
||||
return internal.RawToFloat64(v.numeric)
|
||||
}
|
||||
|
||||
// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is
|
||||
// FLOAT64SLICE.
|
||||
func (v Value) AsFloat64Slice() []float64 {
|
||||
if s, ok := v.slice.(*[]float64); ok {
|
||||
return *s
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsString returns the string value. Make sure that the Value's type
|
||||
// is STRING.
|
||||
func (v Value) AsString() string {
|
||||
return v.stringly
|
||||
}
|
||||
|
||||
// AsStringSlice returns the []string value. Make sure that the Value's type is
|
||||
// STRINGSLICE.
|
||||
func (v Value) AsStringSlice() []string {
|
||||
if s, ok := v.slice.(*[]string); ok {
|
||||
return *s
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type unknownValueType struct{}
|
||||
|
||||
// AsInterface returns Value's data as interface{}.
|
||||
func (v Value) AsInterface() interface{} {
|
||||
switch v.Type() {
|
||||
case BOOL:
|
||||
return v.AsBool()
|
||||
case BOOLSLICE:
|
||||
return v.AsBoolSlice()
|
||||
case INT64:
|
||||
return v.AsInt64()
|
||||
case INT64SLICE:
|
||||
return v.AsInt64Slice()
|
||||
case FLOAT64:
|
||||
return v.AsFloat64()
|
||||
case FLOAT64SLICE:
|
||||
return v.AsFloat64Slice()
|
||||
case STRING:
|
||||
return v.stringly
|
||||
case STRINGSLICE:
|
||||
return v.AsStringSlice()
|
||||
}
|
||||
return unknownValueType{}
|
||||
}
|
||||
|
||||
// Emit returns a string representation of Value's data.
|
||||
func (v Value) Emit() string {
|
||||
switch v.Type() {
|
||||
case BOOLSLICE:
|
||||
return fmt.Sprint(*(v.slice.(*[]bool)))
|
||||
case BOOL:
|
||||
return strconv.FormatBool(v.AsBool())
|
||||
case INT64SLICE:
|
||||
return fmt.Sprint(*(v.slice.(*[]int64)))
|
||||
case INT64:
|
||||
return strconv.FormatInt(v.AsInt64(), 10)
|
||||
case FLOAT64SLICE:
|
||||
return fmt.Sprint(*(v.slice.(*[]float64)))
|
||||
case FLOAT64:
|
||||
return fmt.Sprint(v.AsFloat64())
|
||||
case STRINGSLICE:
|
||||
return fmt.Sprint(*(v.slice.(*[]string)))
|
||||
case STRING:
|
||||
return v.stringly
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of the Value.
|
||||
func (v Value) MarshalJSON() ([]byte, error) {
|
||||
var jsonVal struct {
|
||||
Type string
|
||||
Value interface{}
|
||||
}
|
||||
jsonVal.Type = v.Type().String()
|
||||
jsonVal.Value = v.AsInterface()
|
||||
return json.Marshal(jsonVal)
|
||||
}
|
556
vendor/go.opentelemetry.io/otel/baggage/baggage.go
generated
vendored
Normal file
556
vendor/go.opentelemetry.io/otel/baggage/baggage.go
generated
vendored
Normal file
@@ -0,0 +1,556 @@
|
||||
// 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 baggage // import "go.opentelemetry.io/otel/baggage"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/internal/baggage"
|
||||
)
|
||||
|
||||
const (
|
||||
maxMembers = 180
|
||||
maxBytesPerMembers = 4096
|
||||
maxBytesPerBaggageString = 8192
|
||||
|
||||
listDelimiter = ","
|
||||
keyValueDelimiter = "="
|
||||
propertyDelimiter = ";"
|
||||
|
||||
keyDef = `([\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+)`
|
||||
valueDef = `([\x21\x23-\x2b\x2d-\x3a\x3c-\x5B\x5D-\x7e]*)`
|
||||
keyValueDef = `\s*` + keyDef + `\s*` + keyValueDelimiter + `\s*` + valueDef + `\s*`
|
||||
)
|
||||
|
||||
var (
|
||||
keyRe = regexp.MustCompile(`^` + keyDef + `$`)
|
||||
valueRe = regexp.MustCompile(`^` + valueDef + `$`)
|
||||
propertyRe = regexp.MustCompile(`^(?:\s*` + keyDef + `\s*|` + keyValueDef + `)$`)
|
||||
)
|
||||
|
||||
var (
|
||||
errInvalidKey = errors.New("invalid key")
|
||||
errInvalidValue = errors.New("invalid value")
|
||||
errInvalidProperty = errors.New("invalid baggage list-member property")
|
||||
errInvalidMember = errors.New("invalid baggage list-member")
|
||||
errMemberNumber = errors.New("too many list-members in baggage-string")
|
||||
errMemberBytes = errors.New("list-member too large")
|
||||
errBaggageBytes = errors.New("baggage-string too large")
|
||||
)
|
||||
|
||||
// Property is an additional metadata entry for a baggage list-member.
|
||||
type Property struct {
|
||||
key, value string
|
||||
|
||||
// hasValue indicates if a zero-value value means the property does not
|
||||
// have a value or if it was the zero-value.
|
||||
hasValue bool
|
||||
|
||||
// hasData indicates whether the created property contains data or not.
|
||||
// Properties that do not contain data are invalid with no other check
|
||||
// required.
|
||||
hasData bool
|
||||
}
|
||||
|
||||
func NewKeyProperty(key string) (Property, error) {
|
||||
if !keyRe.MatchString(key) {
|
||||
return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key)
|
||||
}
|
||||
|
||||
p := Property{key: key, hasData: true}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func NewKeyValueProperty(key, value string) (Property, error) {
|
||||
if !keyRe.MatchString(key) {
|
||||
return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key)
|
||||
}
|
||||
if !valueRe.MatchString(value) {
|
||||
return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidValue, value)
|
||||
}
|
||||
|
||||
p := Property{
|
||||
key: key,
|
||||
value: value,
|
||||
hasValue: true,
|
||||
hasData: true,
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func newInvalidProperty() Property {
|
||||
return Property{}
|
||||
}
|
||||
|
||||
// parseProperty attempts to decode a Property from the passed string. It
|
||||
// returns an error if the input is invalid according to the W3C Baggage
|
||||
// specification.
|
||||
func parseProperty(property string) (Property, error) {
|
||||
if property == "" {
|
||||
return newInvalidProperty(), nil
|
||||
}
|
||||
|
||||
match := propertyRe.FindStringSubmatch(property)
|
||||
if len(match) != 4 {
|
||||
return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidProperty, property)
|
||||
}
|
||||
|
||||
p := Property{hasData: true}
|
||||
if match[1] != "" {
|
||||
p.key = match[1]
|
||||
} else {
|
||||
p.key = match[2]
|
||||
p.value = match[3]
|
||||
p.hasValue = true
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// validate ensures p conforms to the W3C Baggage specification, returning an
|
||||
// error otherwise.
|
||||
func (p Property) validate() error {
|
||||
errFunc := func(err error) error {
|
||||
return fmt.Errorf("invalid property: %w", err)
|
||||
}
|
||||
|
||||
if !p.hasData {
|
||||
return errFunc(fmt.Errorf("%w: %q", errInvalidProperty, p))
|
||||
}
|
||||
|
||||
if !keyRe.MatchString(p.key) {
|
||||
return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key))
|
||||
}
|
||||
if p.hasValue && !valueRe.MatchString(p.value) {
|
||||
return errFunc(fmt.Errorf("%w: %q", errInvalidValue, p.value))
|
||||
}
|
||||
if !p.hasValue && p.value != "" {
|
||||
return errFunc(errors.New("inconsistent value"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Key returns the Property key.
|
||||
func (p Property) Key() string {
|
||||
return p.key
|
||||
}
|
||||
|
||||
// Value returns the Property value. Additionally a boolean value is returned
|
||||
// indicating if the returned value is the empty if the Property has a value
|
||||
// that is empty or if the value is not set.
|
||||
func (p Property) Value() (string, bool) {
|
||||
return p.value, p.hasValue
|
||||
}
|
||||
|
||||
// String encodes Property into a string compliant with the W3C Baggage
|
||||
// specification.
|
||||
func (p Property) String() string {
|
||||
if p.hasValue {
|
||||
return fmt.Sprintf("%s%s%v", p.key, keyValueDelimiter, p.value)
|
||||
}
|
||||
return p.key
|
||||
}
|
||||
|
||||
type properties []Property
|
||||
|
||||
func fromInternalProperties(iProps []baggage.Property) properties {
|
||||
if len(iProps) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
props := make(properties, len(iProps))
|
||||
for i, p := range iProps {
|
||||
props[i] = Property{
|
||||
key: p.Key,
|
||||
value: p.Value,
|
||||
hasValue: p.HasValue,
|
||||
}
|
||||
}
|
||||
return props
|
||||
}
|
||||
|
||||
func (p properties) asInternal() []baggage.Property {
|
||||
if len(p) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
iProps := make([]baggage.Property, len(p))
|
||||
for i, prop := range p {
|
||||
iProps[i] = baggage.Property{
|
||||
Key: prop.key,
|
||||
Value: prop.value,
|
||||
HasValue: prop.hasValue,
|
||||
}
|
||||
}
|
||||
return iProps
|
||||
}
|
||||
|
||||
func (p properties) Copy() properties {
|
||||
if len(p) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
props := make(properties, len(p))
|
||||
copy(props, p)
|
||||
return props
|
||||
}
|
||||
|
||||
// validate ensures each Property in p conforms to the W3C Baggage
|
||||
// specification, returning an error otherwise.
|
||||
func (p properties) validate() error {
|
||||
for _, prop := range p {
|
||||
if err := prop.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String encodes properties into a string compliant with the W3C Baggage
|
||||
// specification.
|
||||
func (p properties) String() string {
|
||||
props := make([]string, len(p))
|
||||
for i, prop := range p {
|
||||
props[i] = prop.String()
|
||||
}
|
||||
return strings.Join(props, propertyDelimiter)
|
||||
}
|
||||
|
||||
// Member is a list-member of a baggage-string as defined by the W3C Baggage
|
||||
// specification.
|
||||
type Member struct {
|
||||
key, value string
|
||||
properties properties
|
||||
|
||||
// hasData indicates whether the created property contains data or not.
|
||||
// Properties that do not contain data are invalid with no other check
|
||||
// required.
|
||||
hasData bool
|
||||
}
|
||||
|
||||
// NewMember returns a new Member from the passed arguments. An error is
|
||||
// returned if the created Member would be invalid according to the W3C
|
||||
// Baggage specification.
|
||||
func NewMember(key, value string, props ...Property) (Member, error) {
|
||||
m := Member{
|
||||
key: key,
|
||||
value: value,
|
||||
properties: properties(props).Copy(),
|
||||
hasData: true,
|
||||
}
|
||||
if err := m.validate(); err != nil {
|
||||
return newInvalidMember(), err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func newInvalidMember() Member {
|
||||
return Member{}
|
||||
}
|
||||
|
||||
// parseMember attempts to decode a Member from the passed string. It returns
|
||||
// an error if the input is invalid according to the W3C Baggage
|
||||
// specification.
|
||||
func parseMember(member string) (Member, error) {
|
||||
if n := len(member); n > maxBytesPerMembers {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n)
|
||||
}
|
||||
|
||||
var (
|
||||
key, value string
|
||||
props properties
|
||||
)
|
||||
|
||||
parts := strings.SplitN(member, propertyDelimiter, 2)
|
||||
switch len(parts) {
|
||||
case 2:
|
||||
// Parse the member properties.
|
||||
for _, pStr := range strings.Split(parts[1], propertyDelimiter) {
|
||||
p, err := parseProperty(pStr)
|
||||
if err != nil {
|
||||
return newInvalidMember(), err
|
||||
}
|
||||
props = append(props, p)
|
||||
}
|
||||
fallthrough
|
||||
case 1:
|
||||
// Parse the member key/value pair.
|
||||
|
||||
// Take into account a value can contain equal signs (=).
|
||||
kv := strings.SplitN(parts[0], keyValueDelimiter, 2)
|
||||
if len(kv) != 2 {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidMember, member)
|
||||
}
|
||||
// "Leading and trailing whitespaces are allowed but MUST be trimmed
|
||||
// when converting the header into a data structure."
|
||||
key = strings.TrimSpace(kv[0])
|
||||
var err error
|
||||
value, err = url.QueryUnescape(strings.TrimSpace(kv[1]))
|
||||
if err != nil {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %q", err, value)
|
||||
}
|
||||
if !keyRe.MatchString(key) {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key)
|
||||
}
|
||||
if !valueRe.MatchString(value) {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
|
||||
}
|
||||
default:
|
||||
// This should never happen unless a developer has changed the string
|
||||
// splitting somehow. Panic instead of failing silently and allowing
|
||||
// the bug to slip past the CI checks.
|
||||
panic("failed to parse baggage member")
|
||||
}
|
||||
|
||||
return Member{key: key, value: value, properties: props, hasData: true}, nil
|
||||
}
|
||||
|
||||
// validate ensures m conforms to the W3C Baggage specification, returning an
|
||||
// error otherwise.
|
||||
func (m Member) validate() error {
|
||||
if !m.hasData {
|
||||
return fmt.Errorf("%w: %q", errInvalidMember, m)
|
||||
}
|
||||
|
||||
if !keyRe.MatchString(m.key) {
|
||||
return fmt.Errorf("%w: %q", errInvalidKey, m.key)
|
||||
}
|
||||
if !valueRe.MatchString(m.value) {
|
||||
return fmt.Errorf("%w: %q", errInvalidValue, m.value)
|
||||
}
|
||||
return m.properties.validate()
|
||||
}
|
||||
|
||||
// Key returns the Member key.
|
||||
func (m Member) Key() string { return m.key }
|
||||
|
||||
// Value returns the Member value.
|
||||
func (m Member) Value() string { return m.value }
|
||||
|
||||
// Properties returns a copy of the Member properties.
|
||||
func (m Member) Properties() []Property { return m.properties.Copy() }
|
||||
|
||||
// String encodes Member into a string compliant with the W3C Baggage
|
||||
// specification.
|
||||
func (m Member) String() string {
|
||||
// A key is just an ASCII string, but a value is URL encoded UTF-8.
|
||||
s := fmt.Sprintf("%s%s%s", m.key, keyValueDelimiter, url.QueryEscape(m.value))
|
||||
if len(m.properties) > 0 {
|
||||
s = fmt.Sprintf("%s%s%s", s, propertyDelimiter, m.properties.String())
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Baggage is a list of baggage members representing the baggage-string as
|
||||
// defined by the W3C Baggage specification.
|
||||
type Baggage struct { //nolint:golint
|
||||
list baggage.List
|
||||
}
|
||||
|
||||
// New returns a new valid Baggage. It returns an error if it results in a
|
||||
// Baggage exceeding limits set in that specification.
|
||||
//
|
||||
// It expects all the provided members to have already been validated.
|
||||
func New(members ...Member) (Baggage, error) {
|
||||
if len(members) == 0 {
|
||||
return Baggage{}, nil
|
||||
}
|
||||
|
||||
b := make(baggage.List)
|
||||
for _, m := range members {
|
||||
if !m.hasData {
|
||||
return Baggage{}, errInvalidMember
|
||||
}
|
||||
|
||||
// OpenTelemetry resolves duplicates by last-one-wins.
|
||||
b[m.key] = baggage.Item{
|
||||
Value: m.value,
|
||||
Properties: m.properties.asInternal(),
|
||||
}
|
||||
}
|
||||
|
||||
// Check member numbers after deduplicating.
|
||||
if len(b) > maxMembers {
|
||||
return Baggage{}, errMemberNumber
|
||||
}
|
||||
|
||||
bag := Baggage{b}
|
||||
if n := len(bag.String()); n > maxBytesPerBaggageString {
|
||||
return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n)
|
||||
}
|
||||
|
||||
return bag, nil
|
||||
}
|
||||
|
||||
// Parse attempts to decode a baggage-string from the passed string. It
|
||||
// returns an error if the input is invalid according to the W3C Baggage
|
||||
// specification.
|
||||
//
|
||||
// If there are duplicate list-members contained in baggage, the last one
|
||||
// defined (reading left-to-right) will be the only one kept. This diverges
|
||||
// from the W3C Baggage specification which allows duplicate list-members, but
|
||||
// conforms to the OpenTelemetry Baggage specification.
|
||||
func Parse(bStr string) (Baggage, error) {
|
||||
if bStr == "" {
|
||||
return Baggage{}, nil
|
||||
}
|
||||
|
||||
if n := len(bStr); n > maxBytesPerBaggageString {
|
||||
return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n)
|
||||
}
|
||||
|
||||
b := make(baggage.List)
|
||||
for _, memberStr := range strings.Split(bStr, listDelimiter) {
|
||||
m, err := parseMember(memberStr)
|
||||
if err != nil {
|
||||
return Baggage{}, err
|
||||
}
|
||||
// OpenTelemetry resolves duplicates by last-one-wins.
|
||||
b[m.key] = baggage.Item{
|
||||
Value: m.value,
|
||||
Properties: m.properties.asInternal(),
|
||||
}
|
||||
}
|
||||
|
||||
// OpenTelemetry does not allow for duplicate list-members, but the W3C
|
||||
// specification does. Now that we have deduplicated, ensure the baggage
|
||||
// does not exceed list-member limits.
|
||||
if len(b) > maxMembers {
|
||||
return Baggage{}, errMemberNumber
|
||||
}
|
||||
|
||||
return Baggage{b}, nil
|
||||
}
|
||||
|
||||
// Member returns the baggage list-member identified by key.
|
||||
//
|
||||
// If there is no list-member matching the passed key the returned Member will
|
||||
// be a zero-value Member.
|
||||
// The returned member is not validated, as we assume the validation happened
|
||||
// when it was added to the Baggage.
|
||||
func (b Baggage) Member(key string) Member {
|
||||
v, ok := b.list[key]
|
||||
if !ok {
|
||||
// We do not need to worry about distiguising between the situation
|
||||
// where a zero-valued Member is included in the Baggage because a
|
||||
// zero-valued Member is invalid according to the W3C Baggage
|
||||
// specification (it has an empty key).
|
||||
return newInvalidMember()
|
||||
}
|
||||
|
||||
return Member{
|
||||
key: key,
|
||||
value: v.Value,
|
||||
properties: fromInternalProperties(v.Properties),
|
||||
}
|
||||
}
|
||||
|
||||
// Members returns all the baggage list-members.
|
||||
// The order of the returned list-members does not have significance.
|
||||
//
|
||||
// The returned members are not validated, as we assume the validation happened
|
||||
// when they were added to the Baggage.
|
||||
func (b Baggage) Members() []Member {
|
||||
if len(b.list) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
members := make([]Member, 0, len(b.list))
|
||||
for k, v := range b.list {
|
||||
members = append(members, Member{
|
||||
key: k,
|
||||
value: v.Value,
|
||||
properties: fromInternalProperties(v.Properties),
|
||||
})
|
||||
}
|
||||
return members
|
||||
}
|
||||
|
||||
// SetMember returns a copy the Baggage with the member included. If the
|
||||
// baggage contains a Member with the same key the existing Member is
|
||||
// replaced.
|
||||
//
|
||||
// If member is invalid according to the W3C Baggage specification, an error
|
||||
// is returned with the original Baggage.
|
||||
func (b Baggage) SetMember(member Member) (Baggage, error) {
|
||||
if !member.hasData {
|
||||
return b, errInvalidMember
|
||||
}
|
||||
|
||||
n := len(b.list)
|
||||
if _, ok := b.list[member.key]; !ok {
|
||||
n++
|
||||
}
|
||||
list := make(baggage.List, n)
|
||||
|
||||
for k, v := range b.list {
|
||||
// Do not copy if we are just going to overwrite.
|
||||
if k == member.key {
|
||||
continue
|
||||
}
|
||||
list[k] = v
|
||||
}
|
||||
|
||||
list[member.key] = baggage.Item{
|
||||
Value: member.value,
|
||||
Properties: member.properties.asInternal(),
|
||||
}
|
||||
|
||||
return Baggage{list: list}, nil
|
||||
}
|
||||
|
||||
// DeleteMember returns a copy of the Baggage with the list-member identified
|
||||
// by key removed.
|
||||
func (b Baggage) DeleteMember(key string) Baggage {
|
||||
n := len(b.list)
|
||||
if _, ok := b.list[key]; ok {
|
||||
n--
|
||||
}
|
||||
list := make(baggage.List, n)
|
||||
|
||||
for k, v := range b.list {
|
||||
if k == key {
|
||||
continue
|
||||
}
|
||||
list[k] = v
|
||||
}
|
||||
|
||||
return Baggage{list: list}
|
||||
}
|
||||
|
||||
// Len returns the number of list-members in the Baggage.
|
||||
func (b Baggage) Len() int {
|
||||
return len(b.list)
|
||||
}
|
||||
|
||||
// String encodes Baggage into a string compliant with the W3C Baggage
|
||||
// specification. The returned string will be invalid if the Baggage contains
|
||||
// any invalid list-members.
|
||||
func (b Baggage) String() string {
|
||||
members := make([]string, 0, len(b.list))
|
||||
for k, v := range b.list {
|
||||
members = append(members, Member{
|
||||
key: k,
|
||||
value: v.Value,
|
||||
properties: fromInternalProperties(v.Properties),
|
||||
}.String())
|
||||
}
|
||||
return strings.Join(members, listDelimiter)
|
||||
}
|
39
vendor/go.opentelemetry.io/otel/baggage/context.go
generated
vendored
Normal file
39
vendor/go.opentelemetry.io/otel/baggage/context.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 baggage // import "go.opentelemetry.io/otel/baggage"
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/internal/baggage"
|
||||
)
|
||||
|
||||
// ContextWithBaggage returns a copy of parent with baggage.
|
||||
func ContextWithBaggage(parent context.Context, b Baggage) context.Context {
|
||||
// Delegate so any hooks for the OpenTracing bridge are handled.
|
||||
return baggage.ContextWithList(parent, b.list)
|
||||
}
|
||||
|
||||
// ContextWithoutBaggage returns a copy of parent with no baggage.
|
||||
func ContextWithoutBaggage(parent context.Context) context.Context {
|
||||
// Delegate so any hooks for the OpenTracing bridge are handled.
|
||||
return baggage.ContextWithList(parent, nil)
|
||||
}
|
||||
|
||||
// FromContext returns the baggage contained in ctx.
|
||||
func FromContext(ctx context.Context) Baggage {
|
||||
// Delegate so any hooks for the OpenTracing bridge are handled.
|
||||
return Baggage{list: baggage.ListFromContext(ctx)}
|
||||
}
|
20
vendor/go.opentelemetry.io/otel/baggage/doc.go
generated
vendored
Normal file
20
vendor/go.opentelemetry.io/otel/baggage/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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 baggage provides functionality for storing and retrieving
|
||||
baggage items in Go context. For propagating the baggage, see the
|
||||
go.opentelemetry.io/otel/propagation package.
|
||||
*/
|
||||
package baggage // import "go.opentelemetry.io/otel/baggage"
|
106
vendor/go.opentelemetry.io/otel/codes/codes.go
generated
vendored
Normal file
106
vendor/go.opentelemetry.io/otel/codes/codes.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// 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 codes // import "go.opentelemetry.io/otel/codes"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
// Unset is the default status code.
|
||||
Unset Code = 0
|
||||
// Error indicates the operation contains an error.
|
||||
Error Code = 1
|
||||
// Ok indicates operation has been validated by an Application developers
|
||||
// or Operator to have completed successfully, or contain no error.
|
||||
Ok Code = 2
|
||||
|
||||
maxCode = 3
|
||||
)
|
||||
|
||||
// Code is an 32-bit representation of a status state.
|
||||
type Code uint32
|
||||
|
||||
var codeToStr = map[Code]string{
|
||||
Unset: "Unset",
|
||||
Error: "Error",
|
||||
Ok: "Ok",
|
||||
}
|
||||
|
||||
var strToCode = map[string]Code{
|
||||
`"Unset"`: Unset,
|
||||
`"Error"`: Error,
|
||||
`"Ok"`: Ok,
|
||||
}
|
||||
|
||||
// String returns the Code as a string.
|
||||
func (c Code) String() string {
|
||||
return codeToStr[c]
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals b into the Code.
|
||||
//
|
||||
// This is based on the functionality in the gRPC codes package:
|
||||
// https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244
|
||||
func (c *Code) UnmarshalJSON(b []byte) error {
|
||||
// From json.Unmarshaler: By convention, to approximate the behavior of
|
||||
// Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as
|
||||
// a no-op.
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
if c == nil {
|
||||
return fmt.Errorf("nil receiver passed to UnmarshalJSON")
|
||||
}
|
||||
|
||||
var x interface{}
|
||||
if err := json.Unmarshal(b, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch x.(type) {
|
||||
case string:
|
||||
if jc, ok := strToCode[string(b)]; ok {
|
||||
*c = jc
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid code: %q", string(b))
|
||||
case float64:
|
||||
if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
|
||||
if ci >= maxCode {
|
||||
return fmt.Errorf("invalid code: %q", ci)
|
||||
}
|
||||
|
||||
*c = Code(ci)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid code: %q", string(b))
|
||||
default:
|
||||
return fmt.Errorf("invalid code: %q", string(b))
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON returns c as the JSON encoding of c.
|
||||
func (c *Code) MarshalJSON() ([]byte, error) {
|
||||
if c == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
str, ok := codeToStr[*c]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid code: %d", *c)
|
||||
}
|
||||
return []byte(fmt.Sprintf("%q", str)), nil
|
||||
}
|
21
vendor/go.opentelemetry.io/otel/codes/doc.go
generated
vendored
Normal file
21
vendor/go.opentelemetry.io/otel/codes/doc.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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 codes defines the canonical error codes used by OpenTelemetry.
|
||||
|
||||
It conforms to [the OpenTelemetry
|
||||
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#statuscanonicalcode).
|
||||
*/
|
||||
package codes // import "go.opentelemetry.io/otel/codes"
|
34
vendor/go.opentelemetry.io/otel/doc.go
generated
vendored
Normal file
34
vendor/go.opentelemetry.io/otel/doc.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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 otel provides global access to the OpenTelemetry API. The subpackages of
|
||||
the otel package provide an implementation of the OpenTelemetry API.
|
||||
|
||||
The provided API is used to instrument code and measure data about that code's
|
||||
performance and operation. The measured data, by default, is not processed or
|
||||
transmitted anywhere. An implementation of the OpenTelemetry SDK, like the
|
||||
default SDK implementation (go.opentelemetry.io/otel/sdk), and associated
|
||||
exporters are used to process and transport this data.
|
||||
|
||||
To read the getting started guide, see https://opentelemetry.io/docs/go/getting-started/.
|
||||
|
||||
To read more about tracing, see go.opentelemetry.io/otel/trace.
|
||||
|
||||
To read more about metrics, see go.opentelemetry.io/otel/metric.
|
||||
|
||||
To read more about propagation, see go.opentelemetry.io/otel/propagation and
|
||||
go.opentelemetry.io/otel/baggage.
|
||||
*/
|
||||
package otel // import "go.opentelemetry.io/otel"
|
38
vendor/go.opentelemetry.io/otel/error_handler.go
generated
vendored
Normal file
38
vendor/go.opentelemetry.io/otel/error_handler.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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 otel // import "go.opentelemetry.io/otel"
|
||||
|
||||
// ErrorHandler handles irremediable events.
|
||||
type ErrorHandler interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Handle handles any error deemed irremediable by an OpenTelemetry
|
||||
// component.
|
||||
Handle(error)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
// ErrorHandlerFunc is a convenience adapter to allow the use of a function
|
||||
// as an ErrorHandler.
|
||||
type ErrorHandlerFunc func(error)
|
||||
|
||||
var _ ErrorHandler = ErrorHandlerFunc(nil)
|
||||
|
||||
// Handle handles the irremediable error by calling the ErrorHandlerFunc itself.
|
||||
func (f ErrorHandlerFunc) Handle(err error) {
|
||||
f(err)
|
||||
}
|
201
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/LICENSE
generated
vendored
Normal file
201
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/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.
|
51
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md
generated
vendored
Normal file
51
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# OpenTelemetry-Go OTLP Span Exporter
|
||||
|
||||
[](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)
|
||||
|
||||
[OpenTelemetry Protocol Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.5.0/specification/protocol/exporter.md) implementation.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
go get -u go.opentelemetry.io/otel/exporters/otlp/otlptrace
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
- [Exporter setup and examples](./otlptracehttp/example_test.go)
|
||||
- [Full example sending telemetry to a local collector](../../../example/otel-collector)
|
||||
|
||||
## [`otlptrace`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)
|
||||
|
||||
The `otlptrace` package provides an exporter implementing the OTel span exporter interface.
|
||||
This exporter is configured using a client satisfying the `otlptrace.Client` interface.
|
||||
This client handles the transformation of data into wire format and the transmission of that data to the collector.
|
||||
|
||||
## [`otlptracegrpc`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc)
|
||||
|
||||
The `otlptracegrpc` package implements a client for the span exporter that sends trace telemetry data to the collector using gRPC with protobuf-encoded payloads.
|
||||
|
||||
## [`otlptracehttp`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp)
|
||||
|
||||
The `otlptracehttp` package implements a client for the span exporter that sends trace telemetry data to the collector using HTTP with protobuf-encoded payloads.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
The following environment variables can be used (instead of options objects) to
|
||||
override the default configuration. For more information about how each of
|
||||
these environment variables is interpreted, see [the OpenTelemetry
|
||||
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/protocol/exporter.md).
|
||||
|
||||
| Environment variable | Option | Default value |
|
||||
| ------------------------------------------------------------------------ |------------------------------ | -------------------------------------------------------- |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | `WithEndpoint` `WithInsecure` | `https://localhost:4317` or `https://localhost:4318`[^1] |
|
||||
| `OTEL_EXPORTER_OTLP_CERTIFICATE` `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | `WithTLSClientConfig` | |
|
||||
| `OTEL_EXPORTER_OTLP_HEADERS` `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | `WithHeaders` | |
|
||||
| `OTEL_EXPORTER_OTLP_COMPRESSION` `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` | `WithCompression` | |
|
||||
| `OTEL_EXPORTER_OTLP_TIMEOUT` `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | `WithTimeout` | `10s` |
|
||||
|
||||
[^1]: The gRPC client defaults to `https://localhost:4317` and the HTTP client `https://localhost:4318`.
|
||||
|
||||
Configuration using options have precedence over the environment variables.
|
54
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go
generated
vendored
Normal file
54
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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 otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
|
||||
)
|
||||
|
||||
// Client manages connections to the collector, handles the
|
||||
// transformation of data into wire format, and the transmission of that
|
||||
// data to the collector.
|
||||
type Client interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Start should establish connection(s) to endpoint(s). It is
|
||||
// called just once by the exporter, so the implementation
|
||||
// does not need to worry about idempotence and locking.
|
||||
Start(ctx context.Context) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Stop should close the connections. The function is called
|
||||
// only once by the exporter, so the implementation does not
|
||||
// need to worry about idempotence, but it may be called
|
||||
// concurrently with UploadTraces, so proper
|
||||
// locking is required. The function serves as a
|
||||
// synchronization point - after the function returns, the
|
||||
// process of closing connections is assumed to be finished.
|
||||
Stop(ctx context.Context) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// UploadTraces should transform the passed traces to the wire
|
||||
// format and send it to the collector. May be called
|
||||
// concurrently.
|
||||
UploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
113
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go
generated
vendored
Normal file
113
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// 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 otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
|
||||
tracesdk "go.opentelemetry.io/otel/sdk/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
errAlreadyStarted = errors.New("already started")
|
||||
)
|
||||
|
||||
// Exporter exports trace data in the OTLP wire format.
|
||||
type Exporter struct {
|
||||
client Client
|
||||
|
||||
mu sync.RWMutex
|
||||
started bool
|
||||
|
||||
startOnce sync.Once
|
||||
stopOnce sync.Once
|
||||
}
|
||||
|
||||
// ExportSpans exports a batch of spans.
|
||||
func (e *Exporter) ExportSpans(ctx context.Context, ss []tracesdk.ReadOnlySpan) error {
|
||||
protoSpans := tracetransform.Spans(ss)
|
||||
if len(protoSpans) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return e.client.UploadTraces(ctx, protoSpans)
|
||||
}
|
||||
|
||||
// Start establishes a connection to the receiving endpoint.
|
||||
func (e *Exporter) Start(ctx context.Context) error {
|
||||
var err = errAlreadyStarted
|
||||
e.startOnce.Do(func() {
|
||||
e.mu.Lock()
|
||||
e.started = true
|
||||
e.mu.Unlock()
|
||||
err = e.client.Start(ctx)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown flushes all exports and closes all connections to the receiving endpoint.
|
||||
func (e *Exporter) Shutdown(ctx context.Context) error {
|
||||
e.mu.RLock()
|
||||
started := e.started
|
||||
e.mu.RUnlock()
|
||||
|
||||
if !started {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
e.stopOnce.Do(func() {
|
||||
err = e.client.Stop(ctx)
|
||||
e.mu.Lock()
|
||||
e.started = false
|
||||
e.mu.Unlock()
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ tracesdk.SpanExporter = (*Exporter)(nil)
|
||||
|
||||
// New constructs a new Exporter and starts it.
|
||||
func New(ctx context.Context, client Client) (*Exporter, error) {
|
||||
exp := NewUnstarted(client)
|
||||
if err := exp.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return exp, nil
|
||||
}
|
||||
|
||||
// NewUnstarted constructs a new Exporter and does not start it.
|
||||
func NewUnstarted(client Client) *Exporter {
|
||||
return &Exporter{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
||||
func (e *Exporter) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Type string
|
||||
Client Client
|
||||
}{
|
||||
Type: "otlptrace",
|
||||
Client: e.client,
|
||||
}
|
||||
}
|
158
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go
generated
vendored
Normal file
158
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
// 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 tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||
)
|
||||
|
||||
// KeyValues transforms a slice of attribute KeyValues into OTLP key-values.
|
||||
func KeyValues(attrs []attribute.KeyValue) []*commonpb.KeyValue {
|
||||
if len(attrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]*commonpb.KeyValue, 0, len(attrs))
|
||||
for _, kv := range attrs {
|
||||
out = append(out, KeyValue(kv))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Iterator transforms an attribute iterator into OTLP key-values.
|
||||
func Iterator(iter attribute.Iterator) []*commonpb.KeyValue {
|
||||
l := iter.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]*commonpb.KeyValue, 0, l)
|
||||
for iter.Next() {
|
||||
out = append(out, KeyValue(iter.Attribute()))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ResourceAttributes transforms a Resource OTLP key-values.
|
||||
func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue {
|
||||
return Iterator(resource.Iter())
|
||||
}
|
||||
|
||||
// KeyValue transforms an attribute KeyValue into an OTLP key-value.
|
||||
func KeyValue(kv attribute.KeyValue) *commonpb.KeyValue {
|
||||
return &commonpb.KeyValue{Key: string(kv.Key), Value: Value(kv.Value)}
|
||||
}
|
||||
|
||||
// Value transforms an attribute Value into an OTLP AnyValue.
|
||||
func Value(v attribute.Value) *commonpb.AnyValue {
|
||||
av := new(commonpb.AnyValue)
|
||||
switch v.Type() {
|
||||
case attribute.BOOL:
|
||||
av.Value = &commonpb.AnyValue_BoolValue{
|
||||
BoolValue: v.AsBool(),
|
||||
}
|
||||
case attribute.BOOLSLICE:
|
||||
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||
ArrayValue: &commonpb.ArrayValue{
|
||||
Values: boolSliceValues(v.AsBoolSlice()),
|
||||
},
|
||||
}
|
||||
case attribute.INT64:
|
||||
av.Value = &commonpb.AnyValue_IntValue{
|
||||
IntValue: v.AsInt64(),
|
||||
}
|
||||
case attribute.INT64SLICE:
|
||||
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||
ArrayValue: &commonpb.ArrayValue{
|
||||
Values: int64SliceValues(v.AsInt64Slice()),
|
||||
},
|
||||
}
|
||||
case attribute.FLOAT64:
|
||||
av.Value = &commonpb.AnyValue_DoubleValue{
|
||||
DoubleValue: v.AsFloat64(),
|
||||
}
|
||||
case attribute.FLOAT64SLICE:
|
||||
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||
ArrayValue: &commonpb.ArrayValue{
|
||||
Values: float64SliceValues(v.AsFloat64Slice()),
|
||||
},
|
||||
}
|
||||
case attribute.STRING:
|
||||
av.Value = &commonpb.AnyValue_StringValue{
|
||||
StringValue: v.AsString(),
|
||||
}
|
||||
case attribute.STRINGSLICE:
|
||||
av.Value = &commonpb.AnyValue_ArrayValue{
|
||||
ArrayValue: &commonpb.ArrayValue{
|
||||
Values: stringSliceValues(v.AsStringSlice()),
|
||||
},
|
||||
}
|
||||
default:
|
||||
av.Value = &commonpb.AnyValue_StringValue{
|
||||
StringValue: "INVALID",
|
||||
}
|
||||
}
|
||||
return av
|
||||
}
|
||||
|
||||
func boolSliceValues(vals []bool) []*commonpb.AnyValue {
|
||||
converted := make([]*commonpb.AnyValue, len(vals))
|
||||
for i, v := range vals {
|
||||
converted[i] = &commonpb.AnyValue{
|
||||
Value: &commonpb.AnyValue_BoolValue{
|
||||
BoolValue: v,
|
||||
},
|
||||
}
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func int64SliceValues(vals []int64) []*commonpb.AnyValue {
|
||||
converted := make([]*commonpb.AnyValue, len(vals))
|
||||
for i, v := range vals {
|
||||
converted[i] = &commonpb.AnyValue{
|
||||
Value: &commonpb.AnyValue_IntValue{
|
||||
IntValue: v,
|
||||
},
|
||||
}
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func float64SliceValues(vals []float64) []*commonpb.AnyValue {
|
||||
converted := make([]*commonpb.AnyValue, len(vals))
|
||||
for i, v := range vals {
|
||||
converted[i] = &commonpb.AnyValue{
|
||||
Value: &commonpb.AnyValue_DoubleValue{
|
||||
DoubleValue: v,
|
||||
},
|
||||
}
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func stringSliceValues(vals []string) []*commonpb.AnyValue {
|
||||
converted := make([]*commonpb.AnyValue, len(vals))
|
||||
for i, v := range vals {
|
||||
converted[i] = &commonpb.AnyValue{
|
||||
Value: &commonpb.AnyValue_StringValue{
|
||||
StringValue: v,
|
||||
},
|
||||
}
|
||||
}
|
||||
return converted
|
||||
}
|
30
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go
generated
vendored
Normal file
30
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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 tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||
)
|
||||
|
||||
func InstrumentationScope(il instrumentation.Library) *commonpb.InstrumentationScope {
|
||||
if il == (instrumentation.Library{}) {
|
||||
return nil
|
||||
}
|
||||
return &commonpb.InstrumentationScope{
|
||||
Name: il.Name,
|
||||
Version: il.Version,
|
||||
}
|
||||
}
|
28
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go
generated
vendored
Normal file
28
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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 tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
resourcepb "go.opentelemetry.io/proto/otlp/resource/v1"
|
||||
)
|
||||
|
||||
// Resource transforms a Resource into an OTLP Resource.
|
||||
func Resource(r *resource.Resource) *resourcepb.Resource {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return &resourcepb.Resource{Attributes: ResourceAttributes(r)}
|
||||
}
|
205
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go
generated
vendored
Normal file
205
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
// 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 tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
tracesdk "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
|
||||
)
|
||||
|
||||
// Spans transforms a slice of OpenTelemetry spans into a slice of OTLP
|
||||
// ResourceSpans.
|
||||
func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
|
||||
if len(sdl) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
rsm := make(map[attribute.Distinct]*tracepb.ResourceSpans)
|
||||
|
||||
type key struct {
|
||||
r attribute.Distinct
|
||||
il instrumentation.Library
|
||||
}
|
||||
ssm := make(map[key]*tracepb.ScopeSpans)
|
||||
|
||||
var resources int
|
||||
for _, sd := range sdl {
|
||||
if sd == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
rKey := sd.Resource().Equivalent()
|
||||
k := key{
|
||||
r: rKey,
|
||||
il: sd.InstrumentationLibrary(),
|
||||
}
|
||||
scopeSpan, iOk := ssm[k]
|
||||
if !iOk {
|
||||
// Either the resource or instrumentation library were unknown.
|
||||
scopeSpan = &tracepb.ScopeSpans{
|
||||
Scope: InstrumentationScope(sd.InstrumentationLibrary()),
|
||||
Spans: []*tracepb.Span{},
|
||||
SchemaUrl: sd.InstrumentationLibrary().SchemaURL,
|
||||
}
|
||||
}
|
||||
scopeSpan.Spans = append(scopeSpan.Spans, span(sd))
|
||||
ssm[k] = scopeSpan
|
||||
|
||||
rs, rOk := rsm[rKey]
|
||||
if !rOk {
|
||||
resources++
|
||||
// The resource was unknown.
|
||||
rs = &tracepb.ResourceSpans{
|
||||
Resource: Resource(sd.Resource()),
|
||||
ScopeSpans: []*tracepb.ScopeSpans{scopeSpan},
|
||||
SchemaUrl: sd.Resource().SchemaURL(),
|
||||
}
|
||||
rsm[rKey] = rs
|
||||
continue
|
||||
}
|
||||
|
||||
// The resource has been seen before. Check if the instrumentation
|
||||
// library lookup was unknown because if so we need to add it to the
|
||||
// ResourceSpans. Otherwise, the instrumentation library has already
|
||||
// been seen and the append we did above will be included it in the
|
||||
// ScopeSpans reference.
|
||||
if !iOk {
|
||||
rs.ScopeSpans = append(rs.ScopeSpans, scopeSpan)
|
||||
}
|
||||
}
|
||||
|
||||
// Transform the categorized map into a slice
|
||||
rss := make([]*tracepb.ResourceSpans, 0, resources)
|
||||
for _, rs := range rsm {
|
||||
rss = append(rss, rs)
|
||||
}
|
||||
return rss
|
||||
}
|
||||
|
||||
// span transforms a Span into an OTLP span.
|
||||
func span(sd tracesdk.ReadOnlySpan) *tracepb.Span {
|
||||
if sd == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
tid := sd.SpanContext().TraceID()
|
||||
sid := sd.SpanContext().SpanID()
|
||||
|
||||
s := &tracepb.Span{
|
||||
TraceId: tid[:],
|
||||
SpanId: sid[:],
|
||||
TraceState: sd.SpanContext().TraceState().String(),
|
||||
Status: status(sd.Status().Code, sd.Status().Description),
|
||||
StartTimeUnixNano: uint64(sd.StartTime().UnixNano()),
|
||||
EndTimeUnixNano: uint64(sd.EndTime().UnixNano()),
|
||||
Links: links(sd.Links()),
|
||||
Kind: spanKind(sd.SpanKind()),
|
||||
Name: sd.Name(),
|
||||
Attributes: KeyValues(sd.Attributes()),
|
||||
Events: spanEvents(sd.Events()),
|
||||
DroppedAttributesCount: uint32(sd.DroppedAttributes()),
|
||||
DroppedEventsCount: uint32(sd.DroppedEvents()),
|
||||
DroppedLinksCount: uint32(sd.DroppedLinks()),
|
||||
}
|
||||
|
||||
if psid := sd.Parent().SpanID(); psid.IsValid() {
|
||||
s.ParentSpanId = psid[:]
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// status transform a span code and message into an OTLP span status.
|
||||
func status(status codes.Code, message string) *tracepb.Status {
|
||||
var c tracepb.Status_StatusCode
|
||||
switch status {
|
||||
case codes.Ok:
|
||||
c = tracepb.Status_STATUS_CODE_OK
|
||||
case codes.Error:
|
||||
c = tracepb.Status_STATUS_CODE_ERROR
|
||||
default:
|
||||
c = tracepb.Status_STATUS_CODE_UNSET
|
||||
}
|
||||
return &tracepb.Status{
|
||||
Code: c,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// links transforms span Links to OTLP span links.
|
||||
func links(links []tracesdk.Link) []*tracepb.Span_Link {
|
||||
if len(links) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sl := make([]*tracepb.Span_Link, 0, len(links))
|
||||
for _, otLink := range links {
|
||||
// This redefinition is necessary to prevent otLink.*ID[:] copies
|
||||
// being reused -- in short we need a new otLink per iteration.
|
||||
otLink := otLink
|
||||
|
||||
tid := otLink.SpanContext.TraceID()
|
||||
sid := otLink.SpanContext.SpanID()
|
||||
|
||||
sl = append(sl, &tracepb.Span_Link{
|
||||
TraceId: tid[:],
|
||||
SpanId: sid[:],
|
||||
Attributes: KeyValues(otLink.Attributes),
|
||||
DroppedAttributesCount: uint32(otLink.DroppedAttributeCount),
|
||||
})
|
||||
}
|
||||
return sl
|
||||
}
|
||||
|
||||
// spanEvents transforms span Events to an OTLP span events.
|
||||
func spanEvents(es []tracesdk.Event) []*tracepb.Span_Event {
|
||||
if len(es) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
events := make([]*tracepb.Span_Event, len(es))
|
||||
// Transform message events
|
||||
for i := 0; i < len(es); i++ {
|
||||
events[i] = &tracepb.Span_Event{
|
||||
Name: es[i].Name,
|
||||
TimeUnixNano: uint64(es[i].Time.UnixNano()),
|
||||
Attributes: KeyValues(es[i].Attributes),
|
||||
DroppedAttributesCount: uint32(es[i].DroppedAttributeCount),
|
||||
}
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
// spanKind transforms a SpanKind to an OTLP span kind.
|
||||
func spanKind(kind trace.SpanKind) tracepb.Span_SpanKind {
|
||||
switch kind {
|
||||
case trace.SpanKindInternal:
|
||||
return tracepb.Span_SPAN_KIND_INTERNAL
|
||||
case trace.SpanKindClient:
|
||||
return tracepb.Span_SPAN_KIND_CLIENT
|
||||
case trace.SpanKindServer:
|
||||
return tracepb.Span_SPAN_KIND_SERVER
|
||||
case trace.SpanKindProducer:
|
||||
return tracepb.Span_SPAN_KIND_PRODUCER
|
||||
case trace.SpanKindConsumer:
|
||||
return tracepb.Span_SPAN_KIND_CONSUMER
|
||||
default:
|
||||
return tracepb.Span_SPAN_KIND_UNSPECIFIED
|
||||
}
|
||||
}
|
41
vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
generated
vendored
Normal file
41
vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# 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.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
top_dir='.'
|
||||
if [[ $# -gt 0 ]]; then
|
||||
top_dir="${1}"
|
||||
fi
|
||||
|
||||
p=$(pwd)
|
||||
mod_dirs=()
|
||||
|
||||
# Note `mapfile` does not exist in older bash versions:
|
||||
# https://stackoverflow.com/questions/41475261/need-alternative-to-readarray-mapfile-for-script-on-older-version-of-bash
|
||||
|
||||
while IFS= read -r line; do
|
||||
mod_dirs+=("$line")
|
||||
done < <(find "${top_dir}" -type f -name 'go.mod' -exec dirname {} \; | sort)
|
||||
|
||||
for mod_dir in "${mod_dirs[@]}"; do
|
||||
cd "${mod_dir}"
|
||||
|
||||
while IFS= read -r line; do
|
||||
echo ".${line#${p}}"
|
||||
done < <(go list --find -f '{{.Name}}|{{.Dir}}' ./... | grep '^main|' | cut -f 2- -d '|')
|
||||
cd "${p}"
|
||||
done
|
98
vendor/go.opentelemetry.io/otel/handler.go
generated
vendored
Normal file
98
vendor/go.opentelemetry.io/otel/handler.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// 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 otel // import "go.opentelemetry.io/otel"
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// globalErrorHandler provides an ErrorHandler that can be used
|
||||
// throughout an OpenTelemetry instrumented project. When a user
|
||||
// specified ErrorHandler is registered (`SetErrorHandler`) all calls to
|
||||
// `Handle` and will be delegated to the registered ErrorHandler.
|
||||
globalErrorHandler = defaultErrorHandler()
|
||||
|
||||
// Compile-time check that delegator implements ErrorHandler.
|
||||
_ ErrorHandler = (*delegator)(nil)
|
||||
// Compile-time check that errLogger implements ErrorHandler.
|
||||
_ ErrorHandler = (*errLogger)(nil)
|
||||
)
|
||||
|
||||
type delegator struct {
|
||||
lock *sync.RWMutex
|
||||
eh ErrorHandler
|
||||
}
|
||||
|
||||
func (d *delegator) Handle(err error) {
|
||||
d.lock.RLock()
|
||||
defer d.lock.RUnlock()
|
||||
d.eh.Handle(err)
|
||||
}
|
||||
|
||||
// setDelegate sets the ErrorHandler delegate.
|
||||
func (d *delegator) setDelegate(eh ErrorHandler) {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
d.eh = eh
|
||||
}
|
||||
|
||||
func defaultErrorHandler() *delegator {
|
||||
return &delegator{
|
||||
lock: &sync.RWMutex{},
|
||||
eh: &errLogger{l: log.New(os.Stderr, "", log.LstdFlags)},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// errLogger logs errors if no delegate is set, otherwise they are delegated.
|
||||
type errLogger struct {
|
||||
l *log.Logger
|
||||
}
|
||||
|
||||
// Handle logs err if no delegate is set, otherwise it is delegated.
|
||||
func (h *errLogger) Handle(err error) {
|
||||
h.l.Print(err)
|
||||
}
|
||||
|
||||
// GetErrorHandler returns the global ErrorHandler instance.
|
||||
//
|
||||
// The default ErrorHandler instance returned will log all errors to STDERR
|
||||
// until an override ErrorHandler is set with SetErrorHandler. All
|
||||
// ErrorHandler returned prior to this will automatically forward errors to
|
||||
// the set instance instead of logging.
|
||||
//
|
||||
// Subsequent calls to SetErrorHandler after the first will not forward errors
|
||||
// to the new ErrorHandler for prior returned instances.
|
||||
func GetErrorHandler() ErrorHandler {
|
||||
return globalErrorHandler
|
||||
}
|
||||
|
||||
// SetErrorHandler sets the global ErrorHandler to h.
|
||||
//
|
||||
// The first time this is called all ErrorHandler previously returned from
|
||||
// GetErrorHandler will send errors to h instead of the default logging
|
||||
// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
|
||||
// delegate errors to h.
|
||||
func SetErrorHandler(h ErrorHandler) {
|
||||
globalErrorHandler.setDelegate(h)
|
||||
}
|
||||
|
||||
// Handle is a convenience function for ErrorHandler().Handle(err)
|
||||
func Handle(err error) {
|
||||
GetErrorHandler().Handle(err)
|
||||
}
|
43
vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
generated
vendored
Normal file
43
vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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 baggage provides base types and functionality to store and retrieve
|
||||
baggage in Go context. This package exists because the OpenTracing bridge to
|
||||
OpenTelemetry needs to synchronize state whenever baggage for a context is
|
||||
modified and that context contains an OpenTracing span. If it were not for
|
||||
this need this package would not need to exist and the
|
||||
`go.opentelemetry.io/otel/baggage` package would be the singular place where
|
||||
W3C baggage is handled.
|
||||
*/
|
||||
package baggage // import "go.opentelemetry.io/otel/internal/baggage"
|
||||
|
||||
// List is the collection of baggage members. The W3C allows for duplicates,
|
||||
// but OpenTelemetry does not, therefore, this is represented as a map.
|
||||
type List map[string]Item
|
||||
|
||||
// Item is the value and metadata properties part of a list-member.
|
||||
type Item struct {
|
||||
Value string
|
||||
Properties []Property
|
||||
}
|
||||
|
||||
// Property is a metadata entry for a list-member.
|
||||
type Property struct {
|
||||
Key, Value string
|
||||
|
||||
// HasValue indicates if a zero-value value means the property does not
|
||||
// have a value or if it was the zero-value.
|
||||
HasValue bool
|
||||
}
|
95
vendor/go.opentelemetry.io/otel/internal/baggage/context.go
generated
vendored
Normal file
95
vendor/go.opentelemetry.io/otel/internal/baggage/context.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// 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 baggage // import "go.opentelemetry.io/otel/internal/baggage"
|
||||
|
||||
import "context"
|
||||
|
||||
type baggageContextKeyType int
|
||||
|
||||
const baggageKey baggageContextKeyType = iota
|
||||
|
||||
// SetHookFunc is a callback called when storing baggage in the context.
|
||||
type SetHookFunc func(context.Context, List) context.Context
|
||||
|
||||
// GetHookFunc is a callback called when getting baggage from the context.
|
||||
type GetHookFunc func(context.Context, List) List
|
||||
|
||||
type baggageState struct {
|
||||
list List
|
||||
|
||||
setHook SetHookFunc
|
||||
getHook GetHookFunc
|
||||
}
|
||||
|
||||
// ContextWithSetHook returns a copy of parent with hook configured to be
|
||||
// invoked every time ContextWithBaggage is called.
|
||||
//
|
||||
// Passing nil SetHookFunc creates a context with no set hook to call.
|
||||
func ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context {
|
||||
var s baggageState
|
||||
switch v := parent.Value(baggageKey).(type) {
|
||||
case baggageState:
|
||||
s = v
|
||||
}
|
||||
|
||||
s.setHook = hook
|
||||
return context.WithValue(parent, baggageKey, s)
|
||||
}
|
||||
|
||||
// ContextWithGetHook returns a copy of parent with hook configured to be
|
||||
// invoked every time FromContext is called.
|
||||
//
|
||||
// Passing nil GetHookFunc creates a context with no get hook to call.
|
||||
func ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context {
|
||||
var s baggageState
|
||||
switch v := parent.Value(baggageKey).(type) {
|
||||
case baggageState:
|
||||
s = v
|
||||
}
|
||||
|
||||
s.getHook = hook
|
||||
return context.WithValue(parent, baggageKey, s)
|
||||
}
|
||||
|
||||
// ContextWithList returns a copy of parent with baggage. Passing nil list
|
||||
// returns a context without any baggage.
|
||||
func ContextWithList(parent context.Context, list List) context.Context {
|
||||
var s baggageState
|
||||
switch v := parent.Value(baggageKey).(type) {
|
||||
case baggageState:
|
||||
s = v
|
||||
}
|
||||
|
||||
s.list = list
|
||||
ctx := context.WithValue(parent, baggageKey, s)
|
||||
if s.setHook != nil {
|
||||
ctx = s.setHook(ctx, list)
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
// ListFromContext returns the baggage contained in ctx.
|
||||
func ListFromContext(ctx context.Context) List {
|
||||
switch v := ctx.Value(baggageKey).(type) {
|
||||
case baggageState:
|
||||
if v.getHook != nil {
|
||||
return v.getHook(ctx, v.list)
|
||||
}
|
||||
return v.list
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
63
vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
generated
vendored
Normal file
63
vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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 global // import "go.opentelemetry.io/otel/internal/global"
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/go-logr/stdr"
|
||||
)
|
||||
|
||||
// globalLogger is the logging interface used within the otel api and sdk provide deatails of the internals.
|
||||
//
|
||||
// The default logger uses stdr which is backed by the standard `log.Logger`
|
||||
// interface. This logger will only show messages at the Error Level.
|
||||
var globalLogger logr.Logger = stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))
|
||||
var globalLoggerLock = &sync.RWMutex{}
|
||||
|
||||
// SetLogger overrides the globalLogger with l.
|
||||
//
|
||||
// To see Info messages use a logger with `l.V(1).Enabled() == true`
|
||||
// To see Debug messages use a logger with `l.V(5).Enabled() == true`
|
||||
func SetLogger(l logr.Logger) {
|
||||
globalLoggerLock.Lock()
|
||||
defer globalLoggerLock.Unlock()
|
||||
globalLogger = l
|
||||
}
|
||||
|
||||
// Info prints messages about the general state of the API or SDK.
|
||||
// This should usually be less then 5 messages a minute
|
||||
func Info(msg string, keysAndValues ...interface{}) {
|
||||
globalLoggerLock.RLock()
|
||||
defer globalLoggerLock.RUnlock()
|
||||
globalLogger.V(1).Info(msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// Error prints messages about exceptional states of the API or SDK.
|
||||
func Error(err error, msg string, keysAndValues ...interface{}) {
|
||||
globalLoggerLock.RLock()
|
||||
defer globalLoggerLock.RUnlock()
|
||||
globalLogger.Error(err, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// Debug prints messages about all internal changes in the API or SDK.
|
||||
func Debug(msg string, keysAndValues ...interface{}) {
|
||||
globalLoggerLock.RLock()
|
||||
defer globalLoggerLock.RUnlock()
|
||||
globalLogger.V(5).Info(msg, keysAndValues...)
|
||||
}
|
82
vendor/go.opentelemetry.io/otel/internal/global/propagator.go
generated
vendored
Normal file
82
vendor/go.opentelemetry.io/otel/internal/global/propagator.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// 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 global // import "go.opentelemetry.io/otel/internal/global"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
)
|
||||
|
||||
// textMapPropagator is a default TextMapPropagator that delegates calls to a
|
||||
// registered delegate if one is set, otherwise it defaults to delegating the
|
||||
// calls to a the default no-op propagation.TextMapPropagator.
|
||||
type textMapPropagator struct {
|
||||
mtx sync.Mutex
|
||||
once sync.Once
|
||||
delegate propagation.TextMapPropagator
|
||||
noop propagation.TextMapPropagator
|
||||
}
|
||||
|
||||
// Compile-time guarantee that textMapPropagator implements the
|
||||
// propagation.TextMapPropagator interface.
|
||||
var _ propagation.TextMapPropagator = (*textMapPropagator)(nil)
|
||||
|
||||
func newTextMapPropagator() *textMapPropagator {
|
||||
return &textMapPropagator{
|
||||
noop: propagation.NewCompositeTextMapPropagator(),
|
||||
}
|
||||
}
|
||||
|
||||
// SetDelegate sets a delegate propagation.TextMapPropagator that all calls are
|
||||
// forwarded to. Delegation can only be performed once, all subsequent calls
|
||||
// perform no delegation.
|
||||
func (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {
|
||||
if delegate == nil {
|
||||
return
|
||||
}
|
||||
|
||||
p.mtx.Lock()
|
||||
p.once.Do(func() { p.delegate = delegate })
|
||||
p.mtx.Unlock()
|
||||
}
|
||||
|
||||
// effectiveDelegate returns the current delegate of p if one is set,
|
||||
// otherwise the default noop TextMapPropagator is returned. This method
|
||||
// can be called concurrently.
|
||||
func (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {
|
||||
p.mtx.Lock()
|
||||
defer p.mtx.Unlock()
|
||||
if p.delegate != nil {
|
||||
return p.delegate
|
||||
}
|
||||
return p.noop
|
||||
}
|
||||
|
||||
// Inject set cross-cutting concerns from the Context into the carrier.
|
||||
func (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
|
||||
p.effectiveDelegate().Inject(ctx, carrier)
|
||||
}
|
||||
|
||||
// Extract reads cross-cutting concerns from the carrier into a Context.
|
||||
func (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
|
||||
return p.effectiveDelegate().Extract(ctx, carrier)
|
||||
}
|
||||
|
||||
// Fields returns the keys whose values are set with Inject.
|
||||
func (p *textMapPropagator) Fields() []string {
|
||||
return p.effectiveDelegate().Fields()
|
||||
}
|
127
vendor/go.opentelemetry.io/otel/internal/global/state.go
generated
vendored
Normal file
127
vendor/go.opentelemetry.io/otel/internal/global/state.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// 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 global // import "go.opentelemetry.io/otel/internal/global"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type (
|
||||
tracerProviderHolder struct {
|
||||
tp trace.TracerProvider
|
||||
}
|
||||
|
||||
propagatorsHolder struct {
|
||||
tm propagation.TextMapPropagator
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
globalTracer = defaultTracerValue()
|
||||
globalPropagators = defaultPropagatorsValue()
|
||||
|
||||
delegateTraceOnce sync.Once
|
||||
delegateTextMapPropagatorOnce sync.Once
|
||||
)
|
||||
|
||||
// TracerProvider is the internal implementation for global.TracerProvider.
|
||||
func TracerProvider() trace.TracerProvider {
|
||||
return globalTracer.Load().(tracerProviderHolder).tp
|
||||
}
|
||||
|
||||
// SetTracerProvider is the internal implementation for global.SetTracerProvider.
|
||||
func SetTracerProvider(tp trace.TracerProvider) {
|
||||
current := TracerProvider()
|
||||
|
||||
if _, cOk := current.(*tracerProvider); cOk {
|
||||
if _, tpOk := tp.(*tracerProvider); tpOk && current == tp {
|
||||
// Do not assign the default delegating TracerProvider to delegate
|
||||
// to itself.
|
||||
Error(
|
||||
errors.New("no delegate configured in tracer provider"),
|
||||
"Setting tracer provider to it's current value. No delegate will be configured",
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
delegateTraceOnce.Do(func() {
|
||||
if def, ok := current.(*tracerProvider); ok {
|
||||
def.setDelegate(tp)
|
||||
}
|
||||
})
|
||||
globalTracer.Store(tracerProviderHolder{tp: tp})
|
||||
}
|
||||
|
||||
// TextMapPropagator is the internal implementation for global.TextMapPropagator.
|
||||
func TextMapPropagator() propagation.TextMapPropagator {
|
||||
return globalPropagators.Load().(propagatorsHolder).tm
|
||||
}
|
||||
|
||||
// SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.
|
||||
func SetTextMapPropagator(p propagation.TextMapPropagator) {
|
||||
current := TextMapPropagator()
|
||||
|
||||
if _, cOk := current.(*textMapPropagator); cOk {
|
||||
if _, pOk := p.(*textMapPropagator); pOk && current == p {
|
||||
// Do not assign the default delegating TextMapPropagator to
|
||||
// delegate to itself.
|
||||
Error(
|
||||
errors.New("no delegate configured in text map propagator"),
|
||||
"Setting text map propagator to it's current value. No delegate will be configured",
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// For the textMapPropagator already returned by TextMapPropagator
|
||||
// delegate to p.
|
||||
delegateTextMapPropagatorOnce.Do(func() {
|
||||
if def, ok := current.(*textMapPropagator); ok {
|
||||
def.SetDelegate(p)
|
||||
}
|
||||
})
|
||||
// Return p when subsequent calls to TextMapPropagator are made.
|
||||
globalPropagators.Store(propagatorsHolder{tm: p})
|
||||
}
|
||||
|
||||
func defaultTracerValue() *atomic.Value {
|
||||
v := &atomic.Value{}
|
||||
v.Store(tracerProviderHolder{tp: &tracerProvider{}})
|
||||
return v
|
||||
}
|
||||
|
||||
func defaultPropagatorsValue() *atomic.Value {
|
||||
v := &atomic.Value{}
|
||||
v.Store(propagatorsHolder{tm: newTextMapPropagator()})
|
||||
return v
|
||||
}
|
||||
|
||||
// ResetForTest configures the test to restores the initial global state during
|
||||
// its Cleanup step
|
||||
func ResetForTest(t testing.TB) {
|
||||
t.Cleanup(func() {
|
||||
globalTracer = defaultTracerValue()
|
||||
globalPropagators = defaultPropagatorsValue()
|
||||
delegateTraceOnce = sync.Once{}
|
||||
delegateTextMapPropagatorOnce = sync.Once{}
|
||||
})
|
||||
}
|
192
vendor/go.opentelemetry.io/otel/internal/global/trace.go
generated
vendored
Normal file
192
vendor/go.opentelemetry.io/otel/internal/global/trace.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// 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 global // import "go.opentelemetry.io/otel/internal/global"
|
||||
|
||||
/*
|
||||
This file contains the forwarding implementation of the TracerProvider used as
|
||||
the default global instance. Prior to initialization of an SDK, Tracers
|
||||
returned by the global TracerProvider will provide no-op functionality. This
|
||||
means that all Span created prior to initialization are no-op Spans.
|
||||
|
||||
Once an SDK has been initialized, all provided no-op Tracers are swapped for
|
||||
Tracers provided by the SDK defined TracerProvider. However, any Span started
|
||||
prior to this initialization does not change its behavior. Meaning, the Span
|
||||
remains a no-op Span.
|
||||
|
||||
The implementation to track and swap Tracers locks all new Tracer creation
|
||||
until the swap is complete. This assumes that this operation is not
|
||||
performance-critical. If that assumption is incorrect, be sure to configure an
|
||||
SDK prior to any Tracer creation.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// tracerProvider is a placeholder for a configured SDK TracerProvider.
|
||||
//
|
||||
// All TracerProvider functionality is forwarded to a delegate once
|
||||
// configured.
|
||||
type tracerProvider struct {
|
||||
mtx sync.Mutex
|
||||
tracers map[il]*tracer
|
||||
delegate trace.TracerProvider
|
||||
}
|
||||
|
||||
// Compile-time guarantee that tracerProvider implements the TracerProvider
|
||||
// interface.
|
||||
var _ trace.TracerProvider = &tracerProvider{}
|
||||
|
||||
// setDelegate configures p to delegate all TracerProvider functionality to
|
||||
// provider.
|
||||
//
|
||||
// All Tracers provided prior to this function call are switched out to be
|
||||
// Tracers provided by provider.
|
||||
//
|
||||
// It is guaranteed by the caller that this happens only once.
|
||||
func (p *tracerProvider) setDelegate(provider trace.TracerProvider) {
|
||||
p.mtx.Lock()
|
||||
defer p.mtx.Unlock()
|
||||
|
||||
p.delegate = provider
|
||||
|
||||
if len(p.tracers) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, t := range p.tracers {
|
||||
t.setDelegate(provider)
|
||||
}
|
||||
|
||||
p.tracers = nil
|
||||
}
|
||||
|
||||
// Tracer implements TracerProvider.
|
||||
func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
|
||||
p.mtx.Lock()
|
||||
defer p.mtx.Unlock()
|
||||
|
||||
if p.delegate != nil {
|
||||
return p.delegate.Tracer(name, opts...)
|
||||
}
|
||||
|
||||
// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.
|
||||
|
||||
c := trace.NewTracerConfig(opts...)
|
||||
key := il{
|
||||
name: name,
|
||||
version: c.InstrumentationVersion(),
|
||||
}
|
||||
|
||||
if p.tracers == nil {
|
||||
p.tracers = make(map[il]*tracer)
|
||||
}
|
||||
|
||||
if val, ok := p.tracers[key]; ok {
|
||||
return val
|
||||
}
|
||||
|
||||
t := &tracer{name: name, opts: opts, provider: p}
|
||||
p.tracers[key] = t
|
||||
return t
|
||||
}
|
||||
|
||||
type il struct {
|
||||
name string
|
||||
version string
|
||||
}
|
||||
|
||||
// tracer is a placeholder for a trace.Tracer.
|
||||
//
|
||||
// All Tracer functionality is forwarded to a delegate once configured.
|
||||
// Otherwise, all functionality is forwarded to a NoopTracer.
|
||||
type tracer struct {
|
||||
name string
|
||||
opts []trace.TracerOption
|
||||
provider *tracerProvider
|
||||
|
||||
delegate atomic.Value
|
||||
}
|
||||
|
||||
// Compile-time guarantee that tracer implements the trace.Tracer interface.
|
||||
var _ trace.Tracer = &tracer{}
|
||||
|
||||
// setDelegate configures t to delegate all Tracer functionality to Tracers
|
||||
// created by provider.
|
||||
//
|
||||
// All subsequent calls to the Tracer methods will be passed to the delegate.
|
||||
//
|
||||
// It is guaranteed by the caller that this happens only once.
|
||||
func (t *tracer) setDelegate(provider trace.TracerProvider) {
|
||||
t.delegate.Store(provider.Tracer(t.name, t.opts...))
|
||||
}
|
||||
|
||||
// Start implements trace.Tracer by forwarding the call to t.delegate if
|
||||
// set, otherwise it forwards the call to a NoopTracer.
|
||||
func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
||||
delegate := t.delegate.Load()
|
||||
if delegate != nil {
|
||||
return delegate.(trace.Tracer).Start(ctx, name, opts...)
|
||||
}
|
||||
|
||||
s := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t}
|
||||
ctx = trace.ContextWithSpan(ctx, s)
|
||||
return ctx, s
|
||||
}
|
||||
|
||||
// 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 {
|
||||
sc trace.SpanContext
|
||||
tracer *tracer
|
||||
}
|
||||
|
||||
var _ trace.Span = nonRecordingSpan{}
|
||||
|
||||
// SpanContext returns the wrapped SpanContext.
|
||||
func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
|
||||
|
||||
// IsRecording always returns false.
|
||||
func (nonRecordingSpan) IsRecording() bool { return false }
|
||||
|
||||
// SetStatus does nothing.
|
||||
func (nonRecordingSpan) SetStatus(codes.Code, string) {}
|
||||
|
||||
// SetError does nothing.
|
||||
func (nonRecordingSpan) SetError(bool) {}
|
||||
|
||||
// SetAttributes does nothing.
|
||||
func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
|
||||
|
||||
// End does nothing.
|
||||
func (nonRecordingSpan) End(...trace.SpanEndOption) {}
|
||||
|
||||
// RecordError does nothing.
|
||||
func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
|
||||
|
||||
// AddEvent does nothing.
|
||||
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
|
||||
|
||||
// SetName does nothing.
|
||||
func (nonRecordingSpan) SetName(string) {}
|
||||
|
||||
func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
|
55
vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
generated
vendored
Normal file
55
vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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 internal // import "go.opentelemetry.io/otel/internal"
|
||||
|
||||
import (
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func BoolToRaw(b bool) uint64 {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func RawToBool(r uint64) bool {
|
||||
return r != 0
|
||||
}
|
||||
|
||||
func Int64ToRaw(i int64) uint64 {
|
||||
return uint64(i)
|
||||
}
|
||||
|
||||
func RawToInt64(r uint64) int64 {
|
||||
return int64(r)
|
||||
}
|
||||
|
||||
func Float64ToRaw(f float64) uint64 {
|
||||
return math.Float64bits(f)
|
||||
}
|
||||
|
||||
func RawToFloat64(r uint64) float64 {
|
||||
return math.Float64frombits(r)
|
||||
}
|
||||
|
||||
func RawPtrToFloat64Ptr(r *uint64) *float64 {
|
||||
return (*float64)(unsafe.Pointer(r))
|
||||
}
|
||||
|
||||
func RawPtrToInt64Ptr(r *uint64) *int64 {
|
||||
return (*int64)(unsafe.Pointer(r))
|
||||
}
|
26
vendor/go.opentelemetry.io/otel/internal_logging.go
generated
vendored
Normal file
26
vendor/go.opentelemetry.io/otel/internal_logging.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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 otel // import "go.opentelemetry.io/otel"
|
||||
|
||||
import (
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
)
|
||||
|
||||
// SetLogger configures the logger used internally to opentelemetry.
|
||||
func SetLogger(logger logr.Logger) {
|
||||
global.SetLogger(logger)
|
||||
}
|
31
vendor/go.opentelemetry.io/otel/propagation.go
generated
vendored
Normal file
31
vendor/go.opentelemetry.io/otel/propagation.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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 otel // import "go.opentelemetry.io/otel"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
)
|
||||
|
||||
// GetTextMapPropagator returns the global TextMapPropagator. If none has been
|
||||
// set, a No-Op TextMapPropagator is returned.
|
||||
func GetTextMapPropagator() propagation.TextMapPropagator {
|
||||
return global.TextMapPropagator()
|
||||
}
|
||||
|
||||
// SetTextMapPropagator sets propagator as the global TextMapPropagator.
|
||||
func SetTextMapPropagator(propagator propagation.TextMapPropagator) {
|
||||
global.SetTextMapPropagator(propagator)
|
||||
}
|
58
vendor/go.opentelemetry.io/otel/propagation/baggage.go
generated
vendored
Normal file
58
vendor/go.opentelemetry.io/otel/propagation/baggage.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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 propagation // import "go.opentelemetry.io/otel/propagation"
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/baggage"
|
||||
)
|
||||
|
||||
const baggageHeader = "baggage"
|
||||
|
||||
// Baggage is a propagator that supports the W3C Baggage format.
|
||||
//
|
||||
// This propagates user-defined baggage associated with a trace. The complete
|
||||
// specification is defined at https://www.w3.org/TR/baggage/.
|
||||
type Baggage struct{}
|
||||
|
||||
var _ TextMapPropagator = Baggage{}
|
||||
|
||||
// Inject sets baggage key-values from ctx into the carrier.
|
||||
func (b Baggage) Inject(ctx context.Context, carrier TextMapCarrier) {
|
||||
bStr := baggage.FromContext(ctx).String()
|
||||
if bStr != "" {
|
||||
carrier.Set(baggageHeader, bStr)
|
||||
}
|
||||
}
|
||||
|
||||
// Extract returns a copy of parent with the baggage from the carrier added.
|
||||
func (b Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context {
|
||||
bStr := carrier.Get(baggageHeader)
|
||||
if bStr == "" {
|
||||
return parent
|
||||
}
|
||||
|
||||
bag, err := baggage.Parse(bStr)
|
||||
if err != nil {
|
||||
return parent
|
||||
}
|
||||
return baggage.ContextWithBaggage(parent, bag)
|
||||
}
|
||||
|
||||
// Fields returns the keys who's values are set with Inject.
|
||||
func (b Baggage) Fields() []string {
|
||||
return []string{baggageHeader}
|
||||
}
|
24
vendor/go.opentelemetry.io/otel/propagation/doc.go
generated
vendored
Normal file
24
vendor/go.opentelemetry.io/otel/propagation/doc.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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 propagation contains OpenTelemetry context propagators.
|
||||
|
||||
OpenTelemetry propagators are used to extract and inject context data from and
|
||||
into messages exchanged by applications. The propagator supported by this
|
||||
package is the W3C Trace Context encoding
|
||||
(https://www.w3.org/TR/trace-context/), and W3C Baggage
|
||||
(https://www.w3.org/TR/baggage/).
|
||||
*/
|
||||
package propagation // import "go.opentelemetry.io/otel/propagation"
|
153
vendor/go.opentelemetry.io/otel/propagation/propagation.go
generated
vendored
Normal file
153
vendor/go.opentelemetry.io/otel/propagation/propagation.go
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
// 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 propagation // import "go.opentelemetry.io/otel/propagation"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// TextMapCarrier is the storage medium used by a TextMapPropagator.
|
||||
type TextMapCarrier interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Get returns the value associated with the passed key.
|
||||
Get(key string) string
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Set stores the key-value pair.
|
||||
Set(key string, value string)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Keys lists the keys stored in this carrier.
|
||||
Keys() []string
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage
|
||||
// medium for propagated key-value pairs.
|
||||
type MapCarrier map[string]string
|
||||
|
||||
// Compile time check that MapCarrier implements the TextMapCarrier.
|
||||
var _ TextMapCarrier = MapCarrier{}
|
||||
|
||||
// Get returns the value associated with the passed key.
|
||||
func (c MapCarrier) Get(key string) string {
|
||||
return c[key]
|
||||
}
|
||||
|
||||
// Set stores the key-value pair.
|
||||
func (c MapCarrier) Set(key, value string) {
|
||||
c[key] = value
|
||||
}
|
||||
|
||||
// Keys lists the keys stored in this carrier.
|
||||
func (c MapCarrier) Keys() []string {
|
||||
keys := make([]string, 0, len(c))
|
||||
for k := range c {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier interface.
|
||||
type HeaderCarrier http.Header
|
||||
|
||||
// Get returns the value associated with the passed key.
|
||||
func (hc HeaderCarrier) Get(key string) string {
|
||||
return http.Header(hc).Get(key)
|
||||
}
|
||||
|
||||
// Set stores the key-value pair.
|
||||
func (hc HeaderCarrier) Set(key string, value string) {
|
||||
http.Header(hc).Set(key, value)
|
||||
}
|
||||
|
||||
// Keys lists the keys stored in this carrier.
|
||||
func (hc HeaderCarrier) Keys() []string {
|
||||
keys := make([]string, 0, len(hc))
|
||||
for k := range hc {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// TextMapPropagator propagates cross-cutting concerns as key-value text
|
||||
// pairs within a carrier that travels in-band across process boundaries.
|
||||
type TextMapPropagator interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Inject set cross-cutting concerns from the Context into the carrier.
|
||||
Inject(ctx context.Context, carrier TextMapCarrier)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Extract reads cross-cutting concerns from the carrier into a Context.
|
||||
Extract(ctx context.Context, carrier TextMapCarrier) context.Context
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Fields returns the keys whose values are set with Inject.
|
||||
Fields() []string
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
type compositeTextMapPropagator []TextMapPropagator
|
||||
|
||||
func (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {
|
||||
for _, i := range p {
|
||||
i.Inject(ctx, carrier)
|
||||
}
|
||||
}
|
||||
|
||||
func (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
|
||||
for _, i := range p {
|
||||
ctx = i.Extract(ctx, carrier)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (p compositeTextMapPropagator) Fields() []string {
|
||||
unique := make(map[string]struct{})
|
||||
for _, i := range p {
|
||||
for _, k := range i.Fields() {
|
||||
unique[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
fields := make([]string, 0, len(unique))
|
||||
for k := range unique {
|
||||
fields = append(fields, k)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the
|
||||
// group of passed TextMapPropagator. This allows different cross-cutting
|
||||
// concerns to be propagates in a unified manner.
|
||||
//
|
||||
// The returned TextMapPropagator will inject and extract cross-cutting
|
||||
// concerns in the order the TextMapPropagators were provided. Additionally,
|
||||
// the Fields method will return a de-duplicated slice of the keys that are
|
||||
// set with the Inject method.
|
||||
func NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {
|
||||
return compositeTextMapPropagator(p)
|
||||
}
|
159
vendor/go.opentelemetry.io/otel/propagation/trace_context.go
generated
vendored
Normal file
159
vendor/go.opentelemetry.io/otel/propagation/trace_context.go
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
// 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 propagation // import "go.opentelemetry.io/otel/propagation"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
supportedVersion = 0
|
||||
maxVersion = 254
|
||||
traceparentHeader = "traceparent"
|
||||
tracestateHeader = "tracestate"
|
||||
)
|
||||
|
||||
// TraceContext is a propagator that supports the W3C Trace Context format
|
||||
// (https://www.w3.org/TR/trace-context/)
|
||||
//
|
||||
// This propagator will propagate the traceparent and tracestate headers to
|
||||
// guarantee traces are not broken. It is up to the users of this propagator
|
||||
// to choose if they want to participate in a trace by modifying the
|
||||
// traceparent header and relevant parts of the tracestate header containing
|
||||
// their proprietary information.
|
||||
type TraceContext struct{}
|
||||
|
||||
var _ TextMapPropagator = TraceContext{}
|
||||
var traceCtxRegExp = regexp.MustCompile("^(?P<version>[0-9a-f]{2})-(?P<traceID>[a-f0-9]{32})-(?P<spanID>[a-f0-9]{16})-(?P<traceFlags>[a-f0-9]{2})(?:-.*)?$")
|
||||
|
||||
// Inject set tracecontext from the Context into the carrier.
|
||||
func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
|
||||
sc := trace.SpanContextFromContext(ctx)
|
||||
if !sc.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
if ts := sc.TraceState().String(); ts != "" {
|
||||
carrier.Set(tracestateHeader, ts)
|
||||
}
|
||||
|
||||
// Clear all flags other than the trace-context supported sampling bit.
|
||||
flags := sc.TraceFlags() & trace.FlagsSampled
|
||||
|
||||
h := fmt.Sprintf("%.2x-%s-%s-%s",
|
||||
supportedVersion,
|
||||
sc.TraceID(),
|
||||
sc.SpanID(),
|
||||
flags)
|
||||
carrier.Set(traceparentHeader, h)
|
||||
}
|
||||
|
||||
// Extract reads tracecontext from the carrier into a returned Context.
|
||||
//
|
||||
// The returned Context will be a copy of ctx and contain the extracted
|
||||
// tracecontext as the remote SpanContext. If the extracted tracecontext is
|
||||
// invalid, the passed ctx will be returned directly instead.
|
||||
func (tc TraceContext) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
|
||||
sc := tc.extract(carrier)
|
||||
if !sc.IsValid() {
|
||||
return ctx
|
||||
}
|
||||
return trace.ContextWithRemoteSpanContext(ctx, sc)
|
||||
}
|
||||
|
||||
func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
|
||||
h := carrier.Get(traceparentHeader)
|
||||
if h == "" {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
matches := traceCtxRegExp.FindStringSubmatch(h)
|
||||
|
||||
if len(matches) == 0 {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
if len(matches) < 5 { // four subgroups plus the overall match
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
if len(matches[1]) != 2 {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
ver, err := hex.DecodeString(matches[1])
|
||||
if err != nil {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
version := int(ver[0])
|
||||
if version > maxVersion {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
if version == 0 && len(matches) != 5 { // four subgroups plus the overall match
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
if len(matches[2]) != 32 {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
var scc trace.SpanContextConfig
|
||||
|
||||
scc.TraceID, err = trace.TraceIDFromHex(matches[2][:32])
|
||||
if err != nil {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
if len(matches[3]) != 16 {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
scc.SpanID, err = trace.SpanIDFromHex(matches[3])
|
||||
if err != nil {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
if len(matches[4]) != 2 {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
opts, err := hex.DecodeString(matches[4])
|
||||
if err != nil || len(opts) < 1 || (version == 0 && opts[0] > 2) {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
// Clear all flags other than the trace-context supported sampling bit.
|
||||
scc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled
|
||||
|
||||
// Ignore the error returned here. Failure to parse tracestate MUST NOT
|
||||
// affect the parsing of traceparent according to the W3C tracecontext
|
||||
// specification.
|
||||
scc.TraceState, _ = trace.ParseTraceState(carrier.Get(tracestateHeader))
|
||||
scc.Remote = true
|
||||
|
||||
sc := trace.NewSpanContext(scc)
|
||||
if !sc.IsValid() {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
return sc
|
||||
}
|
||||
|
||||
// Fields returns the keys who's values are set with Inject.
|
||||
func (tc TraceContext) Fields() []string {
|
||||
return []string{traceparentHeader, tracestateHeader}
|
||||
}
|
201
vendor/go.opentelemetry.io/otel/sdk/LICENSE
generated
vendored
Normal file
201
vendor/go.opentelemetry.io/otel/sdk/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.
|
33
vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go
generated
vendored
Normal file
33
vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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 instrumentation provides an instrumentation library structure to be
|
||||
passed to both the OpenTelemetry Tracer and Meter components.
|
||||
|
||||
For more information see
|
||||
[this](https://github.com/open-telemetry/oteps/blob/main/text/0083-component.md).
|
||||
*/
|
||||
package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
|
||||
// Library represents the instrumentation library.
|
||||
type Library struct {
|
||||
// Name is the name of the instrumentation library. This should be the
|
||||
// Go package name of that library.
|
||||
Name string
|
||||
// Version is the version of the instrumentation library.
|
||||
Version string
|
||||
// SchemaURL of the telemetry emitted by the library.
|
||||
SchemaURL string
|
||||
}
|
186
vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go
generated
vendored
Normal file
186
vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
// 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 env // import "go.opentelemetry.io/otel/sdk/internal/env"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
)
|
||||
|
||||
// Environment variable names
|
||||
const (
|
||||
// BatchSpanProcessorScheduleDelayKey
|
||||
// Delay interval between two consecutive exports.
|
||||
// i.e. 5000
|
||||
BatchSpanProcessorScheduleDelayKey = "OTEL_BSP_SCHEDULE_DELAY"
|
||||
// BatchSpanProcessorExportTimeoutKey
|
||||
// Maximum allowed time to export data.
|
||||
// i.e. 3000
|
||||
BatchSpanProcessorExportTimeoutKey = "OTEL_BSP_EXPORT_TIMEOUT"
|
||||
// BatchSpanProcessorMaxQueueSizeKey
|
||||
// Maximum queue size
|
||||
// i.e. 2048
|
||||
BatchSpanProcessorMaxQueueSizeKey = "OTEL_BSP_MAX_QUEUE_SIZE"
|
||||
// BatchSpanProcessorMaxExportBatchSizeKey
|
||||
// Maximum batch size
|
||||
// Note: Must be less than or equal to EnvBatchSpanProcessorMaxQueueSize
|
||||
// i.e. 512
|
||||
BatchSpanProcessorMaxExportBatchSizeKey = "OTEL_BSP_MAX_EXPORT_BATCH_SIZE"
|
||||
|
||||
// AttributeValueLengthKey
|
||||
// Maximum allowed attribute value size.
|
||||
AttributeValueLengthKey = "OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT"
|
||||
|
||||
// AttributeCountKey
|
||||
// Maximum allowed span attribute count
|
||||
AttributeCountKey = "OTEL_ATTRIBUTE_COUNT_LIMIT"
|
||||
|
||||
// SpanAttributeValueLengthKey
|
||||
// Maximum allowed attribute value size for a span.
|
||||
SpanAttributeValueLengthKey = "OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT"
|
||||
|
||||
// SpanAttributeCountKey
|
||||
// Maximum allowed span attribute count for a span.
|
||||
SpanAttributeCountKey = "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT"
|
||||
|
||||
// SpanEventCountKey
|
||||
// Maximum allowed span event count.
|
||||
SpanEventCountKey = "OTEL_SPAN_EVENT_COUNT_LIMIT"
|
||||
|
||||
// SpanEventAttributeCountKey
|
||||
// Maximum allowed attribute per span event count.
|
||||
SpanEventAttributeCountKey = "OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT"
|
||||
|
||||
// SpanLinkCountKey
|
||||
// Maximum allowed span link count.
|
||||
SpanLinkCountKey = "OTEL_SPAN_LINK_COUNT_LIMIT"
|
||||
|
||||
// SpanLinkAttributeCountKey
|
||||
// Maximum allowed attribute per span link count.
|
||||
SpanLinkAttributeCountKey = "OTEL_LINK_ATTRIBUTE_COUNT_LIMIT"
|
||||
)
|
||||
|
||||
// firstInt returns the value of the first matching environment variable from
|
||||
// keys. If the value is not an integer or no match is found, defaultValue is
|
||||
// returned.
|
||||
func firstInt(defaultValue int, keys ...string) int {
|
||||
for _, key := range keys {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
intValue, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
global.Info("Got invalid value, number value expected.", key, value)
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// IntEnvOr returns the int value of the environment variable with name key if
|
||||
// it exists and the value is an int. Otherwise, defaultValue is returned.
|
||||
func IntEnvOr(key string, defaultValue int) int {
|
||||
value, ok := os.LookupEnv(key)
|
||||
if !ok {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
intValue, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
global.Info("Got invalid value, number value expected.", key, value)
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
// BatchSpanProcessorScheduleDelay returns the environment variable value for
|
||||
// the OTEL_BSP_SCHEDULE_DELAY key if it exists, otherwise defaultValue is
|
||||
// returned.
|
||||
func BatchSpanProcessorScheduleDelay(defaultValue int) int {
|
||||
return IntEnvOr(BatchSpanProcessorScheduleDelayKey, defaultValue)
|
||||
}
|
||||
|
||||
// BatchSpanProcessorExportTimeout returns the environment variable value for
|
||||
// the OTEL_BSP_EXPORT_TIMEOUT key if it exists, otherwise defaultValue is
|
||||
// returned.
|
||||
func BatchSpanProcessorExportTimeout(defaultValue int) int {
|
||||
return IntEnvOr(BatchSpanProcessorExportTimeoutKey, defaultValue)
|
||||
}
|
||||
|
||||
// BatchSpanProcessorMaxQueueSize returns the environment variable value for
|
||||
// the OTEL_BSP_MAX_QUEUE_SIZE key if it exists, otherwise defaultValue is
|
||||
// returned.
|
||||
func BatchSpanProcessorMaxQueueSize(defaultValue int) int {
|
||||
return IntEnvOr(BatchSpanProcessorMaxQueueSizeKey, defaultValue)
|
||||
}
|
||||
|
||||
// BatchSpanProcessorMaxExportBatchSize returns the environment variable value for
|
||||
// the OTEL_BSP_MAX_EXPORT_BATCH_SIZE key if it exists, otherwise defaultValue
|
||||
// is returned.
|
||||
func BatchSpanProcessorMaxExportBatchSize(defaultValue int) int {
|
||||
return IntEnvOr(BatchSpanProcessorMaxExportBatchSizeKey, defaultValue)
|
||||
}
|
||||
|
||||
// SpanAttributeValueLength returns the environment variable value for the
|
||||
// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the
|
||||
// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT is
|
||||
// returned or defaultValue if that is not set.
|
||||
func SpanAttributeValueLength(defaultValue int) int {
|
||||
return firstInt(defaultValue, SpanAttributeValueLengthKey, AttributeValueLengthKey)
|
||||
}
|
||||
|
||||
// SpanAttributeCount returns the environment variable value for the
|
||||
// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the
|
||||
// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT is returned or
|
||||
// defaultValue if that is not set.
|
||||
func SpanAttributeCount(defaultValue int) int {
|
||||
return firstInt(defaultValue, SpanAttributeCountKey, AttributeCountKey)
|
||||
}
|
||||
|
||||
// SpanEventCount returns the environment variable value for the
|
||||
// OTEL_SPAN_EVENT_COUNT_LIMIT key if it exists, otherwise defaultValue is
|
||||
// returned.
|
||||
func SpanEventCount(defaultValue int) int {
|
||||
return IntEnvOr(SpanEventCountKey, defaultValue)
|
||||
}
|
||||
|
||||
// SpanEventAttributeCount returns the environment variable value for the
|
||||
// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue
|
||||
// is returned.
|
||||
func SpanEventAttributeCount(defaultValue int) int {
|
||||
return IntEnvOr(SpanEventAttributeCountKey, defaultValue)
|
||||
}
|
||||
|
||||
// SpanLinkCount returns the environment variable value for the
|
||||
// OTEL_SPAN_LINK_COUNT_LIMIT key if it exists, otherwise defaultValue is
|
||||
// returned.
|
||||
func SpanLinkCount(defaultValue int) int {
|
||||
return IntEnvOr(SpanLinkCountKey, defaultValue)
|
||||
}
|
||||
|
||||
// SpanLinkAttributeCount returns the environment variable value for the
|
||||
// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue is
|
||||
// returned.
|
||||
func SpanLinkAttributeCount(defaultValue int) int {
|
||||
return IntEnvOr(SpanLinkAttributeCountKey, defaultValue)
|
||||
}
|
37
vendor/go.opentelemetry.io/otel/sdk/internal/internal.go
generated
vendored
Normal file
37
vendor/go.opentelemetry.io/otel/sdk/internal/internal.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 internal // import "go.opentelemetry.io/otel/sdk/internal"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
// UserAgent is the user agent to be added to the outgoing
|
||||
// requests from the exporters.
|
||||
var UserAgent = fmt.Sprintf("opentelemetry-go/%s", otel.Version())
|
||||
|
||||
// MonotonicEndTime returns the end time at present
|
||||
// but offset from start, monotonically.
|
||||
//
|
||||
// The monotonic clock is used in subtractions hence
|
||||
// the duration since start added back to start gives
|
||||
// end as a monotonic time.
|
||||
// See https://golang.org/pkg/time/#hdr-Monotonic_Clocks
|
||||
func MonotonicEndTime(start time.Time) time.Time {
|
||||
return start.Add(time.Since(start))
|
||||
}
|
72
vendor/go.opentelemetry.io/otel/sdk/resource/auto.go
generated
vendored
Normal file
72
vendor/go.opentelemetry.io/otel/sdk/resource/auto.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrPartialResource is returned by a detector when complete source
|
||||
// information for a Resource is unavailable or the source information
|
||||
// contains invalid values that are omitted from the returned Resource.
|
||||
ErrPartialResource = errors.New("partial resource")
|
||||
)
|
||||
|
||||
// Detector detects OpenTelemetry resource information
|
||||
type Detector interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Detect returns an initialized Resource based on gathered information.
|
||||
// If the source information to construct a Resource contains invalid
|
||||
// values, a Resource is returned with the valid parts of the source
|
||||
// information used for initialization along with an appropriately
|
||||
// wrapped ErrPartialResource error.
|
||||
Detect(ctx context.Context) (*Resource, error)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
// Detect calls all input detectors sequentially and merges each result with the previous one.
|
||||
// It returns the merged error too.
|
||||
func Detect(ctx context.Context, detectors ...Detector) (*Resource, error) {
|
||||
var autoDetectedRes *Resource
|
||||
var errInfo []string
|
||||
for _, detector := range detectors {
|
||||
if detector == nil {
|
||||
continue
|
||||
}
|
||||
res, err := detector.Detect(ctx)
|
||||
if err != nil {
|
||||
errInfo = append(errInfo, err.Error())
|
||||
if !errors.Is(err, ErrPartialResource) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
autoDetectedRes, err = Merge(autoDetectedRes, res)
|
||||
if err != nil {
|
||||
errInfo = append(errInfo, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
var aggregatedError error
|
||||
if len(errInfo) > 0 {
|
||||
aggregatedError = fmt.Errorf("detecting resources: %s", errInfo)
|
||||
}
|
||||
return autoDetectedRes, aggregatedError
|
||||
}
|
108
vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go
generated
vendored
Normal file
108
vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
)
|
||||
|
||||
type (
|
||||
// telemetrySDK is a Detector that provides information about
|
||||
// the OpenTelemetry SDK used. This Detector is included as a
|
||||
// builtin. If these resource attributes are not wanted, use
|
||||
// the WithTelemetrySDK(nil) or WithoutBuiltin() options to
|
||||
// explicitly disable them.
|
||||
telemetrySDK struct{}
|
||||
|
||||
// host is a Detector that provides information about the host
|
||||
// being run on. This Detector is included as a builtin. If
|
||||
// these resource attributes are not wanted, use the
|
||||
// WithHost(nil) or WithoutBuiltin() options to explicitly
|
||||
// disable them.
|
||||
host struct{}
|
||||
|
||||
stringDetector struct {
|
||||
schemaURL string
|
||||
K attribute.Key
|
||||
F func() (string, error)
|
||||
}
|
||||
|
||||
defaultServiceNameDetector struct{}
|
||||
)
|
||||
|
||||
var (
|
||||
_ Detector = telemetrySDK{}
|
||||
_ Detector = host{}
|
||||
_ Detector = stringDetector{}
|
||||
_ Detector = defaultServiceNameDetector{}
|
||||
)
|
||||
|
||||
// Detect returns a *Resource that describes the OpenTelemetry SDK used.
|
||||
func (telemetrySDK) Detect(context.Context) (*Resource, error) {
|
||||
return NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
semconv.TelemetrySDKNameKey.String("opentelemetry"),
|
||||
semconv.TelemetrySDKLanguageKey.String("go"),
|
||||
semconv.TelemetrySDKVersionKey.String(otel.Version()),
|
||||
), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the host being run on.
|
||||
func (host) Detect(ctx context.Context) (*Resource, error) {
|
||||
return StringDetector(semconv.SchemaURL, semconv.HostNameKey, os.Hostname).Detect(ctx)
|
||||
}
|
||||
|
||||
// StringDetector returns a Detector that will produce a *Resource
|
||||
// containing the string as a value corresponding to k. The resulting Resource
|
||||
// will have the specified schemaURL.
|
||||
func StringDetector(schemaURL string, k attribute.Key, f func() (string, error)) Detector {
|
||||
return stringDetector{schemaURL: schemaURL, K: k, F: f}
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the string as a value
|
||||
// corresponding to attribute.Key as well as the specific schemaURL.
|
||||
func (sd stringDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
value, err := sd.F()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", string(sd.K), err)
|
||||
}
|
||||
a := sd.K.String(value)
|
||||
if !a.Valid() {
|
||||
return nil, fmt.Errorf("invalid attribute: %q -> %q", a.Key, a.Value.Emit())
|
||||
}
|
||||
return NewWithAttributes(sd.schemaURL, sd.K.String(value)), nil
|
||||
}
|
||||
|
||||
// Detect implements Detector
|
||||
func (defaultServiceNameDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
return StringDetector(
|
||||
semconv.SchemaURL,
|
||||
semconv.ServiceNameKey,
|
||||
func() (string, error) {
|
||||
executable, err := os.Executable()
|
||||
if err != nil {
|
||||
return "unknown_service:go", nil
|
||||
}
|
||||
return "unknown_service:" + filepath.Base(executable), nil
|
||||
},
|
||||
).Detect(ctx)
|
||||
}
|
199
vendor/go.opentelemetry.io/otel/sdk/resource/config.go
generated
vendored
Normal file
199
vendor/go.opentelemetry.io/otel/sdk/resource/config.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
// config contains configuration for Resource creation.
|
||||
type config struct {
|
||||
// detectors that will be evaluated.
|
||||
detectors []Detector
|
||||
// SchemaURL to associate with the Resource.
|
||||
schemaURL string
|
||||
}
|
||||
|
||||
// Option is the interface that applies a configuration option.
|
||||
type Option interface {
|
||||
// apply sets the Option value of a config.
|
||||
apply(config) config
|
||||
}
|
||||
|
||||
// WithAttributes adds attributes to the configured Resource.
|
||||
func WithAttributes(attributes ...attribute.KeyValue) Option {
|
||||
return WithDetectors(detectAttributes{attributes})
|
||||
}
|
||||
|
||||
type detectAttributes struct {
|
||||
attributes []attribute.KeyValue
|
||||
}
|
||||
|
||||
func (d detectAttributes) Detect(context.Context) (*Resource, error) {
|
||||
return NewSchemaless(d.attributes...), nil
|
||||
}
|
||||
|
||||
// WithDetectors adds detectors to be evaluated for the configured resource.
|
||||
func WithDetectors(detectors ...Detector) Option {
|
||||
return detectorsOption{detectors: detectors}
|
||||
}
|
||||
|
||||
type detectorsOption struct {
|
||||
detectors []Detector
|
||||
}
|
||||
|
||||
func (o detectorsOption) apply(cfg config) config {
|
||||
cfg.detectors = append(cfg.detectors, o.detectors...)
|
||||
return cfg
|
||||
}
|
||||
|
||||
// WithFromEnv adds attributes from environment variables to the configured resource.
|
||||
func WithFromEnv() Option {
|
||||
return WithDetectors(fromEnv{})
|
||||
}
|
||||
|
||||
// WithHost adds attributes from the host to the configured resource.
|
||||
func WithHost() Option {
|
||||
return WithDetectors(host{})
|
||||
}
|
||||
|
||||
// WithTelemetrySDK adds TelemetrySDK version info to the configured resource.
|
||||
func WithTelemetrySDK() Option {
|
||||
return WithDetectors(telemetrySDK{})
|
||||
}
|
||||
|
||||
// WithSchemaURL sets the schema URL for the configured resource.
|
||||
func WithSchemaURL(schemaURL string) Option {
|
||||
return schemaURLOption(schemaURL)
|
||||
}
|
||||
|
||||
type schemaURLOption string
|
||||
|
||||
func (o schemaURLOption) apply(cfg config) config {
|
||||
cfg.schemaURL = string(o)
|
||||
return cfg
|
||||
}
|
||||
|
||||
// WithOS adds all the OS attributes to the configured Resource.
|
||||
// See individual WithOS* functions to configure specific attributes.
|
||||
func WithOS() Option {
|
||||
return WithDetectors(
|
||||
osTypeDetector{},
|
||||
osDescriptionDetector{},
|
||||
)
|
||||
}
|
||||
|
||||
// WithOSType adds an attribute with the operating system type to the configured Resource.
|
||||
func WithOSType() Option {
|
||||
return WithDetectors(osTypeDetector{})
|
||||
}
|
||||
|
||||
// WithOSDescription adds an attribute with the operating system description to the
|
||||
// configured Resource. The formatted string is equivalent to the output of the
|
||||
// `uname -snrvm` command.
|
||||
func WithOSDescription() Option {
|
||||
return WithDetectors(osDescriptionDetector{})
|
||||
}
|
||||
|
||||
// WithProcess adds all the Process attributes to the configured Resource.
|
||||
//
|
||||
// Warning! This option will include process command line arguments. If these
|
||||
// contain sensitive information it will be included in the exported resource.
|
||||
//
|
||||
// This option is equivalent to calling WithProcessPID,
|
||||
// WithProcessExecutableName, WithProcessExecutablePath,
|
||||
// WithProcessCommandArgs, WithProcessOwner, WithProcessRuntimeName,
|
||||
// WithProcessRuntimeVersion, and WithProcessRuntimeDescription. See each
|
||||
// option function for information about what resource attributes each
|
||||
// includes.
|
||||
func WithProcess() Option {
|
||||
return WithDetectors(
|
||||
processPIDDetector{},
|
||||
processExecutableNameDetector{},
|
||||
processExecutablePathDetector{},
|
||||
processCommandArgsDetector{},
|
||||
processOwnerDetector{},
|
||||
processRuntimeNameDetector{},
|
||||
processRuntimeVersionDetector{},
|
||||
processRuntimeDescriptionDetector{},
|
||||
)
|
||||
}
|
||||
|
||||
// WithProcessPID adds an attribute with the process identifier (PID) to the
|
||||
// configured Resource.
|
||||
func WithProcessPID() Option {
|
||||
return WithDetectors(processPIDDetector{})
|
||||
}
|
||||
|
||||
// WithProcessExecutableName adds an attribute with the name of the process
|
||||
// executable to the configured Resource.
|
||||
func WithProcessExecutableName() Option {
|
||||
return WithDetectors(processExecutableNameDetector{})
|
||||
}
|
||||
|
||||
// WithProcessExecutablePath adds an attribute with the full path to the process
|
||||
// executable to the configured Resource.
|
||||
func WithProcessExecutablePath() Option {
|
||||
return WithDetectors(processExecutablePathDetector{})
|
||||
}
|
||||
|
||||
// WithProcessCommandArgs adds an attribute with all the command arguments (including
|
||||
// the command/executable itself) as received by the process to the configured
|
||||
// Resource.
|
||||
//
|
||||
// Warning! This option will include process command line arguments. If these
|
||||
// contain sensitive information it will be included in the exported resource.
|
||||
func WithProcessCommandArgs() Option {
|
||||
return WithDetectors(processCommandArgsDetector{})
|
||||
}
|
||||
|
||||
// WithProcessOwner adds an attribute with the username of the user that owns the process
|
||||
// to the configured Resource.
|
||||
func WithProcessOwner() Option {
|
||||
return WithDetectors(processOwnerDetector{})
|
||||
}
|
||||
|
||||
// WithProcessRuntimeName adds an attribute with the name of the runtime of this
|
||||
// process to the configured Resource.
|
||||
func WithProcessRuntimeName() Option {
|
||||
return WithDetectors(processRuntimeNameDetector{})
|
||||
}
|
||||
|
||||
// WithProcessRuntimeVersion adds an attribute with the version of the runtime of
|
||||
// this process to the configured Resource.
|
||||
func WithProcessRuntimeVersion() Option {
|
||||
return WithDetectors(processRuntimeVersionDetector{})
|
||||
}
|
||||
|
||||
// WithProcessRuntimeDescription adds an attribute with an additional description
|
||||
// about the runtime of the process to the configured Resource.
|
||||
func WithProcessRuntimeDescription() Option {
|
||||
return WithDetectors(processRuntimeDescriptionDetector{})
|
||||
}
|
||||
|
||||
// WithContainer adds all the Container attributes to the configured Resource.
|
||||
// See individual WithContainer* functions to configure specific attributes.
|
||||
func WithContainer() Option {
|
||||
return WithDetectors(
|
||||
cgroupContainerIDDetector{},
|
||||
)
|
||||
}
|
||||
|
||||
// WithContainerID adds an attribute with the id of the container to the configured Resource.
|
||||
func WithContainerID() Option {
|
||||
return WithDetectors(cgroupContainerIDDetector{})
|
||||
}
|
100
vendor/go.opentelemetry.io/otel/sdk/resource/container.go
generated
vendored
Normal file
100
vendor/go.opentelemetry.io/otel/sdk/resource/container.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
)
|
||||
|
||||
type containerIDProvider func() (string, error)
|
||||
|
||||
var (
|
||||
containerID containerIDProvider = getContainerIDFromCGroup
|
||||
cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`)
|
||||
)
|
||||
|
||||
type cgroupContainerIDDetector struct{}
|
||||
|
||||
const cgroupPath = "/proc/self/cgroup"
|
||||
|
||||
// Detect returns a *Resource that describes the id of the container.
|
||||
// If no container id found, an empty resource will be returned.
|
||||
func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
containerID, err := containerID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if containerID == "" {
|
||||
return Empty(), nil
|
||||
}
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ContainerIDKey.String(containerID)), nil
|
||||
}
|
||||
|
||||
var (
|
||||
defaultOSStat = os.Stat
|
||||
osStat = defaultOSStat
|
||||
|
||||
defaultOSOpen = func(name string) (io.ReadCloser, error) {
|
||||
return os.Open(name)
|
||||
}
|
||||
osOpen = defaultOSOpen
|
||||
)
|
||||
|
||||
// getContainerIDFromCGroup returns the id of the container from the cgroup file.
|
||||
// If no container id found, an empty string will be returned.
|
||||
func getContainerIDFromCGroup() (string, error) {
|
||||
if _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) {
|
||||
// File does not exist, skip
|
||||
return "", nil
|
||||
}
|
||||
|
||||
file, err := osOpen(cgroupPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return getContainerIDFromReader(file), nil
|
||||
}
|
||||
|
||||
// getContainerIDFromReader returns the id of the container from reader.
|
||||
func getContainerIDFromReader(reader io.Reader) string {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if id := getContainerIDFromLine(line); id != "" {
|
||||
return id
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// getContainerIDFromLine returns the id of the container from one string line.
|
||||
func getContainerIDFromLine(line string) string {
|
||||
matches := cgroupContainerIDRe.FindStringSubmatch(line)
|
||||
if len(matches) <= 1 {
|
||||
return ""
|
||||
}
|
||||
return matches[1]
|
||||
}
|
28
vendor/go.opentelemetry.io/otel/sdk/resource/doc.go
generated
vendored
Normal file
28
vendor/go.opentelemetry.io/otel/sdk/resource/doc.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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 resource provides detecting and representing resources.
|
||||
//
|
||||
// The fundamental struct is a Resource which holds identifying information
|
||||
// about the entities for which telemetry is exported.
|
||||
//
|
||||
// To automatically construct Resources from an environment a Detector
|
||||
// interface is defined. Implementations of this interface can be passed to
|
||||
// the Detect function to generate a Resource from the merged information.
|
||||
//
|
||||
// To load a user defined Resource from the environment variable
|
||||
// OTEL_RESOURCE_ATTRIBUTES the FromEnv Detector can be used. It will interpret
|
||||
// the value as a list of comma delimited key/value pairs
|
||||
// (e.g. `<key1>=<value1>,<key2>=<value2>,...`).
|
||||
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
99
vendor/go.opentelemetry.io/otel/sdk/resource/env.go
generated
vendored
Normal file
99
vendor/go.opentelemetry.io/otel/sdk/resource/env.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
)
|
||||
|
||||
const (
|
||||
// resourceAttrKey is the environment variable name OpenTelemetry Resource information will be read from.
|
||||
resourceAttrKey = "OTEL_RESOURCE_ATTRIBUTES"
|
||||
|
||||
// svcNameKey is the environment variable name that Service Name information will be read from.
|
||||
svcNameKey = "OTEL_SERVICE_NAME"
|
||||
)
|
||||
|
||||
var (
|
||||
// errMissingValue is returned when a resource value is missing.
|
||||
errMissingValue = fmt.Errorf("%w: missing value", ErrPartialResource)
|
||||
)
|
||||
|
||||
// fromEnv is a Detector that implements the Detector and collects
|
||||
// resources from environment. This Detector is included as a
|
||||
// builtin.
|
||||
type fromEnv struct{}
|
||||
|
||||
// compile time assertion that FromEnv implements Detector interface
|
||||
var _ Detector = fromEnv{}
|
||||
|
||||
// Detect collects resources from environment
|
||||
func (fromEnv) Detect(context.Context) (*Resource, error) {
|
||||
attrs := strings.TrimSpace(os.Getenv(resourceAttrKey))
|
||||
svcName := strings.TrimSpace(os.Getenv(svcNameKey))
|
||||
|
||||
if attrs == "" && svcName == "" {
|
||||
return Empty(), nil
|
||||
}
|
||||
|
||||
var res *Resource
|
||||
|
||||
if svcName != "" {
|
||||
res = NewSchemaless(semconv.ServiceNameKey.String(svcName))
|
||||
}
|
||||
|
||||
r2, err := constructOTResources(attrs)
|
||||
|
||||
// Ensure that the resource with the service name from OTEL_SERVICE_NAME
|
||||
// takes precedence, if it was defined.
|
||||
res, err2 := Merge(r2, res)
|
||||
|
||||
if err == nil {
|
||||
err = err2
|
||||
} else if err2 != nil {
|
||||
err = fmt.Errorf("detecting resources: %s", []string{err.Error(), err2.Error()})
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
func constructOTResources(s string) (*Resource, error) {
|
||||
if s == "" {
|
||||
return Empty(), nil
|
||||
}
|
||||
pairs := strings.Split(s, ",")
|
||||
attrs := []attribute.KeyValue{}
|
||||
var invalid []string
|
||||
for _, p := range pairs {
|
||||
field := strings.SplitN(p, "=", 2)
|
||||
if len(field) != 2 {
|
||||
invalid = append(invalid, p)
|
||||
continue
|
||||
}
|
||||
k, v := strings.TrimSpace(field[0]), strings.TrimSpace(field[1])
|
||||
attrs = append(attrs, attribute.String(k, v))
|
||||
}
|
||||
var err error
|
||||
if len(invalid) > 0 {
|
||||
err = fmt.Errorf("%w: %v", errMissingValue, invalid)
|
||||
}
|
||||
return NewSchemaless(attrs...), err
|
||||
}
|
97
vendor/go.opentelemetry.io/otel/sdk/resource/os.go
generated
vendored
Normal file
97
vendor/go.opentelemetry.io/otel/sdk/resource/os.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
)
|
||||
|
||||
type osDescriptionProvider func() (string, error)
|
||||
|
||||
var defaultOSDescriptionProvider osDescriptionProvider = platformOSDescription
|
||||
|
||||
var osDescription = defaultOSDescriptionProvider
|
||||
|
||||
func setDefaultOSDescriptionProvider() {
|
||||
setOSDescriptionProvider(defaultOSDescriptionProvider)
|
||||
}
|
||||
|
||||
func setOSDescriptionProvider(osDescriptionProvider osDescriptionProvider) {
|
||||
osDescription = osDescriptionProvider
|
||||
}
|
||||
|
||||
type osTypeDetector struct{}
|
||||
type osDescriptionDetector struct{}
|
||||
|
||||
// Detect returns a *Resource that describes the operating system type the
|
||||
// service is running on.
|
||||
func (osTypeDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
osType := runtimeOS()
|
||||
|
||||
osTypeAttribute := mapRuntimeOSToSemconvOSType(osType)
|
||||
|
||||
return NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
osTypeAttribute,
|
||||
), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the operating system the
|
||||
// service is running on.
|
||||
func (osDescriptionDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
description, err := osDescription()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
semconv.OSDescriptionKey.String(description),
|
||||
), nil
|
||||
}
|
||||
|
||||
// mapRuntimeOSToSemconvOSType translates the OS name as provided by the Go runtime
|
||||
// into an OS type attribute with the corresponding value defined by the semantic
|
||||
// conventions. In case the provided OS name isn't mapped, it's transformed to lowercase
|
||||
// and used as the value for the returned OS type attribute.
|
||||
func mapRuntimeOSToSemconvOSType(osType string) attribute.KeyValue {
|
||||
// the elements in this map are the intersection between
|
||||
// available GOOS values and defined semconv OS types
|
||||
osTypeAttributeMap := map[string]attribute.KeyValue{
|
||||
"darwin": semconv.OSTypeDarwin,
|
||||
"dragonfly": semconv.OSTypeDragonflyBSD,
|
||||
"freebsd": semconv.OSTypeFreeBSD,
|
||||
"linux": semconv.OSTypeLinux,
|
||||
"netbsd": semconv.OSTypeNetBSD,
|
||||
"openbsd": semconv.OSTypeOpenBSD,
|
||||
"solaris": semconv.OSTypeSolaris,
|
||||
"windows": semconv.OSTypeWindows,
|
||||
}
|
||||
|
||||
var osTypeAttribute attribute.KeyValue
|
||||
|
||||
if attr, ok := osTypeAttributeMap[osType]; ok {
|
||||
osTypeAttribute = attr
|
||||
} else {
|
||||
osTypeAttribute = semconv.OSTypeKey.String(strings.ToLower(osType))
|
||||
}
|
||||
|
||||
return osTypeAttribute
|
||||
}
|
102
vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go
generated
vendored
Normal file
102
vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type plist struct {
|
||||
XMLName xml.Name `xml:"plist"`
|
||||
Dict dict `xml:"dict"`
|
||||
}
|
||||
|
||||
type dict struct {
|
||||
Key []string `xml:"key"`
|
||||
String []string `xml:"string"`
|
||||
}
|
||||
|
||||
// osRelease builds a string describing the operating system release based on the
|
||||
// contents of the property list (.plist) system files. If no .plist files are found,
|
||||
// or if the required properties to build the release description string are missing,
|
||||
// an empty string is returned instead. The generated string resembles the output of
|
||||
// the `sw_vers` commandline program, but in a single-line string. For more information
|
||||
// about the `sw_vers` program, see: https://www.unix.com/man-page/osx/1/SW_VERS.
|
||||
func osRelease() string {
|
||||
file, err := getPlistFile()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
values, err := parsePlistFile(file)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return buildOSRelease(values)
|
||||
}
|
||||
|
||||
// getPlistFile returns a *os.File pointing to one of the well-known .plist files
|
||||
// available on macOS. If no file can be opened, it returns an error.
|
||||
func getPlistFile() (*os.File, error) {
|
||||
return getFirstAvailableFile([]string{
|
||||
"/System/Library/CoreServices/SystemVersion.plist",
|
||||
"/System/Library/CoreServices/ServerVersion.plist",
|
||||
})
|
||||
}
|
||||
|
||||
// parsePlistFile process the file pointed by `file` as a .plist file and returns
|
||||
// a map with the key-values for each pair of correlated <key> and <string> elements
|
||||
// contained in it.
|
||||
func parsePlistFile(file io.Reader) (map[string]string, error) {
|
||||
var v plist
|
||||
|
||||
err := xml.NewDecoder(file).Decode(&v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(v.Dict.Key) != len(v.Dict.String) {
|
||||
return nil, fmt.Errorf("the number of <key> and <string> elements doesn't match")
|
||||
}
|
||||
|
||||
properties := make(map[string]string, len(v.Dict.Key))
|
||||
for i, key := range v.Dict.Key {
|
||||
properties[key] = v.Dict.String[i]
|
||||
}
|
||||
|
||||
return properties, nil
|
||||
}
|
||||
|
||||
// buildOSRelease builds a string describing the OS release based on the properties
|
||||
// available on the provided map. It tries to find the `ProductName`, `ProductVersion`
|
||||
// and `ProductBuildVersion` properties. If some of these properties are not found,
|
||||
// it returns an empty string.
|
||||
func buildOSRelease(properties map[string]string) string {
|
||||
productName := properties["ProductName"]
|
||||
productVersion := properties["ProductVersion"]
|
||||
productBuildVersion := properties["ProductBuildVersion"]
|
||||
|
||||
if productName == "" || productVersion == "" || productBuildVersion == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s (%s)", productName, productVersion, productBuildVersion)
|
||||
}
|
154
vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go
generated
vendored
Normal file
154
vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// 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.
|
||||
|
||||
//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// osRelease builds a string describing the operating system release based on the
|
||||
// properties of the os-release file. If no os-release file is found, or if the
|
||||
// required properties to build the release description string are missing, an empty
|
||||
// string is returned instead. For more information about os-release files, see:
|
||||
// https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
func osRelease() string {
|
||||
file, err := getOSReleaseFile()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
values := parseOSReleaseFile(file)
|
||||
|
||||
return buildOSRelease(values)
|
||||
}
|
||||
|
||||
// getOSReleaseFile returns a *os.File pointing to one of the well-known os-release
|
||||
// files, according to their order of preference. If no file can be opened, it
|
||||
// returns an error.
|
||||
func getOSReleaseFile() (*os.File, error) {
|
||||
return getFirstAvailableFile([]string{"/etc/os-release", "/usr/lib/os-release"})
|
||||
}
|
||||
|
||||
// parseOSReleaseFile process the file pointed by `file` as an os-release file and
|
||||
// returns a map with the key-values contained in it. Empty lines or lines starting
|
||||
// with a '#' character are ignored, as well as lines with the missing key=value
|
||||
// separator. Values are unquoted and unescaped.
|
||||
func parseOSReleaseFile(file io.Reader) map[string]string {
|
||||
values := make(map[string]string)
|
||||
scanner := bufio.NewScanner(file)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if skip(line) {
|
||||
continue
|
||||
}
|
||||
|
||||
key, value, ok := parse(line)
|
||||
if ok {
|
||||
values[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// skip returns true if the line is blank or starts with a '#' character, and
|
||||
// therefore should be skipped from processing.
|
||||
func skip(line string) bool {
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
return len(line) == 0 || strings.HasPrefix(line, "#")
|
||||
}
|
||||
|
||||
// parse attempts to split the provided line on the first '=' character, and then
|
||||
// sanitize each side of the split before returning them as a key-value pair.
|
||||
func parse(line string) (string, string, bool) {
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
|
||||
if len(parts) != 2 || len(parts[0]) == 0 {
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(parts[0])
|
||||
value := unescape(unquote(strings.TrimSpace(parts[1])))
|
||||
|
||||
return key, value, true
|
||||
}
|
||||
|
||||
// unquote checks whether the string `s` is quoted with double or single quotes
|
||||
// and, if so, returns a version of the string without them. Otherwise it returns
|
||||
// the provided string unchanged.
|
||||
func unquote(s string) string {
|
||||
if len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
|
||||
if (s[0] == '"' || s[0] == '\'') && s[0] == s[len(s)-1] {
|
||||
return s[1 : len(s)-1]
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// unescape removes the `\` prefix from some characters that are expected
|
||||
// to have it added in front of them for escaping purposes.
|
||||
func unescape(s string) string {
|
||||
return strings.NewReplacer(
|
||||
`\$`, `$`,
|
||||
`\"`, `"`,
|
||||
`\'`, `'`,
|
||||
`\\`, `\`,
|
||||
"\\`", "`",
|
||||
).Replace(s)
|
||||
}
|
||||
|
||||
// buildOSRelease builds a string describing the OS release based on the properties
|
||||
// available on the provided map. It favors a combination of the `NAME` and `VERSION`
|
||||
// properties as first option (falling back to `VERSION_ID` if `VERSION` isn't
|
||||
// found), and using `PRETTY_NAME` alone if some of the previous are not present. If
|
||||
// none of these properties are found, it returns an empty string.
|
||||
//
|
||||
// The rationale behind not using `PRETTY_NAME` as first choice was that, for some
|
||||
// Linux distributions, it doesn't include the same detail that can be found on the
|
||||
// individual `NAME` and `VERSION` properties, and combining `PRETTY_NAME` with
|
||||
// other properties can produce "pretty" redundant strings in some cases.
|
||||
func buildOSRelease(values map[string]string) string {
|
||||
var osRelease string
|
||||
|
||||
name := values["NAME"]
|
||||
version := values["VERSION"]
|
||||
|
||||
if version == "" {
|
||||
version = values["VERSION_ID"]
|
||||
}
|
||||
|
||||
if name != "" && version != "" {
|
||||
osRelease = fmt.Sprintf("%s %s", name, version)
|
||||
} else {
|
||||
osRelease = values["PRETTY_NAME"]
|
||||
}
|
||||
|
||||
return osRelease
|
||||
}
|
100
vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go
generated
vendored
Normal file
100
vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// 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.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type unameProvider func(buf *unix.Utsname) (err error)
|
||||
|
||||
var defaultUnameProvider unameProvider = unix.Uname
|
||||
|
||||
var currentUnameProvider = defaultUnameProvider
|
||||
|
||||
func setDefaultUnameProvider() {
|
||||
setUnameProvider(defaultUnameProvider)
|
||||
}
|
||||
|
||||
func setUnameProvider(unameProvider unameProvider) {
|
||||
currentUnameProvider = unameProvider
|
||||
}
|
||||
|
||||
// platformOSDescription returns a human readable OS version information string.
|
||||
// The final string combines OS release information (where available) and the
|
||||
// result of the `uname` system call.
|
||||
func platformOSDescription() (string, error) {
|
||||
uname, err := uname()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
osRelease := osRelease()
|
||||
if osRelease != "" {
|
||||
return fmt.Sprintf("%s (%s)", osRelease, uname), nil
|
||||
}
|
||||
|
||||
return uname, nil
|
||||
}
|
||||
|
||||
// uname issues a uname(2) system call (or equivalent on systems which doesn't
|
||||
// have one) and formats the output in a single string, similar to the output
|
||||
// of the `uname` commandline program. The final string resembles the one
|
||||
// obtained with a call to `uname -snrvm`.
|
||||
func uname() (string, error) {
|
||||
var utsName unix.Utsname
|
||||
|
||||
err := currentUnameProvider(&utsName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s %s %s %s",
|
||||
charsToString(utsName.Sysname[:]),
|
||||
charsToString(utsName.Nodename[:]),
|
||||
charsToString(utsName.Release[:]),
|
||||
charsToString(utsName.Version[:]),
|
||||
charsToString(utsName.Machine[:]),
|
||||
), nil
|
||||
}
|
||||
|
||||
// charsToString converts a C-like null-terminated char array to a Go string.
|
||||
func charsToString(charArray []byte) string {
|
||||
if i := bytes.IndexByte(charArray, 0); i >= 0 {
|
||||
charArray = charArray[:i]
|
||||
}
|
||||
|
||||
return string(charArray)
|
||||
}
|
||||
|
||||
// getFirstAvailableFile returns an *os.File of the first available
|
||||
// file from a list of candidate file paths.
|
||||
func getFirstAvailableFile(candidates []string) (*os.File, error) {
|
||||
for _, c := range candidates {
|
||||
file, err := os.Open(c)
|
||||
if err == nil {
|
||||
return file, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no candidate file available: %v", candidates)
|
||||
}
|
34
vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go
generated
vendored
Normal file
34
vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
|
||||
// +build !aix
|
||||
// +build !darwin
|
||||
// +build !dragonfly
|
||||
// +build !freebsd
|
||||
// +build !linux
|
||||
// +build !netbsd
|
||||
// +build !openbsd
|
||||
// +build !solaris
|
||||
// +build !windows
|
||||
// +build !zos
|
||||
|
||||
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
// platformOSDescription is a placeholder implementation for OSes
|
||||
// for which this project currently doesn't support os.description
|
||||
// attribute detection. See build tags declaration early on this file
|
||||
// for a list of unsupported OSes.
|
||||
func platformOSDescription() (string, error) {
|
||||
return "<unknown>", nil
|
||||
}
|
101
vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go
generated
vendored
Normal file
101
vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
// platformOSDescription returns a human readable OS version information string.
|
||||
// It does so by querying registry values under the
|
||||
// `SOFTWARE\Microsoft\Windows NT\CurrentVersion` key. The final string
|
||||
// resembles the one displayed by the Version Reporter Applet (winver.exe).
|
||||
func platformOSDescription() (string, error) {
|
||||
k, err := registry.OpenKey(
|
||||
registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer k.Close()
|
||||
|
||||
var (
|
||||
productName = readProductName(k)
|
||||
displayVersion = readDisplayVersion(k)
|
||||
releaseID = readReleaseID(k)
|
||||
currentMajorVersionNumber = readCurrentMajorVersionNumber(k)
|
||||
currentMinorVersionNumber = readCurrentMinorVersionNumber(k)
|
||||
currentBuildNumber = readCurrentBuildNumber(k)
|
||||
ubr = readUBR(k)
|
||||
)
|
||||
|
||||
if displayVersion != "" {
|
||||
displayVersion += " "
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %s(%s) [Version %s.%s.%s.%s]",
|
||||
productName,
|
||||
displayVersion,
|
||||
releaseID,
|
||||
currentMajorVersionNumber,
|
||||
currentMinorVersionNumber,
|
||||
currentBuildNumber,
|
||||
ubr,
|
||||
), nil
|
||||
}
|
||||
|
||||
func getStringValue(name string, k registry.Key) string {
|
||||
value, _, _ := k.GetStringValue(name)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func getIntegerValue(name string, k registry.Key) uint64 {
|
||||
value, _, _ := k.GetIntegerValue(name)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func readProductName(k registry.Key) string {
|
||||
return getStringValue("ProductName", k)
|
||||
}
|
||||
|
||||
func readDisplayVersion(k registry.Key) string {
|
||||
return getStringValue("DisplayVersion", k)
|
||||
}
|
||||
|
||||
func readReleaseID(k registry.Key) string {
|
||||
return getStringValue("ReleaseID", k)
|
||||
}
|
||||
|
||||
func readCurrentMajorVersionNumber(k registry.Key) string {
|
||||
return strconv.FormatUint(getIntegerValue("CurrentMajorVersionNumber", k), 10)
|
||||
}
|
||||
|
||||
func readCurrentMinorVersionNumber(k registry.Key) string {
|
||||
return strconv.FormatUint(getIntegerValue("CurrentMinorVersionNumber", k), 10)
|
||||
}
|
||||
|
||||
func readCurrentBuildNumber(k registry.Key) string {
|
||||
return getStringValue("CurrentBuildNumber", k)
|
||||
}
|
||||
|
||||
func readUBR(k registry.Key) string {
|
||||
return strconv.FormatUint(getIntegerValue("UBR", k), 10)
|
||||
}
|
180
vendor/go.opentelemetry.io/otel/sdk/resource/process.go
generated
vendored
Normal file
180
vendor/go.opentelemetry.io/otel/sdk/resource/process.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
)
|
||||
|
||||
type pidProvider func() int
|
||||
type executablePathProvider func() (string, error)
|
||||
type commandArgsProvider func() []string
|
||||
type ownerProvider func() (*user.User, error)
|
||||
type runtimeNameProvider func() string
|
||||
type runtimeVersionProvider func() string
|
||||
type runtimeOSProvider func() string
|
||||
type runtimeArchProvider func() string
|
||||
|
||||
var (
|
||||
defaultPidProvider pidProvider = os.Getpid
|
||||
defaultExecutablePathProvider executablePathProvider = os.Executable
|
||||
defaultCommandArgsProvider commandArgsProvider = func() []string { return os.Args }
|
||||
defaultOwnerProvider ownerProvider = user.Current
|
||||
defaultRuntimeNameProvider runtimeNameProvider = func() string {
|
||||
if runtime.Compiler == "gc" {
|
||||
return "go"
|
||||
}
|
||||
return runtime.Compiler
|
||||
}
|
||||
defaultRuntimeVersionProvider runtimeVersionProvider = runtime.Version
|
||||
defaultRuntimeOSProvider runtimeOSProvider = func() string { return runtime.GOOS }
|
||||
defaultRuntimeArchProvider runtimeArchProvider = func() string { return runtime.GOARCH }
|
||||
)
|
||||
|
||||
var (
|
||||
pid = defaultPidProvider
|
||||
executablePath = defaultExecutablePathProvider
|
||||
commandArgs = defaultCommandArgsProvider
|
||||
owner = defaultOwnerProvider
|
||||
runtimeName = defaultRuntimeNameProvider
|
||||
runtimeVersion = defaultRuntimeVersionProvider
|
||||
runtimeOS = defaultRuntimeOSProvider
|
||||
runtimeArch = defaultRuntimeArchProvider
|
||||
)
|
||||
|
||||
func setDefaultOSProviders() {
|
||||
setOSProviders(
|
||||
defaultPidProvider,
|
||||
defaultExecutablePathProvider,
|
||||
defaultCommandArgsProvider,
|
||||
)
|
||||
}
|
||||
|
||||
func setOSProviders(
|
||||
pidProvider pidProvider,
|
||||
executablePathProvider executablePathProvider,
|
||||
commandArgsProvider commandArgsProvider,
|
||||
) {
|
||||
pid = pidProvider
|
||||
executablePath = executablePathProvider
|
||||
commandArgs = commandArgsProvider
|
||||
}
|
||||
|
||||
func setDefaultRuntimeProviders() {
|
||||
setRuntimeProviders(
|
||||
defaultRuntimeNameProvider,
|
||||
defaultRuntimeVersionProvider,
|
||||
defaultRuntimeOSProvider,
|
||||
defaultRuntimeArchProvider,
|
||||
)
|
||||
}
|
||||
|
||||
func setRuntimeProviders(
|
||||
runtimeNameProvider runtimeNameProvider,
|
||||
runtimeVersionProvider runtimeVersionProvider,
|
||||
runtimeOSProvider runtimeOSProvider,
|
||||
runtimeArchProvider runtimeArchProvider,
|
||||
) {
|
||||
runtimeName = runtimeNameProvider
|
||||
runtimeVersion = runtimeVersionProvider
|
||||
runtimeOS = runtimeOSProvider
|
||||
runtimeArch = runtimeArchProvider
|
||||
}
|
||||
|
||||
func setDefaultUserProviders() {
|
||||
setUserProviders(defaultOwnerProvider)
|
||||
}
|
||||
|
||||
func setUserProviders(ownerProvider ownerProvider) {
|
||||
owner = ownerProvider
|
||||
}
|
||||
|
||||
type processPIDDetector struct{}
|
||||
type processExecutableNameDetector struct{}
|
||||
type processExecutablePathDetector struct{}
|
||||
type processCommandArgsDetector struct{}
|
||||
type processOwnerDetector struct{}
|
||||
type processRuntimeNameDetector struct{}
|
||||
type processRuntimeVersionDetector struct{}
|
||||
type processRuntimeDescriptionDetector struct{}
|
||||
|
||||
// Detect returns a *Resource that describes the process identifier (PID) of the
|
||||
// executing process.
|
||||
func (processPIDDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessPIDKey.Int(pid())), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the name of the process executable.
|
||||
func (processExecutableNameDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
executableName := filepath.Base(commandArgs()[0])
|
||||
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutableNameKey.String(executableName)), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the full path of the process executable.
|
||||
func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
executablePath, err := executablePath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutablePathKey.String(executablePath)), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes all the command arguments as received
|
||||
// by the process.
|
||||
func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgsKey.StringSlice(commandArgs())), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the username of the user that owns the
|
||||
// process.
|
||||
func (processOwnerDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
owner, err := owner()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessOwnerKey.String(owner.Username)), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the name of the compiler used to compile
|
||||
// this process image.
|
||||
func (processRuntimeNameDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeNameKey.String(runtimeName())), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the version of the runtime of this process.
|
||||
func (processRuntimeVersionDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeVersionKey.String(runtimeVersion())), nil
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the runtime of this process.
|
||||
func (processRuntimeDescriptionDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||
runtimeDescription := fmt.Sprintf(
|
||||
"go version %s %s/%s", runtimeVersion(), runtimeOS(), runtimeArch())
|
||||
|
||||
return NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
semconv.ProcessRuntimeDescriptionKey.String(runtimeDescription),
|
||||
), nil
|
||||
}
|
280
vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
generated
vendored
Normal file
280
vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
// 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
// Resource describes an entity about which identifying information
|
||||
// and metadata is exposed. Resource is an immutable object,
|
||||
// equivalent to a map from key to unique value.
|
||||
//
|
||||
// Resources should be passed and stored as pointers
|
||||
// (`*resource.Resource`). The `nil` value is equivalent to an empty
|
||||
// Resource.
|
||||
type Resource struct {
|
||||
attrs attribute.Set
|
||||
schemaURL string
|
||||
}
|
||||
|
||||
var (
|
||||
emptyResource Resource
|
||||
defaultResource *Resource
|
||||
defaultResourceOnce sync.Once
|
||||
)
|
||||
|
||||
var errMergeConflictSchemaURL = errors.New("cannot merge resource due to conflicting Schema URL")
|
||||
|
||||
// New returns a Resource combined from the user-provided detectors.
|
||||
func New(ctx context.Context, opts ...Option) (*Resource, error) {
|
||||
cfg := config{}
|
||||
for _, opt := range opts {
|
||||
cfg = opt.apply(cfg)
|
||||
}
|
||||
|
||||
resource, err := Detect(ctx, cfg.detectors...)
|
||||
|
||||
var err2 error
|
||||
resource, err2 = Merge(resource, &Resource{schemaURL: cfg.schemaURL})
|
||||
if err == nil {
|
||||
err = err2
|
||||
} else if err2 != nil {
|
||||
err = fmt.Errorf("detecting resources: %s", []string{err.Error(), err2.Error()})
|
||||
}
|
||||
|
||||
return resource, err
|
||||
}
|
||||
|
||||
// NewWithAttributes creates a resource from attrs and associates the resource with a
|
||||
// schema URL. If attrs contains duplicate keys, the last value will be used. If attrs
|
||||
// contains any invalid items those items will be dropped. The attrs are assumed to be
|
||||
// in a schema identified by schemaURL.
|
||||
func NewWithAttributes(schemaURL string, attrs ...attribute.KeyValue) *Resource {
|
||||
resource := NewSchemaless(attrs...)
|
||||
resource.schemaURL = schemaURL
|
||||
return resource
|
||||
}
|
||||
|
||||
// NewSchemaless creates a resource from attrs. If attrs contains duplicate keys,
|
||||
// the last value will be used. If attrs contains any invalid items those items will
|
||||
// be dropped. The resource will not be associated with a schema URL. If the schema
|
||||
// of the attrs is known use NewWithAttributes instead.
|
||||
func NewSchemaless(attrs ...attribute.KeyValue) *Resource {
|
||||
if len(attrs) == 0 {
|
||||
return &emptyResource
|
||||
}
|
||||
|
||||
// Ensure attributes comply with the specification:
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.0.1/specification/common/common.md#attributes
|
||||
s, _ := attribute.NewSetWithFiltered(attrs, func(kv attribute.KeyValue) bool {
|
||||
return kv.Valid()
|
||||
})
|
||||
|
||||
// If attrs only contains invalid entries do not allocate a new resource.
|
||||
if s.Len() == 0 {
|
||||
return &emptyResource
|
||||
}
|
||||
|
||||
return &Resource{attrs: s} //nolint
|
||||
}
|
||||
|
||||
// String implements the Stringer interface and provides a
|
||||
// human-readable form of the resource.
|
||||
//
|
||||
// Avoid using this representation as the key in a map of resources,
|
||||
// use Equivalent() as the key instead.
|
||||
func (r *Resource) String() string {
|
||||
if r == nil {
|
||||
return ""
|
||||
}
|
||||
return r.attrs.Encoded(attribute.DefaultEncoder())
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
||||
func (r *Resource) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Attributes attribute.Set
|
||||
SchemaURL string
|
||||
}{
|
||||
Attributes: r.attrs,
|
||||
SchemaURL: r.schemaURL,
|
||||
}
|
||||
}
|
||||
|
||||
// Attributes returns a copy of attributes from the resource in a sorted order.
|
||||
// To avoid allocating a new slice, use an iterator.
|
||||
func (r *Resource) Attributes() []attribute.KeyValue {
|
||||
if r == nil {
|
||||
r = Empty()
|
||||
}
|
||||
return r.attrs.ToSlice()
|
||||
}
|
||||
|
||||
func (r *Resource) SchemaURL() string {
|
||||
if r == nil {
|
||||
return ""
|
||||
}
|
||||
return r.schemaURL
|
||||
}
|
||||
|
||||
// Iter returns an iterator of the Resource attributes.
|
||||
// This is ideal to use if you do not want a copy of the attributes.
|
||||
func (r *Resource) Iter() attribute.Iterator {
|
||||
if r == nil {
|
||||
r = Empty()
|
||||
}
|
||||
return r.attrs.Iter()
|
||||
}
|
||||
|
||||
// Equal returns true when a Resource is equivalent to this Resource.
|
||||
func (r *Resource) Equal(eq *Resource) bool {
|
||||
if r == nil {
|
||||
r = Empty()
|
||||
}
|
||||
if eq == nil {
|
||||
eq = Empty()
|
||||
}
|
||||
return r.Equivalent() == eq.Equivalent()
|
||||
}
|
||||
|
||||
// Merge creates a new resource by combining resource a and b.
|
||||
//
|
||||
// If there are common keys between resource a and b, then the value
|
||||
// from resource b will overwrite the value from resource a, even
|
||||
// if resource b's value is empty.
|
||||
//
|
||||
// The SchemaURL of the resources will be merged according to the spec rules:
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/bad49c714a62da5493f2d1d9bafd7ebe8c8ce7eb/specification/resource/sdk.md#merge
|
||||
// If the resources have different non-empty schemaURL an empty resource and an error
|
||||
// will be returned.
|
||||
func Merge(a, b *Resource) (*Resource, error) {
|
||||
if a == nil && b == nil {
|
||||
return Empty(), nil
|
||||
}
|
||||
if a == nil {
|
||||
return b, nil
|
||||
}
|
||||
if b == nil {
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Merge the schema URL.
|
||||
var schemaURL string
|
||||
if a.schemaURL == "" {
|
||||
schemaURL = b.schemaURL
|
||||
} else if b.schemaURL == "" {
|
||||
schemaURL = a.schemaURL
|
||||
} else if a.schemaURL == b.schemaURL {
|
||||
schemaURL = a.schemaURL
|
||||
} else {
|
||||
return Empty(), errMergeConflictSchemaURL
|
||||
}
|
||||
|
||||
// Note: 'b' attributes will overwrite 'a' with last-value-wins in attribute.Key()
|
||||
// Meaning this is equivalent to: append(a.Attributes(), b.Attributes()...)
|
||||
mi := attribute.NewMergeIterator(b.Set(), a.Set())
|
||||
combine := make([]attribute.KeyValue, 0, a.Len()+b.Len())
|
||||
for mi.Next() {
|
||||
combine = append(combine, mi.Label())
|
||||
}
|
||||
merged := NewWithAttributes(schemaURL, combine...)
|
||||
return merged, nil
|
||||
}
|
||||
|
||||
// Empty returns an instance of Resource with no attributes. It is
|
||||
// equivalent to a `nil` Resource.
|
||||
func Empty() *Resource {
|
||||
return &emptyResource
|
||||
}
|
||||
|
||||
// Default returns an instance of Resource with a default
|
||||
// "service.name" and OpenTelemetrySDK attributes.
|
||||
func Default() *Resource {
|
||||
defaultResourceOnce.Do(func() {
|
||||
var err error
|
||||
defaultResource, err = Detect(
|
||||
context.Background(),
|
||||
defaultServiceNameDetector{},
|
||||
fromEnv{},
|
||||
telemetrySDK{},
|
||||
)
|
||||
if err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
// If Detect did not return a valid resource, fall back to emptyResource.
|
||||
if defaultResource == nil {
|
||||
defaultResource = &emptyResource
|
||||
}
|
||||
})
|
||||
return defaultResource
|
||||
}
|
||||
|
||||
// Environment returns an instance of Resource with attributes
|
||||
// extracted from the OTEL_RESOURCE_ATTRIBUTES environment variable.
|
||||
func Environment() *Resource {
|
||||
detector := &fromEnv{}
|
||||
resource, err := detector.Detect(context.Background())
|
||||
if err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
return resource
|
||||
}
|
||||
|
||||
// Equivalent returns an object that can be compared for equality
|
||||
// between two resources. This value is suitable for use as a key in
|
||||
// a map.
|
||||
func (r *Resource) Equivalent() attribute.Distinct {
|
||||
return r.Set().Equivalent()
|
||||
}
|
||||
|
||||
// Set returns the equivalent *attribute.Set of this resource's attributes.
|
||||
func (r *Resource) Set() *attribute.Set {
|
||||
if r == nil {
|
||||
r = Empty()
|
||||
}
|
||||
return &r.attrs
|
||||
}
|
||||
|
||||
// MarshalJSON encodes the resource attributes as a JSON list of { "Key":
|
||||
// "...", "Value": ... } pairs in order sorted by key.
|
||||
func (r *Resource) MarshalJSON() ([]byte, error) {
|
||||
if r == nil {
|
||||
r = Empty()
|
||||
}
|
||||
return r.attrs.MarshalJSON()
|
||||
}
|
||||
|
||||
// Len returns the number of unique key-values in this Resource.
|
||||
func (r *Resource) Len() int {
|
||||
if r == nil {
|
||||
return 0
|
||||
}
|
||||
return r.attrs.Len()
|
||||
}
|
||||
|
||||
// Encoded returns an encoded representation of the resource.
|
||||
func (r *Resource) Encoded(enc attribute.Encoder) string {
|
||||
if r == nil {
|
||||
return ""
|
||||
}
|
||||
return r.attrs.Encoded(enc)
|
||||
}
|
396
vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
generated
vendored
Normal file
396
vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
generated
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
"go.opentelemetry.io/otel/sdk/internal/env"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Defaults for BatchSpanProcessorOptions.
|
||||
const (
|
||||
DefaultMaxQueueSize = 2048
|
||||
DefaultScheduleDelay = 5000
|
||||
DefaultExportTimeout = 30000
|
||||
DefaultMaxExportBatchSize = 512
|
||||
)
|
||||
|
||||
type BatchSpanProcessorOption func(o *BatchSpanProcessorOptions)
|
||||
|
||||
type BatchSpanProcessorOptions struct {
|
||||
// MaxQueueSize is the maximum queue size to buffer spans for delayed processing. If the
|
||||
// queue gets full it drops the spans. Use BlockOnQueueFull to change this behavior.
|
||||
// The default value of MaxQueueSize is 2048.
|
||||
MaxQueueSize int
|
||||
|
||||
// BatchTimeout is the maximum duration for constructing a batch. Processor
|
||||
// forcefully sends available spans when timeout is reached.
|
||||
// The default value of BatchTimeout is 5000 msec.
|
||||
BatchTimeout time.Duration
|
||||
|
||||
// ExportTimeout specifies the maximum duration for exporting spans. If the timeout
|
||||
// is reached, the export will be cancelled.
|
||||
// The default value of ExportTimeout is 30000 msec.
|
||||
ExportTimeout time.Duration
|
||||
|
||||
// MaxExportBatchSize is the maximum number of spans to process in a single batch.
|
||||
// If there are more than one batch worth of spans then it processes multiple batches
|
||||
// of spans one batch after the other without any delay.
|
||||
// The default value of MaxExportBatchSize is 512.
|
||||
MaxExportBatchSize int
|
||||
|
||||
// BlockOnQueueFull blocks onEnd() and onStart() method if the queue is full
|
||||
// AND if BlockOnQueueFull is set to true.
|
||||
// Blocking option should be used carefully as it can severely affect the performance of an
|
||||
// application.
|
||||
BlockOnQueueFull bool
|
||||
}
|
||||
|
||||
// batchSpanProcessor is a SpanProcessor that batches asynchronously-received
|
||||
// spans and sends them to a trace.Exporter when complete.
|
||||
type batchSpanProcessor struct {
|
||||
e SpanExporter
|
||||
o BatchSpanProcessorOptions
|
||||
|
||||
queue chan ReadOnlySpan
|
||||
dropped uint32
|
||||
|
||||
batch []ReadOnlySpan
|
||||
batchMutex sync.Mutex
|
||||
timer *time.Timer
|
||||
stopWait sync.WaitGroup
|
||||
stopOnce sync.Once
|
||||
stopCh chan struct{}
|
||||
}
|
||||
|
||||
var _ SpanProcessor = (*batchSpanProcessor)(nil)
|
||||
|
||||
// NewBatchSpanProcessor creates a new SpanProcessor that will send completed
|
||||
// span batches to the exporter with the supplied options.
|
||||
//
|
||||
// If the exporter is nil, the span processor will preform no action.
|
||||
func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor {
|
||||
maxQueueSize := env.BatchSpanProcessorMaxQueueSize(DefaultMaxQueueSize)
|
||||
maxExportBatchSize := env.BatchSpanProcessorMaxExportBatchSize(DefaultMaxExportBatchSize)
|
||||
|
||||
if maxExportBatchSize > maxQueueSize {
|
||||
if DefaultMaxExportBatchSize > maxQueueSize {
|
||||
maxExportBatchSize = maxQueueSize
|
||||
} else {
|
||||
maxExportBatchSize = DefaultMaxExportBatchSize
|
||||
}
|
||||
}
|
||||
|
||||
o := BatchSpanProcessorOptions{
|
||||
BatchTimeout: time.Duration(env.BatchSpanProcessorScheduleDelay(DefaultScheduleDelay)) * time.Millisecond,
|
||||
ExportTimeout: time.Duration(env.BatchSpanProcessorExportTimeout(DefaultExportTimeout)) * time.Millisecond,
|
||||
MaxQueueSize: maxQueueSize,
|
||||
MaxExportBatchSize: maxExportBatchSize,
|
||||
}
|
||||
for _, opt := range options {
|
||||
opt(&o)
|
||||
}
|
||||
bsp := &batchSpanProcessor{
|
||||
e: exporter,
|
||||
o: o,
|
||||
batch: make([]ReadOnlySpan, 0, o.MaxExportBatchSize),
|
||||
timer: time.NewTimer(o.BatchTimeout),
|
||||
queue: make(chan ReadOnlySpan, o.MaxQueueSize),
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
bsp.stopWait.Add(1)
|
||||
go func() {
|
||||
defer bsp.stopWait.Done()
|
||||
bsp.processQueue()
|
||||
bsp.drainQueue()
|
||||
}()
|
||||
|
||||
return bsp
|
||||
}
|
||||
|
||||
// OnStart method does nothing.
|
||||
func (bsp *batchSpanProcessor) OnStart(parent context.Context, s ReadWriteSpan) {}
|
||||
|
||||
// OnEnd method enqueues a ReadOnlySpan for later processing.
|
||||
func (bsp *batchSpanProcessor) OnEnd(s ReadOnlySpan) {
|
||||
// Do not enqueue spans if we are just going to drop them.
|
||||
if bsp.e == nil {
|
||||
return
|
||||
}
|
||||
bsp.enqueue(s)
|
||||
}
|
||||
|
||||
// Shutdown flushes the queue and waits until all spans are processed.
|
||||
// It only executes once. Subsequent call does nothing.
|
||||
func (bsp *batchSpanProcessor) Shutdown(ctx context.Context) error {
|
||||
var err error
|
||||
bsp.stopOnce.Do(func() {
|
||||
wait := make(chan struct{})
|
||||
go func() {
|
||||
close(bsp.stopCh)
|
||||
bsp.stopWait.Wait()
|
||||
if bsp.e != nil {
|
||||
if err := bsp.e.Shutdown(ctx); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
close(wait)
|
||||
}()
|
||||
// Wait until the wait group is done or the context is cancelled
|
||||
select {
|
||||
case <-wait:
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
}
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
type forceFlushSpan struct {
|
||||
ReadOnlySpan
|
||||
flushed chan struct{}
|
||||
}
|
||||
|
||||
func (f forceFlushSpan) SpanContext() trace.SpanContext {
|
||||
return trace.NewSpanContext(trace.SpanContextConfig{TraceFlags: trace.FlagsSampled})
|
||||
}
|
||||
|
||||
// ForceFlush exports all ended spans that have not yet been exported.
|
||||
func (bsp *batchSpanProcessor) ForceFlush(ctx context.Context) error {
|
||||
var err error
|
||||
if bsp.e != nil {
|
||||
flushCh := make(chan struct{})
|
||||
if bsp.enqueueBlockOnQueueFull(ctx, forceFlushSpan{flushed: flushCh}, true) {
|
||||
select {
|
||||
case <-flushCh:
|
||||
// Processed any items in queue prior to ForceFlush being called
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
wait := make(chan error)
|
||||
go func() {
|
||||
wait <- bsp.exportSpans(ctx)
|
||||
close(wait)
|
||||
}()
|
||||
// Wait until the export is finished or the context is cancelled/timed out
|
||||
select {
|
||||
case err = <-wait:
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func WithMaxQueueSize(size int) BatchSpanProcessorOption {
|
||||
return func(o *BatchSpanProcessorOptions) {
|
||||
o.MaxQueueSize = size
|
||||
}
|
||||
}
|
||||
|
||||
func WithMaxExportBatchSize(size int) BatchSpanProcessorOption {
|
||||
return func(o *BatchSpanProcessorOptions) {
|
||||
o.MaxExportBatchSize = size
|
||||
}
|
||||
}
|
||||
|
||||
func WithBatchTimeout(delay time.Duration) BatchSpanProcessorOption {
|
||||
return func(o *BatchSpanProcessorOptions) {
|
||||
o.BatchTimeout = delay
|
||||
}
|
||||
}
|
||||
|
||||
func WithExportTimeout(timeout time.Duration) BatchSpanProcessorOption {
|
||||
return func(o *BatchSpanProcessorOptions) {
|
||||
o.ExportTimeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
func WithBlocking() BatchSpanProcessorOption {
|
||||
return func(o *BatchSpanProcessorOptions) {
|
||||
o.BlockOnQueueFull = true
|
||||
}
|
||||
}
|
||||
|
||||
// exportSpans is a subroutine of processing and draining the queue.
|
||||
func (bsp *batchSpanProcessor) exportSpans(ctx context.Context) error {
|
||||
|
||||
bsp.timer.Reset(bsp.o.BatchTimeout)
|
||||
|
||||
bsp.batchMutex.Lock()
|
||||
defer bsp.batchMutex.Unlock()
|
||||
|
||||
if bsp.o.ExportTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, bsp.o.ExportTimeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
if l := len(bsp.batch); l > 0 {
|
||||
global.Debug("exporting spans", "count", len(bsp.batch), "total_dropped", atomic.LoadUint32(&bsp.dropped))
|
||||
err := bsp.e.ExportSpans(ctx, bsp.batch)
|
||||
|
||||
// A new batch is always created after exporting, even if the batch failed to be exported.
|
||||
//
|
||||
// It is up to the exporter to implement any type of retry logic if a batch is failing
|
||||
// to be exported, since it is specific to the protocol and backend being sent to.
|
||||
bsp.batch = bsp.batch[:0]
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// processQueue removes spans from the `queue` channel until processor
|
||||
// is shut down. It calls the exporter in batches of up to MaxExportBatchSize
|
||||
// waiting up to BatchTimeout to form a batch.
|
||||
func (bsp *batchSpanProcessor) processQueue() {
|
||||
defer bsp.timer.Stop()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
for {
|
||||
select {
|
||||
case <-bsp.stopCh:
|
||||
return
|
||||
case <-bsp.timer.C:
|
||||
if err := bsp.exportSpans(ctx); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
case sd := <-bsp.queue:
|
||||
if ffs, ok := sd.(forceFlushSpan); ok {
|
||||
close(ffs.flushed)
|
||||
continue
|
||||
}
|
||||
bsp.batchMutex.Lock()
|
||||
bsp.batch = append(bsp.batch, sd)
|
||||
shouldExport := len(bsp.batch) >= bsp.o.MaxExportBatchSize
|
||||
bsp.batchMutex.Unlock()
|
||||
if shouldExport {
|
||||
if !bsp.timer.Stop() {
|
||||
<-bsp.timer.C
|
||||
}
|
||||
if err := bsp.exportSpans(ctx); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drainQueue awaits the any caller that had added to bsp.stopWait
|
||||
// to finish the enqueue, then exports the final batch.
|
||||
func (bsp *batchSpanProcessor) drainQueue() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
for {
|
||||
select {
|
||||
case sd := <-bsp.queue:
|
||||
if sd == nil {
|
||||
if err := bsp.exportSpans(ctx); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
bsp.batchMutex.Lock()
|
||||
bsp.batch = append(bsp.batch, sd)
|
||||
shouldExport := len(bsp.batch) == bsp.o.MaxExportBatchSize
|
||||
bsp.batchMutex.Unlock()
|
||||
|
||||
if shouldExport {
|
||||
if err := bsp.exportSpans(ctx); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
close(bsp.queue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (bsp *batchSpanProcessor) enqueue(sd ReadOnlySpan) {
|
||||
bsp.enqueueBlockOnQueueFull(context.TODO(), sd, bsp.o.BlockOnQueueFull)
|
||||
}
|
||||
|
||||
func (bsp *batchSpanProcessor) enqueueBlockOnQueueFull(ctx context.Context, sd ReadOnlySpan, block bool) bool {
|
||||
if !sd.SpanContext().IsSampled() {
|
||||
return false
|
||||
}
|
||||
|
||||
// This ensures the bsp.queue<- below does not panic as the
|
||||
// processor shuts down.
|
||||
defer func() {
|
||||
x := recover()
|
||||
switch err := x.(type) {
|
||||
case nil:
|
||||
return
|
||||
case runtime.Error:
|
||||
if err.Error() == "send on closed channel" {
|
||||
return
|
||||
}
|
||||
}
|
||||
panic(x)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-bsp.stopCh:
|
||||
return false
|
||||
default:
|
||||
}
|
||||
|
||||
if block {
|
||||
select {
|
||||
case bsp.queue <- sd:
|
||||
return true
|
||||
case <-ctx.Done():
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
case bsp.queue <- sd:
|
||||
return true
|
||||
default:
|
||||
atomic.AddUint32(&bsp.dropped, 1)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
||||
func (bsp *batchSpanProcessor) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Type string
|
||||
SpanExporter SpanExporter
|
||||
Config BatchSpanProcessorOptions
|
||||
}{
|
||||
Type: "BatchSpanProcessor",
|
||||
SpanExporter: bsp.e,
|
||||
Config: bsp.o,
|
||||
}
|
||||
}
|
21
vendor/go.opentelemetry.io/otel/sdk/trace/doc.go
generated
vendored
Normal file
21
vendor/go.opentelemetry.io/otel/sdk/trace/doc.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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 contains support for OpenTelemetry distributed tracing.
|
||||
|
||||
The following assumes a basic familiarity with OpenTelemetry concepts.
|
||||
See https://opentelemetry.io.
|
||||
*/
|
||||
package trace // import "go.opentelemetry.io/otel/sdk/trace"
|
37
vendor/go.opentelemetry.io/otel/sdk/trace/event.go
generated
vendored
Normal file
37
vendor/go.opentelemetry.io/otel/sdk/trace/event.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
// Event is a thing that happened during a Span's lifetime.
|
||||
type Event struct {
|
||||
// Name is the name of this event
|
||||
Name string
|
||||
|
||||
// Attributes describe the aspects of the event.
|
||||
Attributes []attribute.KeyValue
|
||||
|
||||
// DroppedAttributeCount is the number of attributes that were not
|
||||
// recorded due to configured limits being reached.
|
||||
DroppedAttributeCount int
|
||||
|
||||
// Time at which this event was recorded.
|
||||
Time time.Time
|
||||
}
|
44
vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go
generated
vendored
Normal file
44
vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
// evictedQueue is a FIFO queue with a configurable capacity.
|
||||
type evictedQueue struct {
|
||||
queue []interface{}
|
||||
capacity int
|
||||
droppedCount int
|
||||
}
|
||||
|
||||
func newEvictedQueue(capacity int) evictedQueue {
|
||||
// Do not pre-allocate queue, do this lazily.
|
||||
return evictedQueue{capacity: capacity}
|
||||
}
|
||||
|
||||
// add adds value to the evictedQueue eq. If eq is at capacity, the oldest
|
||||
// queued value will be discarded and the drop count incremented.
|
||||
func (eq *evictedQueue) add(value interface{}) {
|
||||
if eq.capacity == 0 {
|
||||
eq.droppedCount++
|
||||
return
|
||||
}
|
||||
|
||||
if eq.capacity > 0 && len(eq.queue) == eq.capacity {
|
||||
// Drop first-in while avoiding allocating more capacity to eq.queue.
|
||||
copy(eq.queue[:eq.capacity-1], eq.queue[1:])
|
||||
eq.queue = eq.queue[:eq.capacity-1]
|
||||
eq.droppedCount++
|
||||
}
|
||||
eq.queue = append(eq.queue, value)
|
||||
}
|
77
vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go
generated
vendored
Normal file
77
vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
crand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// IDGenerator allows custom generators for TraceID and SpanID.
|
||||
type IDGenerator interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// NewIDs returns a new trace and span ID.
|
||||
NewIDs(ctx context.Context) (trace.TraceID, trace.SpanID)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// NewSpanID returns a ID for a new span in the trace with traceID.
|
||||
NewSpanID(ctx context.Context, traceID trace.TraceID) trace.SpanID
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
type randomIDGenerator struct {
|
||||
sync.Mutex
|
||||
randSource *rand.Rand
|
||||
}
|
||||
|
||||
var _ IDGenerator = &randomIDGenerator{}
|
||||
|
||||
// NewSpanID returns a non-zero span ID from a randomly-chosen sequence.
|
||||
func (gen *randomIDGenerator) NewSpanID(ctx context.Context, traceID trace.TraceID) trace.SpanID {
|
||||
gen.Lock()
|
||||
defer gen.Unlock()
|
||||
sid := trace.SpanID{}
|
||||
gen.randSource.Read(sid[:])
|
||||
return sid
|
||||
}
|
||||
|
||||
// NewIDs returns a non-zero trace ID and a non-zero span ID from a
|
||||
// randomly-chosen sequence.
|
||||
func (gen *randomIDGenerator) NewIDs(ctx context.Context) (trace.TraceID, trace.SpanID) {
|
||||
gen.Lock()
|
||||
defer gen.Unlock()
|
||||
tid := trace.TraceID{}
|
||||
gen.randSource.Read(tid[:])
|
||||
sid := trace.SpanID{}
|
||||
gen.randSource.Read(sid[:])
|
||||
return tid, sid
|
||||
}
|
||||
|
||||
func defaultIDGenerator() IDGenerator {
|
||||
gen := &randomIDGenerator{}
|
||||
var rngSeed int64
|
||||
_ = binary.Read(crand.Reader, binary.LittleEndian, &rngSeed)
|
||||
gen.randSource = rand.New(rand.NewSource(rngSeed))
|
||||
return gen
|
||||
}
|
34
vendor/go.opentelemetry.io/otel/sdk/trace/link.go
generated
vendored
Normal file
34
vendor/go.opentelemetry.io/otel/sdk/trace/link.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Link is the relationship between two Spans. The relationship can be within
|
||||
// the same Trace or across different Traces.
|
||||
type Link struct {
|
||||
// SpanContext of the linked Span.
|
||||
SpanContext trace.SpanContext
|
||||
|
||||
// Attributes describe the aspects of the link.
|
||||
Attributes []attribute.KeyValue
|
||||
|
||||
// DroppedAttributeCount is the number of attributes that were not
|
||||
// recorded due to configured limits being reached.
|
||||
DroppedAttributeCount int
|
||||
}
|
450
vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
generated
vendored
Normal file
450
vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
generated
vendored
Normal file
@@ -0,0 +1,450 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTracerName = "go.opentelemetry.io/otel/sdk/tracer"
|
||||
)
|
||||
|
||||
// tracerProviderConfig
|
||||
type tracerProviderConfig struct {
|
||||
// processors contains collection of SpanProcessors that are processing pipeline
|
||||
// for spans in the trace signal.
|
||||
// SpanProcessors registered with a TracerProvider and are called at the start
|
||||
// and end of a Span's lifecycle, and are called in the order they are
|
||||
// registered.
|
||||
processors []SpanProcessor
|
||||
|
||||
// sampler is the default sampler used when creating new spans.
|
||||
sampler Sampler
|
||||
|
||||
// idGenerator is used to generate all Span and Trace IDs when needed.
|
||||
idGenerator IDGenerator
|
||||
|
||||
// spanLimits defines the attribute, event, and link limits for spans.
|
||||
spanLimits SpanLimits
|
||||
|
||||
// resource contains attributes representing an entity that produces telemetry.
|
||||
resource *resource.Resource
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
||||
func (cfg tracerProviderConfig) MarshalLog() interface{} {
|
||||
return struct {
|
||||
SpanProcessors []SpanProcessor
|
||||
SamplerType string
|
||||
IDGeneratorType string
|
||||
SpanLimits SpanLimits
|
||||
Resource *resource.Resource
|
||||
}{
|
||||
SpanProcessors: cfg.processors,
|
||||
SamplerType: fmt.Sprintf("%T", cfg.sampler),
|
||||
IDGeneratorType: fmt.Sprintf("%T", cfg.idGenerator),
|
||||
SpanLimits: cfg.spanLimits,
|
||||
Resource: cfg.resource,
|
||||
}
|
||||
}
|
||||
|
||||
type TracerProvider struct {
|
||||
mu sync.Mutex
|
||||
namedTracer map[instrumentation.Library]*tracer
|
||||
spanProcessors atomic.Value
|
||||
|
||||
// These fields are not protected by the lock mu. They are assumed to be
|
||||
// immutable after creation of the TracerProvider.
|
||||
sampler Sampler
|
||||
idGenerator IDGenerator
|
||||
spanLimits SpanLimits
|
||||
resource *resource.Resource
|
||||
}
|
||||
|
||||
var _ trace.TracerProvider = &TracerProvider{}
|
||||
|
||||
// NewTracerProvider returns a new and configured TracerProvider.
|
||||
//
|
||||
// By default the returned TracerProvider is configured with:
|
||||
// - a ParentBased(AlwaysSample) Sampler
|
||||
// - a random number IDGenerator
|
||||
// - the resource.Default() Resource
|
||||
// - the default SpanLimits.
|
||||
//
|
||||
// The passed opts are used to override these default values and configure the
|
||||
// returned TracerProvider appropriately.
|
||||
func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {
|
||||
o := tracerProviderConfig{
|
||||
spanLimits: NewSpanLimits(),
|
||||
}
|
||||
o = applyTracerProviderEnvConfigs(o)
|
||||
|
||||
for _, opt := range opts {
|
||||
o = opt.apply(o)
|
||||
}
|
||||
|
||||
o = ensureValidTracerProviderConfig(o)
|
||||
|
||||
tp := &TracerProvider{
|
||||
namedTracer: make(map[instrumentation.Library]*tracer),
|
||||
sampler: o.sampler,
|
||||
idGenerator: o.idGenerator,
|
||||
spanLimits: o.spanLimits,
|
||||
resource: o.resource,
|
||||
}
|
||||
|
||||
global.Info("TracerProvider created", "config", o)
|
||||
|
||||
for _, sp := range o.processors {
|
||||
tp.RegisterSpanProcessor(sp)
|
||||
}
|
||||
|
||||
return tp
|
||||
}
|
||||
|
||||
// Tracer returns a Tracer with the given name and options. If a Tracer for
|
||||
// the given name and options does not exist it is created, otherwise the
|
||||
// existing Tracer is returned.
|
||||
//
|
||||
// If name is empty, DefaultTracerName is used instead.
|
||||
//
|
||||
// This method is safe to be called concurrently.
|
||||
func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
|
||||
c := trace.NewTracerConfig(opts...)
|
||||
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
if name == "" {
|
||||
name = defaultTracerName
|
||||
}
|
||||
il := instrumentation.Library{
|
||||
Name: name,
|
||||
Version: c.InstrumentationVersion(),
|
||||
SchemaURL: c.SchemaURL(),
|
||||
}
|
||||
t, ok := p.namedTracer[il]
|
||||
if !ok {
|
||||
t = &tracer{
|
||||
provider: p,
|
||||
instrumentationLibrary: il,
|
||||
}
|
||||
p.namedTracer[il] = t
|
||||
global.Info("Tracer created", "name", name, "version", c.InstrumentationVersion(), "schemaURL", c.SchemaURL())
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors
|
||||
func (p *TracerProvider) RegisterSpanProcessor(s SpanProcessor) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
new := spanProcessorStates{}
|
||||
if old, ok := p.spanProcessors.Load().(spanProcessorStates); ok {
|
||||
new = append(new, old...)
|
||||
}
|
||||
newSpanSync := &spanProcessorState{
|
||||
sp: s,
|
||||
state: &sync.Once{},
|
||||
}
|
||||
new = append(new, newSpanSync)
|
||||
p.spanProcessors.Store(new)
|
||||
}
|
||||
|
||||
// UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors
|
||||
func (p *TracerProvider) UnregisterSpanProcessor(s SpanProcessor) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
spss := spanProcessorStates{}
|
||||
old, ok := p.spanProcessors.Load().(spanProcessorStates)
|
||||
if !ok || len(old) == 0 {
|
||||
return
|
||||
}
|
||||
spss = append(spss, old...)
|
||||
|
||||
// stop the span processor if it is started and remove it from the list
|
||||
var stopOnce *spanProcessorState
|
||||
var idx int
|
||||
for i, sps := range spss {
|
||||
if sps.sp == s {
|
||||
stopOnce = sps
|
||||
idx = i
|
||||
}
|
||||
}
|
||||
if stopOnce != nil {
|
||||
stopOnce.state.Do(func() {
|
||||
if err := s.Shutdown(context.Background()); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
if len(spss) > 1 {
|
||||
copy(spss[idx:], spss[idx+1:])
|
||||
}
|
||||
spss[len(spss)-1] = nil
|
||||
spss = spss[:len(spss)-1]
|
||||
|
||||
p.spanProcessors.Store(spss)
|
||||
}
|
||||
|
||||
// ForceFlush immediately exports all spans that have not yet been exported for
|
||||
// all the registered span processors.
|
||||
func (p *TracerProvider) ForceFlush(ctx context.Context) error {
|
||||
spss, ok := p.spanProcessors.Load().(spanProcessorStates)
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to load span processors")
|
||||
}
|
||||
if len(spss) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, sps := range spss {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if err := sps.sp.ForceFlush(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown shuts down the span processors in the order they were registered.
|
||||
func (p *TracerProvider) Shutdown(ctx context.Context) error {
|
||||
spss, ok := p.spanProcessors.Load().(spanProcessorStates)
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to load span processors")
|
||||
}
|
||||
if len(spss) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, sps := range spss {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
var err error
|
||||
sps.state.Do(func() {
|
||||
err = sps.sp.Shutdown(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type TracerProviderOption interface {
|
||||
apply(tracerProviderConfig) tracerProviderConfig
|
||||
}
|
||||
|
||||
type traceProviderOptionFunc func(tracerProviderConfig) tracerProviderConfig
|
||||
|
||||
func (fn traceProviderOptionFunc) apply(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
return fn(cfg)
|
||||
}
|
||||
|
||||
// WithSyncer registers the exporter with the TracerProvider using a
|
||||
// SimpleSpanProcessor.
|
||||
//
|
||||
// This is not recommended for production use. The synchronous nature of the
|
||||
// SimpleSpanProcessor that will wrap the exporter make it good for testing,
|
||||
// debugging, or showing examples of other feature, but it will be slow and
|
||||
// have a high computation resource usage overhead. The WithBatcher option is
|
||||
// recommended for production use instead.
|
||||
func WithSyncer(e SpanExporter) TracerProviderOption {
|
||||
return WithSpanProcessor(NewSimpleSpanProcessor(e))
|
||||
}
|
||||
|
||||
// WithBatcher registers the exporter with the TracerProvider using a
|
||||
// BatchSpanProcessor configured with the passed opts.
|
||||
func WithBatcher(e SpanExporter, opts ...BatchSpanProcessorOption) TracerProviderOption {
|
||||
return WithSpanProcessor(NewBatchSpanProcessor(e, opts...))
|
||||
}
|
||||
|
||||
// WithSpanProcessor registers the SpanProcessor with a TracerProvider.
|
||||
func WithSpanProcessor(sp SpanProcessor) TracerProviderOption {
|
||||
return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
cfg.processors = append(cfg.processors, sp)
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithResource returns a TracerProviderOption that will configure the
|
||||
// Resource r as a TracerProvider's Resource. The configured Resource is
|
||||
// referenced by all the Tracers the TracerProvider creates. It represents the
|
||||
// entity producing telemetry.
|
||||
//
|
||||
// If this option is not used, the TracerProvider will use the
|
||||
// resource.Default() Resource by default.
|
||||
func WithResource(r *resource.Resource) TracerProviderOption {
|
||||
return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
var err error
|
||||
cfg.resource, err = resource.Merge(resource.Environment(), r)
|
||||
if err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithIDGenerator returns a TracerProviderOption that will configure the
|
||||
// IDGenerator g as a TracerProvider's IDGenerator. The configured IDGenerator
|
||||
// is used by the Tracers the TracerProvider creates to generate new Span and
|
||||
// Trace IDs.
|
||||
//
|
||||
// If this option is not used, the TracerProvider will use a random number
|
||||
// IDGenerator by default.
|
||||
func WithIDGenerator(g IDGenerator) TracerProviderOption {
|
||||
return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
if g != nil {
|
||||
cfg.idGenerator = g
|
||||
}
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithSampler returns a TracerProviderOption that will configure the Sampler
|
||||
// s as a TracerProvider's Sampler. The configured Sampler is used by the
|
||||
// Tracers the TracerProvider creates to make their sampling decisions for the
|
||||
// Spans they create.
|
||||
//
|
||||
// This option overrides the Sampler configured through the OTEL_TRACES_SAMPLER
|
||||
// and OTEL_TRACES_SAMPLER_ARG environment variables. If this option is not used
|
||||
// and the sampler is not configured through environment variables or the environment
|
||||
// contains invalid/unsupported configuration, the TracerProvider will use a
|
||||
// ParentBased(AlwaysSample) Sampler by default.
|
||||
func WithSampler(s Sampler) TracerProviderOption {
|
||||
return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
if s != nil {
|
||||
cfg.sampler = s
|
||||
}
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanLimits returns a TracerProviderOption that configures a
|
||||
// TracerProvider to use the SpanLimits sl. These SpanLimits bound any Span
|
||||
// created by a Tracer from the TracerProvider.
|
||||
//
|
||||
// If any field of sl is zero or negative it will be replaced with the default
|
||||
// value for that field.
|
||||
//
|
||||
// If this or WithRawSpanLimits are not provided, the TracerProvider will use
|
||||
// the limits defined by environment variables, or the defaults if unset.
|
||||
// Refer to the NewSpanLimits documentation for information about this
|
||||
// relationship.
|
||||
//
|
||||
// Deprecated: Use WithRawSpanLimits instead which allows setting unlimited
|
||||
// and zero limits. This option will be kept until the next major version
|
||||
// incremented release.
|
||||
func WithSpanLimits(sl SpanLimits) TracerProviderOption {
|
||||
if sl.AttributeValueLengthLimit <= 0 {
|
||||
sl.AttributeValueLengthLimit = DefaultAttributeValueLengthLimit
|
||||
}
|
||||
if sl.AttributeCountLimit <= 0 {
|
||||
sl.AttributeCountLimit = DefaultAttributeCountLimit
|
||||
}
|
||||
if sl.EventCountLimit <= 0 {
|
||||
sl.EventCountLimit = DefaultEventCountLimit
|
||||
}
|
||||
if sl.AttributePerEventCountLimit <= 0 {
|
||||
sl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit
|
||||
}
|
||||
if sl.LinkCountLimit <= 0 {
|
||||
sl.LinkCountLimit = DefaultLinkCountLimit
|
||||
}
|
||||
if sl.AttributePerLinkCountLimit <= 0 {
|
||||
sl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit
|
||||
}
|
||||
return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
cfg.spanLimits = sl
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithRawSpanLimits returns a TracerProviderOption that configures a
|
||||
// TracerProvider to use these limits. These limits bound any Span created by
|
||||
// a Tracer from the TracerProvider.
|
||||
//
|
||||
// The limits will be used as-is. Zero or negative values will not be changed
|
||||
// to the default value like WithSpanLimits does. Setting a limit to zero will
|
||||
// effectively disable the related resource it limits and setting to a
|
||||
// negative value will mean that resource is unlimited. Consequentially, this
|
||||
// means that the zero-value SpanLimits will disable all span resources.
|
||||
// Because of this, limits should be constructed using NewSpanLimits and
|
||||
// updated accordingly.
|
||||
//
|
||||
// If this or WithSpanLimits are not provided, the TracerProvider will use the
|
||||
// limits defined by environment variables, or the defaults if unset. Refer to
|
||||
// the NewSpanLimits documentation for information about this relationship.
|
||||
func WithRawSpanLimits(limits SpanLimits) TracerProviderOption {
|
||||
return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
cfg.spanLimits = limits
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
func applyTracerProviderEnvConfigs(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
for _, opt := range tracerProviderOptionsFromEnv() {
|
||||
cfg = opt.apply(cfg)
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func tracerProviderOptionsFromEnv() []TracerProviderOption {
|
||||
var opts []TracerProviderOption
|
||||
|
||||
sampler, err := samplerFromEnv()
|
||||
if err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
|
||||
if sampler != nil {
|
||||
opts = append(opts, WithSampler(sampler))
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
// ensureValidTracerProviderConfig ensures that given TracerProviderConfig is valid.
|
||||
func ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderConfig {
|
||||
if cfg.sampler == nil {
|
||||
cfg.sampler = ParentBased(AlwaysSample())
|
||||
}
|
||||
if cfg.idGenerator == nil {
|
||||
cfg.idGenerator = defaultIDGenerator()
|
||||
}
|
||||
if cfg.resource == nil {
|
||||
cfg.resource = resource.Default()
|
||||
}
|
||||
return cfg
|
||||
}
|
107
vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go
generated
vendored
Normal file
107
vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
tracesSamplerKey = "OTEL_TRACES_SAMPLER"
|
||||
tracesSamplerArgKey = "OTEL_TRACES_SAMPLER_ARG"
|
||||
|
||||
samplerAlwaysOn = "always_on"
|
||||
samplerAlwaysOff = "always_off"
|
||||
samplerTraceIDRatio = "traceidratio"
|
||||
samplerParentBasedAlwaysOn = "parentbased_always_on"
|
||||
samplerParsedBasedAlwaysOff = "parentbased_always_off"
|
||||
samplerParentBasedTraceIDRatio = "parentbased_traceidratio"
|
||||
)
|
||||
|
||||
type errUnsupportedSampler string
|
||||
|
||||
func (e errUnsupportedSampler) Error() string {
|
||||
return fmt.Sprintf("unsupported sampler: %s", string(e))
|
||||
}
|
||||
|
||||
var (
|
||||
errNegativeTraceIDRatio = errors.New("invalid trace ID ratio: less than 0.0")
|
||||
errGreaterThanOneTraceIDRatio = errors.New("invalid trace ID ratio: greater than 1.0")
|
||||
)
|
||||
|
||||
type samplerArgParseError struct {
|
||||
parseErr error
|
||||
}
|
||||
|
||||
func (e samplerArgParseError) Error() string {
|
||||
return fmt.Sprintf("parsing sampler argument: %s", e.parseErr.Error())
|
||||
}
|
||||
|
||||
func (e samplerArgParseError) Unwrap() error {
|
||||
return e.parseErr
|
||||
}
|
||||
|
||||
func samplerFromEnv() (Sampler, error) {
|
||||
sampler, ok := os.LookupEnv(tracesSamplerKey)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sampler = strings.ToLower(strings.TrimSpace(sampler))
|
||||
samplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey)
|
||||
samplerArg = strings.TrimSpace(samplerArg)
|
||||
|
||||
switch sampler {
|
||||
case samplerAlwaysOn:
|
||||
return AlwaysSample(), nil
|
||||
case samplerAlwaysOff:
|
||||
return NeverSample(), nil
|
||||
case samplerTraceIDRatio:
|
||||
ratio, err := parseTraceIDRatio(samplerArg, hasSamplerArg)
|
||||
return ratio, err
|
||||
case samplerParentBasedAlwaysOn:
|
||||
return ParentBased(AlwaysSample()), nil
|
||||
case samplerParsedBasedAlwaysOff:
|
||||
return ParentBased(NeverSample()), nil
|
||||
case samplerParentBasedTraceIDRatio:
|
||||
ratio, err := parseTraceIDRatio(samplerArg, hasSamplerArg)
|
||||
return ParentBased(ratio), err
|
||||
default:
|
||||
return nil, errUnsupportedSampler(sampler)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func parseTraceIDRatio(arg string, hasSamplerArg bool) (Sampler, error) {
|
||||
if !hasSamplerArg {
|
||||
return TraceIDRatioBased(1.0), nil
|
||||
}
|
||||
v, err := strconv.ParseFloat(arg, 64)
|
||||
if err != nil {
|
||||
return TraceIDRatioBased(1.0), samplerArgParseError{err}
|
||||
}
|
||||
if v < 0.0 {
|
||||
return TraceIDRatioBased(1.0), errNegativeTraceIDRatio
|
||||
}
|
||||
if v > 1.0 {
|
||||
return TraceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio
|
||||
}
|
||||
|
||||
return TraceIDRatioBased(v), nil
|
||||
}
|
292
vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go
generated
vendored
Normal file
292
vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go
generated
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Sampler decides whether a trace should be sampled and exported.
|
||||
type Sampler interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// ShouldSample returns a SamplingResult based on a decision made from the
|
||||
// passed parameters.
|
||||
ShouldSample(parameters SamplingParameters) SamplingResult
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Description returns information describing the Sampler.
|
||||
Description() string
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
// SamplingParameters contains the values passed to a Sampler.
|
||||
type SamplingParameters struct {
|
||||
ParentContext context.Context
|
||||
TraceID trace.TraceID
|
||||
Name string
|
||||
Kind trace.SpanKind
|
||||
Attributes []attribute.KeyValue
|
||||
Links []trace.Link
|
||||
}
|
||||
|
||||
// SamplingDecision indicates whether a span is dropped, recorded and/or sampled.
|
||||
type SamplingDecision uint8
|
||||
|
||||
// Valid sampling decisions
|
||||
const (
|
||||
// Drop will not record the span and all attributes/events will be dropped
|
||||
Drop SamplingDecision = iota
|
||||
|
||||
// Record indicates the span's `IsRecording() == true`, but `Sampled` flag
|
||||
// *must not* be set
|
||||
RecordOnly
|
||||
|
||||
// RecordAndSample has span's `IsRecording() == true` and `Sampled` flag
|
||||
// *must* be set
|
||||
RecordAndSample
|
||||
)
|
||||
|
||||
// SamplingResult conveys a SamplingDecision, set of Attributes and a Tracestate.
|
||||
type SamplingResult struct {
|
||||
Decision SamplingDecision
|
||||
Attributes []attribute.KeyValue
|
||||
Tracestate trace.TraceState
|
||||
}
|
||||
|
||||
type traceIDRatioSampler struct {
|
||||
traceIDUpperBound uint64
|
||||
description string
|
||||
}
|
||||
|
||||
func (ts traceIDRatioSampler) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
psc := trace.SpanContextFromContext(p.ParentContext)
|
||||
x := binary.BigEndian.Uint64(p.TraceID[0:8]) >> 1
|
||||
if x < ts.traceIDUpperBound {
|
||||
return SamplingResult{
|
||||
Decision: RecordAndSample,
|
||||
Tracestate: psc.TraceState(),
|
||||
}
|
||||
}
|
||||
return SamplingResult{
|
||||
Decision: Drop,
|
||||
Tracestate: psc.TraceState(),
|
||||
}
|
||||
}
|
||||
|
||||
func (ts traceIDRatioSampler) Description() string {
|
||||
return ts.description
|
||||
}
|
||||
|
||||
// TraceIDRatioBased samples a given fraction of traces. Fractions >= 1 will
|
||||
// always sample. Fractions < 0 are treated as zero. To respect the
|
||||
// parent trace's `SampledFlag`, the `TraceIDRatioBased` sampler should be used
|
||||
// as a delegate of a `Parent` sampler.
|
||||
//nolint:revive // revive complains about stutter of `trace.TraceIDRatioBased`
|
||||
func TraceIDRatioBased(fraction float64) Sampler {
|
||||
if fraction >= 1 {
|
||||
return AlwaysSample()
|
||||
}
|
||||
|
||||
if fraction <= 0 {
|
||||
fraction = 0
|
||||
}
|
||||
|
||||
return &traceIDRatioSampler{
|
||||
traceIDUpperBound: uint64(fraction * (1 << 63)),
|
||||
description: fmt.Sprintf("TraceIDRatioBased{%g}", fraction),
|
||||
}
|
||||
}
|
||||
|
||||
type alwaysOnSampler struct{}
|
||||
|
||||
func (as alwaysOnSampler) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
return SamplingResult{
|
||||
Decision: RecordAndSample,
|
||||
Tracestate: trace.SpanContextFromContext(p.ParentContext).TraceState(),
|
||||
}
|
||||
}
|
||||
|
||||
func (as alwaysOnSampler) Description() string {
|
||||
return "AlwaysOnSampler"
|
||||
}
|
||||
|
||||
// AlwaysSample returns a Sampler that samples every trace.
|
||||
// Be careful about using this sampler in a production application with
|
||||
// significant traffic: a new trace will be started and exported for every
|
||||
// request.
|
||||
func AlwaysSample() Sampler {
|
||||
return alwaysOnSampler{}
|
||||
}
|
||||
|
||||
type alwaysOffSampler struct{}
|
||||
|
||||
func (as alwaysOffSampler) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
return SamplingResult{
|
||||
Decision: Drop,
|
||||
Tracestate: trace.SpanContextFromContext(p.ParentContext).TraceState(),
|
||||
}
|
||||
}
|
||||
|
||||
func (as alwaysOffSampler) Description() string {
|
||||
return "AlwaysOffSampler"
|
||||
}
|
||||
|
||||
// NeverSample returns a Sampler that samples no traces.
|
||||
func NeverSample() Sampler {
|
||||
return alwaysOffSampler{}
|
||||
}
|
||||
|
||||
// ParentBased returns a composite sampler which behaves differently,
|
||||
// based on the parent of the span. If the span has no parent,
|
||||
// the root(Sampler) is used to make sampling decision. If the span has
|
||||
// a parent, depending on whether the parent is remote and whether it
|
||||
// is sampled, one of the following samplers will apply:
|
||||
// - remoteParentSampled(Sampler) (default: AlwaysOn)
|
||||
// - remoteParentNotSampled(Sampler) (default: AlwaysOff)
|
||||
// - localParentSampled(Sampler) (default: AlwaysOn)
|
||||
// - localParentNotSampled(Sampler) (default: AlwaysOff)
|
||||
func ParentBased(root Sampler, samplers ...ParentBasedSamplerOption) Sampler {
|
||||
return parentBased{
|
||||
root: root,
|
||||
config: configureSamplersForParentBased(samplers),
|
||||
}
|
||||
}
|
||||
|
||||
type parentBased struct {
|
||||
root Sampler
|
||||
config samplerConfig
|
||||
}
|
||||
|
||||
func configureSamplersForParentBased(samplers []ParentBasedSamplerOption) samplerConfig {
|
||||
c := samplerConfig{
|
||||
remoteParentSampled: AlwaysSample(),
|
||||
remoteParentNotSampled: NeverSample(),
|
||||
localParentSampled: AlwaysSample(),
|
||||
localParentNotSampled: NeverSample(),
|
||||
}
|
||||
|
||||
for _, so := range samplers {
|
||||
c = so.apply(c)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// samplerConfig is a group of options for parentBased sampler.
|
||||
type samplerConfig struct {
|
||||
remoteParentSampled, remoteParentNotSampled Sampler
|
||||
localParentSampled, localParentNotSampled Sampler
|
||||
}
|
||||
|
||||
// ParentBasedSamplerOption configures the sampler for a particular sampling case.
|
||||
type ParentBasedSamplerOption interface {
|
||||
apply(samplerConfig) samplerConfig
|
||||
}
|
||||
|
||||
// WithRemoteParentSampled sets the sampler for the case of sampled remote parent.
|
||||
func WithRemoteParentSampled(s Sampler) ParentBasedSamplerOption {
|
||||
return remoteParentSampledOption{s}
|
||||
}
|
||||
|
||||
type remoteParentSampledOption struct {
|
||||
s Sampler
|
||||
}
|
||||
|
||||
func (o remoteParentSampledOption) apply(config samplerConfig) samplerConfig {
|
||||
config.remoteParentSampled = o.s
|
||||
return config
|
||||
}
|
||||
|
||||
// WithRemoteParentNotSampled sets the sampler for the case of remote parent
|
||||
// which is not sampled.
|
||||
func WithRemoteParentNotSampled(s Sampler) ParentBasedSamplerOption {
|
||||
return remoteParentNotSampledOption{s}
|
||||
}
|
||||
|
||||
type remoteParentNotSampledOption struct {
|
||||
s Sampler
|
||||
}
|
||||
|
||||
func (o remoteParentNotSampledOption) apply(config samplerConfig) samplerConfig {
|
||||
config.remoteParentNotSampled = o.s
|
||||
return config
|
||||
}
|
||||
|
||||
// WithLocalParentSampled sets the sampler for the case of sampled local parent.
|
||||
func WithLocalParentSampled(s Sampler) ParentBasedSamplerOption {
|
||||
return localParentSampledOption{s}
|
||||
}
|
||||
|
||||
type localParentSampledOption struct {
|
||||
s Sampler
|
||||
}
|
||||
|
||||
func (o localParentSampledOption) apply(config samplerConfig) samplerConfig {
|
||||
config.localParentSampled = o.s
|
||||
return config
|
||||
}
|
||||
|
||||
// WithLocalParentNotSampled sets the sampler for the case of local parent
|
||||
// which is not sampled.
|
||||
func WithLocalParentNotSampled(s Sampler) ParentBasedSamplerOption {
|
||||
return localParentNotSampledOption{s}
|
||||
}
|
||||
|
||||
type localParentNotSampledOption struct {
|
||||
s Sampler
|
||||
}
|
||||
|
||||
func (o localParentNotSampledOption) apply(config samplerConfig) samplerConfig {
|
||||
config.localParentNotSampled = o.s
|
||||
return config
|
||||
}
|
||||
|
||||
func (pb parentBased) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
psc := trace.SpanContextFromContext(p.ParentContext)
|
||||
if psc.IsValid() {
|
||||
if psc.IsRemote() {
|
||||
if psc.IsSampled() {
|
||||
return pb.config.remoteParentSampled.ShouldSample(p)
|
||||
}
|
||||
return pb.config.remoteParentNotSampled.ShouldSample(p)
|
||||
}
|
||||
|
||||
if psc.IsSampled() {
|
||||
return pb.config.localParentSampled.ShouldSample(p)
|
||||
}
|
||||
return pb.config.localParentNotSampled.ShouldSample(p)
|
||||
}
|
||||
return pb.root.ShouldSample(p)
|
||||
}
|
||||
|
||||
func (pb parentBased) Description() string {
|
||||
return fmt.Sprintf("ParentBased{root:%s,remoteParentSampled:%s,"+
|
||||
"remoteParentNotSampled:%s,localParentSampled:%s,localParentNotSampled:%s}",
|
||||
pb.root.Description(),
|
||||
pb.config.remoteParentSampled.Description(),
|
||||
pb.config.remoteParentNotSampled.Description(),
|
||||
pb.config.localParentSampled.Description(),
|
||||
pb.config.localParentNotSampled.Description(),
|
||||
)
|
||||
}
|
128
vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go
generated
vendored
Normal file
128
vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
// simpleSpanProcessor is a SpanProcessor that synchronously sends all
|
||||
// completed Spans to a trace.Exporter immediately.
|
||||
type simpleSpanProcessor struct {
|
||||
exporterMu sync.RWMutex
|
||||
exporter SpanExporter
|
||||
stopOnce sync.Once
|
||||
}
|
||||
|
||||
var _ SpanProcessor = (*simpleSpanProcessor)(nil)
|
||||
|
||||
// NewSimpleSpanProcessor returns a new SpanProcessor that will synchronously
|
||||
// send completed spans to the exporter immediately.
|
||||
//
|
||||
// This SpanProcessor is not recommended for production use. The synchronous
|
||||
// nature of this SpanProcessor make it good for testing, debugging, or
|
||||
// showing examples of other feature, but it will be slow and have a high
|
||||
// computation resource usage overhead. The BatchSpanProcessor is recommended
|
||||
// for production use instead.
|
||||
func NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor {
|
||||
ssp := &simpleSpanProcessor{
|
||||
exporter: exporter,
|
||||
}
|
||||
return ssp
|
||||
}
|
||||
|
||||
// OnStart does nothing.
|
||||
func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {}
|
||||
|
||||
// OnEnd immediately exports a ReadOnlySpan.
|
||||
func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) {
|
||||
ssp.exporterMu.RLock()
|
||||
defer ssp.exporterMu.RUnlock()
|
||||
|
||||
if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() {
|
||||
if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown shuts down the exporter this SimpleSpanProcessor exports to.
|
||||
func (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error {
|
||||
var err error
|
||||
ssp.stopOnce.Do(func() {
|
||||
stopFunc := func(exp SpanExporter) (<-chan error, func()) {
|
||||
done := make(chan error)
|
||||
return done, func() { done <- exp.Shutdown(ctx) }
|
||||
}
|
||||
|
||||
// The exporter field of the simpleSpanProcessor needs to be zeroed to
|
||||
// signal it is shut down, meaning all subsequent calls to OnEnd will
|
||||
// be gracefully ignored. This needs to be done synchronously to avoid
|
||||
// any race condition.
|
||||
//
|
||||
// A closure is used to keep reference to the exporter and then the
|
||||
// field is zeroed. This ensures the simpleSpanProcessor is shut down
|
||||
// before the exporter. This order is important as it avoids a
|
||||
// potential deadlock. If the exporter shut down operation generates a
|
||||
// span, that span would need to be exported. Meaning, OnEnd would be
|
||||
// called and try acquiring the lock that is held here.
|
||||
ssp.exporterMu.Lock()
|
||||
done, shutdown := stopFunc(ssp.exporter)
|
||||
ssp.exporter = nil
|
||||
ssp.exporterMu.Unlock()
|
||||
|
||||
go shutdown()
|
||||
|
||||
// Wait for the exporter to shut down or the deadline to expire.
|
||||
select {
|
||||
case err = <-done:
|
||||
case <-ctx.Done():
|
||||
// It is possible for the exporter to have immediately shut down
|
||||
// and the context to be done simultaneously. In that case this
|
||||
// outer select statement will randomly choose a case. This will
|
||||
// result in a different returned error for similar scenarios.
|
||||
// Instead, double check if the exporter shut down at the same
|
||||
// time and return that error if so. This will ensure consistency
|
||||
// as well as ensure the caller knows the exporter shut down
|
||||
// successfully (they can already determine if the deadline is
|
||||
// expired given they passed the context).
|
||||
select {
|
||||
case err = <-done:
|
||||
default:
|
||||
err = ctx.Err()
|
||||
}
|
||||
}
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// ForceFlush does nothing as there is no data to flush.
|
||||
func (ssp *simpleSpanProcessor) ForceFlush(context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this Span Processor.
|
||||
func (ssp *simpleSpanProcessor) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Type string
|
||||
Exporter SpanExporter
|
||||
}{
|
||||
Type: "SimpleSpanProcessor",
|
||||
Exporter: ssp.exporter,
|
||||
}
|
||||
}
|
138
vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go
generated
vendored
Normal file
138
vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// snapshot is an record of a spans state at a particular checkpointed time.
|
||||
// It is used as a read-only representation of that state.
|
||||
type snapshot struct {
|
||||
name string
|
||||
spanContext trace.SpanContext
|
||||
parent trace.SpanContext
|
||||
spanKind trace.SpanKind
|
||||
startTime time.Time
|
||||
endTime time.Time
|
||||
attributes []attribute.KeyValue
|
||||
events []Event
|
||||
links []Link
|
||||
status Status
|
||||
childSpanCount int
|
||||
droppedAttributeCount int
|
||||
droppedEventCount int
|
||||
droppedLinkCount int
|
||||
resource *resource.Resource
|
||||
instrumentationLibrary instrumentation.Library
|
||||
}
|
||||
|
||||
var _ ReadOnlySpan = snapshot{}
|
||||
|
||||
func (s snapshot) private() {}
|
||||
|
||||
// Name returns the name of the span.
|
||||
func (s snapshot) Name() string {
|
||||
return s.name
|
||||
}
|
||||
|
||||
// SpanContext returns the unique SpanContext that identifies the span.
|
||||
func (s snapshot) SpanContext() trace.SpanContext {
|
||||
return s.spanContext
|
||||
}
|
||||
|
||||
// Parent returns the unique SpanContext that identifies the parent of the
|
||||
// span if one exists. If the span has no parent the returned SpanContext
|
||||
// will be invalid.
|
||||
func (s snapshot) Parent() trace.SpanContext {
|
||||
return s.parent
|
||||
}
|
||||
|
||||
// SpanKind returns the role the span plays in a Trace.
|
||||
func (s snapshot) SpanKind() trace.SpanKind {
|
||||
return s.spanKind
|
||||
}
|
||||
|
||||
// StartTime returns the time the span started recording.
|
||||
func (s snapshot) StartTime() time.Time {
|
||||
return s.startTime
|
||||
}
|
||||
|
||||
// EndTime returns the time the span stopped recording. It will be zero if
|
||||
// the span has not ended.
|
||||
func (s snapshot) EndTime() time.Time {
|
||||
return s.endTime
|
||||
}
|
||||
|
||||
// Attributes returns the defining attributes of the span.
|
||||
func (s snapshot) Attributes() []attribute.KeyValue {
|
||||
return s.attributes
|
||||
}
|
||||
|
||||
// Links returns all the links the span has to other spans.
|
||||
func (s snapshot) Links() []Link {
|
||||
return s.links
|
||||
}
|
||||
|
||||
// Events returns all the events that occurred within in the spans
|
||||
// lifetime.
|
||||
func (s snapshot) Events() []Event {
|
||||
return s.events
|
||||
}
|
||||
|
||||
// Status returns the spans status.
|
||||
func (s snapshot) Status() Status {
|
||||
return s.status
|
||||
}
|
||||
|
||||
// InstrumentationLibrary returns information about the instrumentation
|
||||
// library that created the span.
|
||||
func (s snapshot) InstrumentationLibrary() instrumentation.Library {
|
||||
return s.instrumentationLibrary
|
||||
}
|
||||
|
||||
// Resource returns information about the entity that produced the span.
|
||||
func (s snapshot) Resource() *resource.Resource {
|
||||
return s.resource
|
||||
}
|
||||
|
||||
// DroppedAttributes returns the number of attributes dropped by the span
|
||||
// due to limits being reached.
|
||||
func (s snapshot) DroppedAttributes() int {
|
||||
return s.droppedAttributeCount
|
||||
}
|
||||
|
||||
// DroppedLinks returns the number of links dropped by the span due to limits
|
||||
// being reached.
|
||||
func (s snapshot) DroppedLinks() int {
|
||||
return s.droppedLinkCount
|
||||
}
|
||||
|
||||
// DroppedEvents returns the number of events dropped by the span due to
|
||||
// limits being reached.
|
||||
func (s snapshot) DroppedEvents() int {
|
||||
return s.droppedEventCount
|
||||
}
|
||||
|
||||
// ChildSpanCount returns the count of spans that consider the span a
|
||||
// direct parent.
|
||||
func (s snapshot) ChildSpanCount() int {
|
||||
return s.childSpanCount
|
||||
}
|
797
vendor/go.opentelemetry.io/otel/sdk/trace/span.go
generated
vendored
Normal file
797
vendor/go.opentelemetry.io/otel/sdk/trace/span.go
generated
vendored
Normal file
@@ -0,0 +1,797 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
rt "runtime/trace"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
"go.opentelemetry.io/otel/sdk/internal"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// ReadOnlySpan allows reading information from the data structure underlying a
|
||||
// trace.Span. It is used in places where reading information from a span is
|
||||
// necessary but changing the span isn't necessary or allowed.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type ReadOnlySpan interface {
|
||||
// Name returns the name of the span.
|
||||
Name() string
|
||||
// SpanContext returns the unique SpanContext that identifies the span.
|
||||
SpanContext() trace.SpanContext
|
||||
// Parent returns the unique SpanContext that identifies the parent of the
|
||||
// span if one exists. If the span has no parent the returned SpanContext
|
||||
// will be invalid.
|
||||
Parent() trace.SpanContext
|
||||
// SpanKind returns the role the span plays in a Trace.
|
||||
SpanKind() trace.SpanKind
|
||||
// StartTime returns the time the span started recording.
|
||||
StartTime() time.Time
|
||||
// EndTime returns the time the span stopped recording. It will be zero if
|
||||
// the span has not ended.
|
||||
EndTime() time.Time
|
||||
// Attributes returns the defining attributes of the span.
|
||||
// The order of the returned attributes is not guaranteed to be stable across invocations.
|
||||
Attributes() []attribute.KeyValue
|
||||
// Links returns all the links the span has to other spans.
|
||||
Links() []Link
|
||||
// Events returns all the events that occurred within in the spans
|
||||
// lifetime.
|
||||
Events() []Event
|
||||
// Status returns the spans status.
|
||||
Status() Status
|
||||
// InstrumentationLibrary returns information about the instrumentation
|
||||
// library that created the span.
|
||||
InstrumentationLibrary() instrumentation.Library
|
||||
// Resource returns information about the entity that produced the span.
|
||||
Resource() *resource.Resource
|
||||
// DroppedAttributes returns the number of attributes dropped by the span
|
||||
// due to limits being reached.
|
||||
DroppedAttributes() int
|
||||
// DroppedLinks returns the number of links dropped by the span due to
|
||||
// limits being reached.
|
||||
DroppedLinks() int
|
||||
// DroppedEvents returns the number of events dropped by the span due to
|
||||
// limits being reached.
|
||||
DroppedEvents() int
|
||||
// ChildSpanCount returns the count of spans that consider the span a
|
||||
// direct parent.
|
||||
ChildSpanCount() int
|
||||
|
||||
// A private method to prevent users implementing the
|
||||
// interface and so future additions to it will not
|
||||
// violate compatibility.
|
||||
private()
|
||||
}
|
||||
|
||||
// ReadWriteSpan exposes the same methods as trace.Span and in addition allows
|
||||
// reading information from the underlying data structure.
|
||||
// This interface exposes the union of the methods of trace.Span (which is a
|
||||
// "write-only" span) and ReadOnlySpan. New methods for writing or reading span
|
||||
// information should be added under trace.Span or ReadOnlySpan, respectively.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type ReadWriteSpan interface {
|
||||
trace.Span
|
||||
ReadOnlySpan
|
||||
}
|
||||
|
||||
// recordingSpan is an implementation of the OpenTelemetry Span API
|
||||
// representing the individual component of a trace that is sampled.
|
||||
type recordingSpan struct {
|
||||
// mu protects the contents of this span.
|
||||
mu sync.Mutex
|
||||
|
||||
// parent holds the parent span of this span as a trace.SpanContext.
|
||||
parent trace.SpanContext
|
||||
|
||||
// spanKind represents the kind of this span as a trace.SpanKind.
|
||||
spanKind trace.SpanKind
|
||||
|
||||
// name is the name of this span.
|
||||
name string
|
||||
|
||||
// startTime is the time at which this span was started.
|
||||
startTime time.Time
|
||||
|
||||
// endTime is the time at which this span was ended. It contains the zero
|
||||
// value of time.Time until the span is ended.
|
||||
endTime time.Time
|
||||
|
||||
// status is the status of this span.
|
||||
status Status
|
||||
|
||||
// childSpanCount holds the number of child spans created for this span.
|
||||
childSpanCount int
|
||||
|
||||
// spanContext holds the SpanContext of this span.
|
||||
spanContext trace.SpanContext
|
||||
|
||||
// attributes is a collection of user provided key/values. The collection
|
||||
// is constrained by a configurable maximum held by the parent
|
||||
// TracerProvider. When additional attributes are added after this maximum
|
||||
// is reached these attributes the user is attempting to add are dropped.
|
||||
// This dropped number of attributes is tracked and reported in the
|
||||
// ReadOnlySpan exported when the span ends.
|
||||
attributes []attribute.KeyValue
|
||||
droppedAttributes int
|
||||
|
||||
// events are stored in FIFO queue capped by configured limit.
|
||||
events evictedQueue
|
||||
|
||||
// links are stored in FIFO queue capped by configured limit.
|
||||
links evictedQueue
|
||||
|
||||
// executionTracerTaskEnd ends the execution tracer span.
|
||||
executionTracerTaskEnd func()
|
||||
|
||||
// tracer is the SDK tracer that created this span.
|
||||
tracer *tracer
|
||||
}
|
||||
|
||||
var _ ReadWriteSpan = (*recordingSpan)(nil)
|
||||
var _ runtimeTracer = (*recordingSpan)(nil)
|
||||
|
||||
// SpanContext returns the SpanContext of this span.
|
||||
func (s *recordingSpan) SpanContext() trace.SpanContext {
|
||||
if s == nil {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
return s.spanContext
|
||||
}
|
||||
|
||||
// IsRecording returns if this span is being recorded. If this span has ended
|
||||
// this will return false.
|
||||
func (s *recordingSpan) IsRecording() bool {
|
||||
if s == nil {
|
||||
return false
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
return s.endTime.IsZero()
|
||||
}
|
||||
|
||||
// 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 the set status when the code is for an error. If this span is
|
||||
// not being recorded than this method does nothing.
|
||||
func (s *recordingSpan) SetStatus(code codes.Code, description string) {
|
||||
if !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
|
||||
status := Status{Code: code}
|
||||
if code == codes.Error {
|
||||
status.Description = description
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
s.status = status
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
// SetAttributes sets attributes of this span.
|
||||
//
|
||||
// If a key from attributes already exists the value associated with that key
|
||||
// will be overwritten with the value contained in attributes.
|
||||
//
|
||||
// If this span is not being recorded than this method does nothing.
|
||||
//
|
||||
// If adding attributes to the span would exceed the maximum amount of
|
||||
// attributes the span is configured to have, the last added attributes will
|
||||
// be dropped.
|
||||
func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) {
|
||||
if !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
limit := s.tracer.provider.spanLimits.AttributeCountLimit
|
||||
if limit == 0 {
|
||||
// No attributes allowed.
|
||||
s.droppedAttributes += len(attributes)
|
||||
return
|
||||
}
|
||||
|
||||
// If adding these attributes could exceed the capacity of s perform a
|
||||
// de-duplication and truncation while adding to avoid over allocation.
|
||||
if limit > 0 && len(s.attributes)+len(attributes) > limit {
|
||||
s.addOverCapAttrs(limit, attributes)
|
||||
return
|
||||
}
|
||||
|
||||
// Otherwise, add without deduplication. When attributes are read they
|
||||
// will be deduplicated, optimizing the operation.
|
||||
for _, a := range attributes {
|
||||
if !a.Valid() {
|
||||
// Drop all invalid attributes.
|
||||
s.droppedAttributes++
|
||||
continue
|
||||
}
|
||||
a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)
|
||||
s.attributes = append(s.attributes, a)
|
||||
}
|
||||
}
|
||||
|
||||
// addOverCapAttrs adds the attributes attrs to the span s while
|
||||
// de-duplicating the attributes of s and attrs and dropping attributes that
|
||||
// exceed the limit.
|
||||
//
|
||||
// This method assumes s.mu.Lock is held by the caller.
|
||||
//
|
||||
// This method should only be called when there is a possibility that adding
|
||||
// attrs to s will exceed the limit. Otherwise, attrs should be added to s
|
||||
// without checking for duplicates and all retrieval methods of the attributes
|
||||
// for s will de-duplicate as needed.
|
||||
//
|
||||
// This method assumes limit is a value > 0. The argument should be validated
|
||||
// by the caller.
|
||||
func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) {
|
||||
// In order to not allocate more capacity to s.attributes than needed,
|
||||
// prune and truncate this addition of attributes while adding.
|
||||
|
||||
// Do not set a capacity when creating this map. Benchmark testing has
|
||||
// showed this to only add unused memory allocations in general use.
|
||||
exists := make(map[attribute.Key]int)
|
||||
s.dedupeAttrsFromRecord(&exists)
|
||||
|
||||
// Now that s.attributes is deduplicated, adding unique attributes up to
|
||||
// the capacity of s will not over allocate s.attributes.
|
||||
for _, a := range attrs {
|
||||
if !a.Valid() {
|
||||
// Drop all invalid attributes.
|
||||
s.droppedAttributes++
|
||||
continue
|
||||
}
|
||||
|
||||
if idx, ok := exists[a.Key]; ok {
|
||||
// Perform all updates before dropping, even when at capacity.
|
||||
s.attributes[idx] = a
|
||||
continue
|
||||
}
|
||||
|
||||
if len(s.attributes) >= limit {
|
||||
// Do not just drop all of the remaining attributes, make sure
|
||||
// updates are checked and performed.
|
||||
s.droppedAttributes++
|
||||
} else {
|
||||
a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)
|
||||
s.attributes = append(s.attributes, a)
|
||||
exists[a.Key] = len(s.attributes) - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// truncateAttr returns a truncated version of attr. Only string and string
|
||||
// slice attribute values are truncated. String values are truncated to at
|
||||
// most a length of limit. Each string slice value is truncated in this fasion
|
||||
// (the slice length itself is unaffected).
|
||||
//
|
||||
// No truncation is perfromed for a negative limit.
|
||||
func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue {
|
||||
if limit < 0 {
|
||||
return attr
|
||||
}
|
||||
switch attr.Value.Type() {
|
||||
case attribute.STRING:
|
||||
if v := attr.Value.AsString(); len(v) > limit {
|
||||
return attr.Key.String(v[:limit])
|
||||
}
|
||||
case attribute.STRINGSLICE:
|
||||
// Do no mutate the original, make a copy.
|
||||
trucated := attr.Key.StringSlice(attr.Value.AsStringSlice())
|
||||
// Do not do this.
|
||||
//
|
||||
// v := trucated.Value.AsStringSlice()
|
||||
// cp := make([]string, len(v))
|
||||
// /* Copy and truncate values to cp ... */
|
||||
// trucated.Value = attribute.StringSliceValue(cp)
|
||||
//
|
||||
// Copying the []string and then assigning it back as a new value with
|
||||
// attribute.StringSliceValue will copy the data twice. Instead, we
|
||||
// already made a copy above that only this function owns, update the
|
||||
// underlying slice data of our copy.
|
||||
v := trucated.Value.AsStringSlice()
|
||||
for i := range v {
|
||||
if len(v[i]) > limit {
|
||||
v[i] = v[i][:limit]
|
||||
}
|
||||
}
|
||||
return trucated
|
||||
}
|
||||
return attr
|
||||
}
|
||||
|
||||
// End ends the span. This method does nothing if the span is already ended or
|
||||
// is not being recorded.
|
||||
//
|
||||
// The only SpanOption currently supported is WithTimestamp which will set the
|
||||
// end time for a Span's life-cycle.
|
||||
//
|
||||
// If this method is called while panicking an error event is added to the
|
||||
// Span before ending it and the panic is continued.
|
||||
func (s *recordingSpan) End(options ...trace.SpanEndOption) {
|
||||
// Do not start by checking if the span is being recorded which requires
|
||||
// acquiring a lock. Make a minimal check that the span is not nil.
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Store the end time as soon as possible to avoid artificially increasing
|
||||
// the span's duration in case some operation below takes a while.
|
||||
et := internal.MonotonicEndTime(s.startTime)
|
||||
|
||||
// Do relative expensive check now that we have an end time and see if we
|
||||
// need to do any more processing.
|
||||
if !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
|
||||
config := trace.NewSpanEndConfig(options...)
|
||||
if recovered := recover(); recovered != nil {
|
||||
// Record but don't stop the panic.
|
||||
defer panic(recovered)
|
||||
opts := []trace.EventOption{
|
||||
trace.WithAttributes(
|
||||
semconv.ExceptionTypeKey.String(typeStr(recovered)),
|
||||
semconv.ExceptionMessageKey.String(fmt.Sprint(recovered)),
|
||||
),
|
||||
}
|
||||
|
||||
if config.StackTrace() {
|
||||
opts = append(opts, trace.WithAttributes(
|
||||
semconv.ExceptionStacktraceKey.String(recordStackTrace()),
|
||||
))
|
||||
}
|
||||
|
||||
s.addEvent(semconv.ExceptionEventName, opts...)
|
||||
}
|
||||
|
||||
if s.executionTracerTaskEnd != nil {
|
||||
s.executionTracerTaskEnd()
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
// Setting endTime to non-zero marks the span as ended and not recording.
|
||||
if config.Timestamp().IsZero() {
|
||||
s.endTime = et
|
||||
} else {
|
||||
s.endTime = config.Timestamp()
|
||||
}
|
||||
s.mu.Unlock()
|
||||
|
||||
if sps, ok := s.tracer.provider.spanProcessors.Load().(spanProcessorStates); ok {
|
||||
if len(sps) == 0 {
|
||||
return
|
||||
}
|
||||
snap := s.snapshot()
|
||||
for _, sp := range sps {
|
||||
sp.sp.OnEnd(snap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RecordError will record err as a span event for this span. An additional call to
|
||||
// SetStatus is required if the Status of the Span should be set to Error, this method
|
||||
// does not change the Span status. If this span is not being recorded or err is nil
|
||||
// than this method does nothing.
|
||||
func (s *recordingSpan) RecordError(err error, opts ...trace.EventOption) {
|
||||
if s == nil || err == nil || !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
|
||||
opts = append(opts, trace.WithAttributes(
|
||||
semconv.ExceptionTypeKey.String(typeStr(err)),
|
||||
semconv.ExceptionMessageKey.String(err.Error()),
|
||||
))
|
||||
|
||||
c := trace.NewEventConfig(opts...)
|
||||
if c.StackTrace() {
|
||||
opts = append(opts, trace.WithAttributes(
|
||||
semconv.ExceptionStacktraceKey.String(recordStackTrace()),
|
||||
))
|
||||
}
|
||||
|
||||
s.addEvent(semconv.ExceptionEventName, opts...)
|
||||
}
|
||||
|
||||
func typeStr(i interface{}) string {
|
||||
t := reflect.TypeOf(i)
|
||||
if t.PkgPath() == "" && t.Name() == "" {
|
||||
// Likely a builtin type.
|
||||
return t.String()
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name())
|
||||
}
|
||||
|
||||
func recordStackTrace() string {
|
||||
stackTrace := make([]byte, 2048)
|
||||
n := runtime.Stack(stackTrace, false)
|
||||
|
||||
return string(stackTrace[0:n])
|
||||
}
|
||||
|
||||
// AddEvent adds an event with the provided name and options. If this span is
|
||||
// not being recorded than this method does nothing.
|
||||
func (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) {
|
||||
if !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
s.addEvent(name, o...)
|
||||
}
|
||||
|
||||
func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) {
|
||||
c := trace.NewEventConfig(o...)
|
||||
e := Event{Name: name, Attributes: c.Attributes(), Time: c.Timestamp()}
|
||||
|
||||
// Discard attributes over limit.
|
||||
limit := s.tracer.provider.spanLimits.AttributePerEventCountLimit
|
||||
if limit == 0 {
|
||||
// Drop all attributes.
|
||||
e.DroppedAttributeCount = len(e.Attributes)
|
||||
e.Attributes = nil
|
||||
} else if limit > 0 && len(e.Attributes) > limit {
|
||||
// Drop over capacity.
|
||||
e.DroppedAttributeCount = len(e.Attributes) - limit
|
||||
e.Attributes = e.Attributes[:limit]
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
s.events.add(e)
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
// SetName sets the name of this span. If this span is not being recorded than
|
||||
// this method does nothing.
|
||||
func (s *recordingSpan) SetName(name string) {
|
||||
if !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.name = name
|
||||
}
|
||||
|
||||
// Name returns the name of this span.
|
||||
func (s *recordingSpan) Name() string {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.name
|
||||
}
|
||||
|
||||
// Name returns the SpanContext of this span's parent span.
|
||||
func (s *recordingSpan) Parent() trace.SpanContext {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.parent
|
||||
}
|
||||
|
||||
// SpanKind returns the SpanKind of this span.
|
||||
func (s *recordingSpan) SpanKind() trace.SpanKind {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.spanKind
|
||||
}
|
||||
|
||||
// StartTime returns the time this span started.
|
||||
func (s *recordingSpan) StartTime() time.Time {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.startTime
|
||||
}
|
||||
|
||||
// EndTime returns the time this span ended. For spans that have not yet
|
||||
// ended, the returned value will be the zero value of time.Time.
|
||||
func (s *recordingSpan) EndTime() time.Time {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.endTime
|
||||
}
|
||||
|
||||
// Attributes returns the attributes of this span.
|
||||
//
|
||||
// The order of the returned attributes is not guaranteed to be stable.
|
||||
func (s *recordingSpan) Attributes() []attribute.KeyValue {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.dedupeAttrs()
|
||||
return s.attributes
|
||||
}
|
||||
|
||||
// dedupeAttrs deduplicates the attributes of s to fit capacity.
|
||||
//
|
||||
// This method assumes s.mu.Lock is held by the caller.
|
||||
func (s *recordingSpan) dedupeAttrs() {
|
||||
// Do not set a capacity when creating this map. Benchmark testing has
|
||||
// showed this to only add unused memory allocations in general use.
|
||||
exists := make(map[attribute.Key]int)
|
||||
s.dedupeAttrsFromRecord(&exists)
|
||||
}
|
||||
|
||||
// dedupeAttrsFromRecord deduplicates the attributes of s to fit capacity
|
||||
// using record as the record of unique attribute keys to their index.
|
||||
//
|
||||
// This method assumes s.mu.Lock is held by the caller.
|
||||
func (s *recordingSpan) dedupeAttrsFromRecord(record *map[attribute.Key]int) {
|
||||
// Use the fact that slices share the same backing array.
|
||||
unique := s.attributes[:0]
|
||||
for _, a := range s.attributes {
|
||||
if idx, ok := (*record)[a.Key]; ok {
|
||||
unique[idx] = a
|
||||
} else {
|
||||
unique = append(unique, a)
|
||||
(*record)[a.Key] = len(unique) - 1
|
||||
}
|
||||
}
|
||||
// s.attributes have element types of attribute.KeyValue. These types are
|
||||
// not pointers and they themselves do not contain pointer fields,
|
||||
// therefore the duplicate values do not need to be zeroed for them to be
|
||||
// garbage collected.
|
||||
s.attributes = unique
|
||||
}
|
||||
|
||||
// Links returns the links of this span.
|
||||
func (s *recordingSpan) Links() []Link {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if len(s.links.queue) == 0 {
|
||||
return []Link{}
|
||||
}
|
||||
return s.interfaceArrayToLinksArray()
|
||||
}
|
||||
|
||||
// Events returns the events of this span.
|
||||
func (s *recordingSpan) Events() []Event {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if len(s.events.queue) == 0 {
|
||||
return []Event{}
|
||||
}
|
||||
return s.interfaceArrayToEventArray()
|
||||
}
|
||||
|
||||
// Status returns the status of this span.
|
||||
func (s *recordingSpan) Status() Status {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.status
|
||||
}
|
||||
|
||||
// InstrumentationLibrary returns the instrumentation.Library associated with
|
||||
// the Tracer that created this span.
|
||||
func (s *recordingSpan) InstrumentationLibrary() instrumentation.Library {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.tracer.instrumentationLibrary
|
||||
}
|
||||
|
||||
// Resource returns the Resource associated with the Tracer that created this
|
||||
// span.
|
||||
func (s *recordingSpan) Resource() *resource.Resource {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.tracer.provider.resource
|
||||
}
|
||||
|
||||
func (s *recordingSpan) addLink(link trace.Link) {
|
||||
if !s.IsRecording() || !link.SpanContext.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
l := Link{SpanContext: link.SpanContext, Attributes: link.Attributes}
|
||||
|
||||
// Discard attributes over limit.
|
||||
limit := s.tracer.provider.spanLimits.AttributePerLinkCountLimit
|
||||
if limit == 0 {
|
||||
// Drop all attributes.
|
||||
l.DroppedAttributeCount = len(l.Attributes)
|
||||
l.Attributes = nil
|
||||
} else if limit > 0 && len(l.Attributes) > limit {
|
||||
l.DroppedAttributeCount = len(l.Attributes) - limit
|
||||
l.Attributes = l.Attributes[:limit]
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
s.links.add(l)
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
// DroppedAttributes returns the number of attributes dropped by the span
|
||||
// due to limits being reached.
|
||||
func (s *recordingSpan) DroppedAttributes() int {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.droppedAttributes
|
||||
}
|
||||
|
||||
// DroppedLinks returns the number of links dropped by the span due to limits
|
||||
// being reached.
|
||||
func (s *recordingSpan) DroppedLinks() int {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.links.droppedCount
|
||||
}
|
||||
|
||||
// DroppedEvents returns the number of events dropped by the span due to
|
||||
// limits being reached.
|
||||
func (s *recordingSpan) DroppedEvents() int {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.events.droppedCount
|
||||
}
|
||||
|
||||
// ChildSpanCount returns the count of spans that consider the span a
|
||||
// direct parent.
|
||||
func (s *recordingSpan) ChildSpanCount() int {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.childSpanCount
|
||||
}
|
||||
|
||||
// TracerProvider returns a trace.TracerProvider that can be used to generate
|
||||
// additional Spans on the same telemetry pipeline as the current Span.
|
||||
func (s *recordingSpan) TracerProvider() trace.TracerProvider {
|
||||
return s.tracer.provider
|
||||
}
|
||||
|
||||
// snapshot creates a read-only copy of the current state of the span.
|
||||
func (s *recordingSpan) snapshot() ReadOnlySpan {
|
||||
var sd snapshot
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
sd.endTime = s.endTime
|
||||
sd.instrumentationLibrary = s.tracer.instrumentationLibrary
|
||||
sd.name = s.name
|
||||
sd.parent = s.parent
|
||||
sd.resource = s.tracer.provider.resource
|
||||
sd.spanContext = s.spanContext
|
||||
sd.spanKind = s.spanKind
|
||||
sd.startTime = s.startTime
|
||||
sd.status = s.status
|
||||
sd.childSpanCount = s.childSpanCount
|
||||
|
||||
if len(s.attributes) > 0 {
|
||||
s.dedupeAttrs()
|
||||
sd.attributes = s.attributes
|
||||
}
|
||||
sd.droppedAttributeCount = s.droppedAttributes
|
||||
if len(s.events.queue) > 0 {
|
||||
sd.events = s.interfaceArrayToEventArray()
|
||||
sd.droppedEventCount = s.events.droppedCount
|
||||
}
|
||||
if len(s.links.queue) > 0 {
|
||||
sd.links = s.interfaceArrayToLinksArray()
|
||||
sd.droppedLinkCount = s.links.droppedCount
|
||||
}
|
||||
return &sd
|
||||
}
|
||||
|
||||
func (s *recordingSpan) interfaceArrayToLinksArray() []Link {
|
||||
linkArr := make([]Link, 0)
|
||||
for _, value := range s.links.queue {
|
||||
linkArr = append(linkArr, value.(Link))
|
||||
}
|
||||
return linkArr
|
||||
}
|
||||
|
||||
func (s *recordingSpan) interfaceArrayToEventArray() []Event {
|
||||
eventArr := make([]Event, 0)
|
||||
for _, value := range s.events.queue {
|
||||
eventArr = append(eventArr, value.(Event))
|
||||
}
|
||||
return eventArr
|
||||
}
|
||||
|
||||
func (s *recordingSpan) addChild() {
|
||||
if !s.IsRecording() {
|
||||
return
|
||||
}
|
||||
s.mu.Lock()
|
||||
s.childSpanCount++
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (*recordingSpan) private() {}
|
||||
|
||||
// runtimeTrace starts a "runtime/trace".Task for the span and returns a
|
||||
// context containing the task.
|
||||
func (s *recordingSpan) runtimeTrace(ctx context.Context) context.Context {
|
||||
if !rt.IsEnabled() {
|
||||
// Avoid additional overhead if runtime/trace is not enabled.
|
||||
return ctx
|
||||
}
|
||||
nctx, task := rt.NewTask(ctx, s.name)
|
||||
|
||||
s.mu.Lock()
|
||||
s.executionTracerTaskEnd = task.End
|
||||
s.mu.Unlock()
|
||||
|
||||
return nctx
|
||||
}
|
||||
|
||||
// nonRecordingSpan is a minimal implementation of the OpenTelemetry Span API
|
||||
// that wraps a SpanContext. It performs no operations other than to return
|
||||
// the wrapped SpanContext or TracerProvider that created it.
|
||||
type nonRecordingSpan struct {
|
||||
// tracer is the SDK tracer that created this span.
|
||||
tracer *tracer
|
||||
sc trace.SpanContext
|
||||
}
|
||||
|
||||
var _ trace.Span = nonRecordingSpan{}
|
||||
|
||||
// SpanContext returns the wrapped SpanContext.
|
||||
func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
|
||||
|
||||
// IsRecording always returns false.
|
||||
func (nonRecordingSpan) IsRecording() bool { return false }
|
||||
|
||||
// SetStatus does nothing.
|
||||
func (nonRecordingSpan) SetStatus(codes.Code, string) {}
|
||||
|
||||
// SetError does nothing.
|
||||
func (nonRecordingSpan) SetError(bool) {}
|
||||
|
||||
// SetAttributes does nothing.
|
||||
func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
|
||||
|
||||
// End does nothing.
|
||||
func (nonRecordingSpan) End(...trace.SpanEndOption) {}
|
||||
|
||||
// RecordError does nothing.
|
||||
func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
|
||||
|
||||
// AddEvent does nothing.
|
||||
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
|
||||
|
||||
// SetName does nothing.
|
||||
func (nonRecordingSpan) SetName(string) {}
|
||||
|
||||
// TracerProvider returns the trace.TracerProvider that provided the Tracer
|
||||
// that created this span.
|
||||
func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
|
||||
|
||||
func isRecording(s SamplingResult) bool {
|
||||
return s.Decision == RecordOnly || s.Decision == RecordAndSample
|
||||
}
|
||||
|
||||
func isSampled(s SamplingResult) bool {
|
||||
return s.Decision == RecordAndSample
|
||||
}
|
||||
|
||||
// Status is the classified state of a Span.
|
||||
type Status struct {
|
||||
// Code is an identifier of a Spans state classification.
|
||||
Code codes.Code
|
||||
// Description is a user hint about why that status was set. It is only
|
||||
// applicable when Code is Error.
|
||||
Description string
|
||||
}
|
47
vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go
generated
vendored
Normal file
47
vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import "context"
|
||||
|
||||
// SpanExporter handles the delivery of spans to external receivers. This is
|
||||
// the final component in the trace export pipeline.
|
||||
type SpanExporter interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// ExportSpans exports a batch of spans.
|
||||
//
|
||||
// This function is called synchronously, so there is no concurrency
|
||||
// safety requirement. However, due to the synchronous calling pattern,
|
||||
// it is critical that all timeouts and cancellations contained in the
|
||||
// passed context must be honored.
|
||||
//
|
||||
// Any retry logic must be contained in this function. The SDK that
|
||||
// calls this function will not implement any retry logic. All errors
|
||||
// returned by this function are considered unrecoverable and will be
|
||||
// reported to a configured error Handler.
|
||||
ExportSpans(ctx context.Context, spans []ReadOnlySpan) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Shutdown notifies the exporter of a pending halt to operations. The
|
||||
// exporter is expected to preform any cleanup or synchronization it
|
||||
// requires while honoring all timeouts and cancellations contained in
|
||||
// the passed context.
|
||||
Shutdown(ctx context.Context) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
126
vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go
generated
vendored
Normal file
126
vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import "go.opentelemetry.io/otel/sdk/internal/env"
|
||||
|
||||
const (
|
||||
// DefaultAttributeValueLengthLimit is the default maximum allowed
|
||||
// attribute value length, unlimited.
|
||||
DefaultAttributeValueLengthLimit = -1
|
||||
|
||||
// DefaultAttributeCountLimit is the default maximum number of attributes
|
||||
// a span can have.
|
||||
DefaultAttributeCountLimit = 128
|
||||
|
||||
// DefaultEventCountLimit is the default maximum number of events a span
|
||||
// can have.
|
||||
DefaultEventCountLimit = 128
|
||||
|
||||
// DefaultLinkCountLimit is the default maximum number of links a span can
|
||||
// have.
|
||||
DefaultLinkCountLimit = 128
|
||||
|
||||
// DefaultAttributePerEventCountLimit is the default maximum number of
|
||||
// attributes a span event can have.
|
||||
DefaultAttributePerEventCountLimit = 128
|
||||
|
||||
// DefaultAttributePerLinkCountLimit is the default maximum number of
|
||||
// attributes a span link can have.
|
||||
DefaultAttributePerLinkCountLimit = 128
|
||||
)
|
||||
|
||||
// SpanLimits represents the limits of a span.
|
||||
type SpanLimits struct {
|
||||
// AttributeValueLengthLimit is the maximum allowed attribute value length.
|
||||
//
|
||||
// This limit only applies to string and string slice attribute values.
|
||||
// Any string longer than this value will be truncated to this length.
|
||||
//
|
||||
// Setting this to a negative value means no limit is applied.
|
||||
AttributeValueLengthLimit int
|
||||
|
||||
// AttributeCountLimit is the maximum allowed span attribute count. Any
|
||||
// attribute added to a span once this limit is reached will be dropped.
|
||||
//
|
||||
// Setting this to zero means no attributes will be recorded.
|
||||
//
|
||||
// Setting this to a negative value means no limit is applied.
|
||||
AttributeCountLimit int
|
||||
|
||||
// EventCountLimit is the maximum allowed span event count. Any event
|
||||
// added to a span once this limit is reached means it will be added but
|
||||
// the oldest event will be dropped.
|
||||
//
|
||||
// Setting this to zero means no events we be recorded.
|
||||
//
|
||||
// Setting this to a negative value means no limit is applied.
|
||||
EventCountLimit int
|
||||
|
||||
// LinkCountLimit is the maximum allowed span link count. Any link added
|
||||
// to a span once this limit is reached means it will be added but the
|
||||
// oldest link will be dropped.
|
||||
//
|
||||
// Setting this to zero means no links we be recorded.
|
||||
//
|
||||
// Setting this to a negative value means no limit is applied.
|
||||
LinkCountLimit int
|
||||
|
||||
// AttributePerEventCountLimit is the maximum number of attributes allowed
|
||||
// per span event. Any attribute added after this limit reached will be
|
||||
// dropped.
|
||||
//
|
||||
// Setting this to zero means no attributes will be recorded for events.
|
||||
//
|
||||
// Setting this to a negative value means no limit is applied.
|
||||
AttributePerEventCountLimit int
|
||||
|
||||
// AttributePerLinkCountLimit is the maximum number of attributes allowed
|
||||
// per span link. Any attribute added after this limit reached will be
|
||||
// dropped.
|
||||
//
|
||||
// Setting this to zero means no attributes will be recorded for links.
|
||||
//
|
||||
// Setting this to a negative value means no limit is applied.
|
||||
AttributePerLinkCountLimit int
|
||||
}
|
||||
|
||||
// NewSpanLimits returns a SpanLimits with all limits set to the value their
|
||||
// corresponding environment variable holds, or the default if unset.
|
||||
//
|
||||
// • AttributeValueLengthLimit: OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT
|
||||
// (default: unlimited)
|
||||
//
|
||||
// • AttributeCountLimit: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT (default: 128)
|
||||
//
|
||||
// • EventCountLimit: OTEL_SPAN_EVENT_COUNT_LIMIT (default: 128)
|
||||
//
|
||||
// • AttributePerEventCountLimit: OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT (default:
|
||||
// 128)
|
||||
//
|
||||
// • LinkCountLimit: OTEL_SPAN_LINK_COUNT_LIMIT (default: 128)
|
||||
//
|
||||
// • AttributePerLinkCountLimit: OTEL_LINK_ATTRIBUTE_COUNT_LIMIT (default:
|
||||
// 128)
|
||||
func NewSpanLimits() SpanLimits {
|
||||
return SpanLimits{
|
||||
AttributeValueLengthLimit: env.SpanAttributeValueLength(DefaultAttributeValueLengthLimit),
|
||||
AttributeCountLimit: env.SpanAttributeCount(DefaultAttributeCountLimit),
|
||||
EventCountLimit: env.SpanEventCount(DefaultEventCountLimit),
|
||||
LinkCountLimit: env.SpanLinkCount(DefaultLinkCountLimit),
|
||||
AttributePerEventCountLimit: env.SpanEventAttributeCount(DefaultAttributePerEventCountLimit),
|
||||
AttributePerLinkCountLimit: env.SpanLinkAttributeCount(DefaultAttributePerLinkCountLimit),
|
||||
}
|
||||
}
|
67
vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go
generated
vendored
Normal file
67
vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// SpanProcessor is a processing pipeline for spans in the trace signal.
|
||||
// SpanProcessors registered with a TracerProvider and are called at the start
|
||||
// and end of a Span's lifecycle, and are called in the order they are
|
||||
// registered.
|
||||
type SpanProcessor interface {
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// OnStart is called when a span is started. It is called synchronously
|
||||
// and should not block.
|
||||
OnStart(parent context.Context, s ReadWriteSpan)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// OnEnd is called when span is finished. It is called synchronously and
|
||||
// hence not block.
|
||||
OnEnd(s ReadOnlySpan)
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// Shutdown is called when the SDK shuts down. Any cleanup or release of
|
||||
// resources held by the processor should be done in this call.
|
||||
//
|
||||
// Calls to OnStart, OnEnd, or ForceFlush after this has been called
|
||||
// should be ignored.
|
||||
//
|
||||
// All timeouts and cancellations contained in ctx must be honored, this
|
||||
// should not block indefinitely.
|
||||
Shutdown(ctx context.Context) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
|
||||
// ForceFlush exports all ended spans to the configured Exporter that have not yet
|
||||
// been exported. It should only be called when absolutely necessary, such as when
|
||||
// using a FaaS provider that may suspend the process after an invocation, but before
|
||||
// the Processor can export the completed spans.
|
||||
ForceFlush(ctx context.Context) error
|
||||
// DO NOT CHANGE: any modification will not be backwards compatible and
|
||||
// must never be done outside of a new major release.
|
||||
}
|
||||
|
||||
type spanProcessorState struct {
|
||||
sp SpanProcessor
|
||||
state *sync.Once
|
||||
}
|
||||
type spanProcessorStates []*spanProcessorState
|
156
vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go
generated
vendored
Normal file
156
vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// 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/sdk/trace"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type tracer struct {
|
||||
provider *TracerProvider
|
||||
instrumentationLibrary instrumentation.Library
|
||||
}
|
||||
|
||||
var _ trace.Tracer = &tracer{}
|
||||
|
||||
// Start starts a Span and returns it along with a context containing it.
|
||||
//
|
||||
// The Span is created with the provided name and as a child of any existing
|
||||
// span context found in the passed context. The created Span will be
|
||||
// configured appropriately by any SpanOption passed.
|
||||
func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) {
|
||||
config := trace.NewSpanStartConfig(options...)
|
||||
|
||||
// For local spans created by this SDK, track child span count.
|
||||
if p := trace.SpanFromContext(ctx); p != nil {
|
||||
if sdkSpan, ok := p.(*recordingSpan); ok {
|
||||
sdkSpan.addChild()
|
||||
}
|
||||
}
|
||||
|
||||
s := tr.newSpan(ctx, name, &config)
|
||||
if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() {
|
||||
sps, _ := tr.provider.spanProcessors.Load().(spanProcessorStates)
|
||||
for _, sp := range sps {
|
||||
sp.sp.OnStart(ctx, rw)
|
||||
}
|
||||
}
|
||||
if rtt, ok := s.(runtimeTracer); ok {
|
||||
ctx = rtt.runtimeTrace(ctx)
|
||||
}
|
||||
|
||||
return trace.ContextWithSpan(ctx, s), s
|
||||
}
|
||||
|
||||
type runtimeTracer interface {
|
||||
// runtimeTrace starts a "runtime/trace".Task for the span and
|
||||
// returns a context containing the task.
|
||||
runtimeTrace(ctx context.Context) context.Context
|
||||
}
|
||||
|
||||
// newSpan returns a new configured span.
|
||||
func (tr *tracer) newSpan(ctx context.Context, name string, config *trace.SpanConfig) trace.Span {
|
||||
// If told explicitly to make this a new root use a zero value SpanContext
|
||||
// as a parent which contains an invalid trace ID and is not remote.
|
||||
var psc trace.SpanContext
|
||||
if config.NewRoot() {
|
||||
ctx = trace.ContextWithSpanContext(ctx, psc)
|
||||
} else {
|
||||
psc = trace.SpanContextFromContext(ctx)
|
||||
}
|
||||
|
||||
// If there is a valid parent trace ID, use it to ensure the continuity of
|
||||
// the trace. Always generate a new span ID so other components can rely
|
||||
// on a unique span ID, even if the Span is non-recording.
|
||||
var tid trace.TraceID
|
||||
var sid trace.SpanID
|
||||
if !psc.TraceID().IsValid() {
|
||||
tid, sid = tr.provider.idGenerator.NewIDs(ctx)
|
||||
} else {
|
||||
tid = psc.TraceID()
|
||||
sid = tr.provider.idGenerator.NewSpanID(ctx, tid)
|
||||
}
|
||||
|
||||
samplingResult := tr.provider.sampler.ShouldSample(SamplingParameters{
|
||||
ParentContext: ctx,
|
||||
TraceID: tid,
|
||||
Name: name,
|
||||
Kind: config.SpanKind(),
|
||||
Attributes: config.Attributes(),
|
||||
Links: config.Links(),
|
||||
})
|
||||
|
||||
scc := trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceState: samplingResult.Tracestate,
|
||||
}
|
||||
if isSampled(samplingResult) {
|
||||
scc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled
|
||||
} else {
|
||||
scc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled
|
||||
}
|
||||
sc := trace.NewSpanContext(scc)
|
||||
|
||||
if !isRecording(samplingResult) {
|
||||
return tr.newNonRecordingSpan(sc)
|
||||
}
|
||||
return tr.newRecordingSpan(psc, sc, name, samplingResult, config)
|
||||
}
|
||||
|
||||
// newRecordingSpan returns a new configured recordingSpan.
|
||||
func (tr *tracer) newRecordingSpan(psc, sc trace.SpanContext, name string, sr SamplingResult, config *trace.SpanConfig) *recordingSpan {
|
||||
startTime := config.Timestamp()
|
||||
if startTime.IsZero() {
|
||||
startTime = time.Now()
|
||||
}
|
||||
|
||||
s := &recordingSpan{
|
||||
// Do not pre-allocate the attributes slice here! Doing so will
|
||||
// allocate memory that is likely never going to be used, or if used,
|
||||
// will be over-sized. The default Go compiler has been tested to
|
||||
// dynamically allocate needed space very well. Benchmarking has shown
|
||||
// it to be more performant than what we can predetermine here,
|
||||
// especially for the common use case of few to no added
|
||||
// attributes.
|
||||
|
||||
parent: psc,
|
||||
spanContext: sc,
|
||||
spanKind: trace.ValidateSpanKind(config.SpanKind()),
|
||||
name: name,
|
||||
startTime: startTime,
|
||||
events: newEvictedQueue(tr.provider.spanLimits.EventCountLimit),
|
||||
links: newEvictedQueue(tr.provider.spanLimits.LinkCountLimit),
|
||||
tracer: tr,
|
||||
}
|
||||
|
||||
for _, l := range config.Links() {
|
||||
s.addLink(l)
|
||||
}
|
||||
|
||||
s.SetAttributes(sr.Attributes...)
|
||||
s.SetAttributes(config.Attributes()...)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// newNonRecordingSpan returns a new configured nonRecordingSpan.
|
||||
func (tr *tracer) newNonRecordingSpan(sc trace.SpanContext) nonRecordingSpan {
|
||||
return nonRecordingSpan{tracer: tr, sc: sc}
|
||||
}
|
20
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/doc.go
generated
vendored
Normal file
20
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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 semconv implements OpenTelemetry semantic conventions.
|
||||
//
|
||||
// OpenTelemetry semantic conventions are agreed standardized naming
|
||||
// patterns for OpenTelemetry things. This package represents the conventions
|
||||
// as of the v1.7.0 version of the OpenTelemetry specification.
|
||||
package semconv // import "go.opentelemetry.io/otel/semconv/v1.7.0"
|
20
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/exception.go
generated
vendored
Normal file
20
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/exception.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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 semconv // import "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
|
||||
const (
|
||||
// ExceptionEventName is the name of the Span event representing an exception.
|
||||
ExceptionEventName = "exception"
|
||||
)
|
314
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/http.go
generated
vendored
Normal file
314
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/http.go
generated
vendored
Normal file
@@ -0,0 +1,314 @@
|
||||
// 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 semconv // import "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
var (
|
||||
HTTPSchemeHTTP = HTTPSchemeKey.String("http")
|
||||
HTTPSchemeHTTPS = HTTPSchemeKey.String("https")
|
||||
)
|
||||
|
||||
// NetAttributesFromHTTPRequest generates attributes of the net
|
||||
// namespace as specified by the OpenTelemetry specification for a
|
||||
// span. The network parameter is a string that net.Dial function
|
||||
// from standard library can understand.
|
||||
func NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue {
|
||||
attrs := []attribute.KeyValue{}
|
||||
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
attrs = append(attrs, NetTransportTCP)
|
||||
case "udp", "udp4", "udp6":
|
||||
attrs = append(attrs, NetTransportUDP)
|
||||
case "ip", "ip4", "ip6":
|
||||
attrs = append(attrs, NetTransportIP)
|
||||
case "unix", "unixgram", "unixpacket":
|
||||
attrs = append(attrs, NetTransportUnix)
|
||||
default:
|
||||
attrs = append(attrs, NetTransportOther)
|
||||
}
|
||||
|
||||
peerIP, peerName, peerPort := hostIPNamePort(request.RemoteAddr)
|
||||
if peerIP != "" {
|
||||
attrs = append(attrs, NetPeerIPKey.String(peerIP))
|
||||
}
|
||||
if peerName != "" {
|
||||
attrs = append(attrs, NetPeerNameKey.String(peerName))
|
||||
}
|
||||
if peerPort != 0 {
|
||||
attrs = append(attrs, NetPeerPortKey.Int(peerPort))
|
||||
}
|
||||
|
||||
hostIP, hostName, hostPort := "", "", 0
|
||||
for _, someHost := range []string{request.Host, request.Header.Get("Host"), request.URL.Host} {
|
||||
hostIP, hostName, hostPort = hostIPNamePort(someHost)
|
||||
if hostIP != "" || hostName != "" || hostPort != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if hostIP != "" {
|
||||
attrs = append(attrs, NetHostIPKey.String(hostIP))
|
||||
}
|
||||
if hostName != "" {
|
||||
attrs = append(attrs, NetHostNameKey.String(hostName))
|
||||
}
|
||||
if hostPort != 0 {
|
||||
attrs = append(attrs, NetHostPortKey.Int(hostPort))
|
||||
}
|
||||
|
||||
return attrs
|
||||
}
|
||||
|
||||
// hostIPNamePort extracts the IP address, name and (optional) port from hostWithPort.
|
||||
// It handles both IPv4 and IPv6 addresses. If the host portion is not recognized
|
||||
// as a valid IPv4 or IPv6 address, the `ip` result will be empty and the
|
||||
// host portion will instead be returned in `name`.
|
||||
func hostIPNamePort(hostWithPort string) (ip string, name string, port int) {
|
||||
var (
|
||||
hostPart, portPart string
|
||||
parsedPort uint64
|
||||
err error
|
||||
)
|
||||
if hostPart, portPart, err = net.SplitHostPort(hostWithPort); err != nil {
|
||||
hostPart, portPart = hostWithPort, ""
|
||||
}
|
||||
if parsedIP := net.ParseIP(hostPart); parsedIP != nil {
|
||||
ip = parsedIP.String()
|
||||
} else {
|
||||
name = hostPart
|
||||
}
|
||||
if parsedPort, err = strconv.ParseUint(portPart, 10, 16); err == nil {
|
||||
port = int(parsedPort)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EndUserAttributesFromHTTPRequest generates attributes of the
|
||||
// enduser namespace as specified by the OpenTelemetry specification
|
||||
// for a span.
|
||||
func EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
|
||||
if username, _, ok := request.BasicAuth(); ok {
|
||||
return []attribute.KeyValue{EnduserIDKey.String(username)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HTTPClientAttributesFromHTTPRequest generates attributes of the
|
||||
// http namespace as specified by the OpenTelemetry specification for
|
||||
// a span on the client side.
|
||||
func HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
|
||||
attrs := []attribute.KeyValue{}
|
||||
|
||||
if request.Method != "" {
|
||||
attrs = append(attrs, HTTPMethodKey.String(request.Method))
|
||||
} else {
|
||||
attrs = append(attrs, HTTPMethodKey.String(http.MethodGet))
|
||||
}
|
||||
|
||||
// remove any username/password info that may be in the URL
|
||||
// before adding it to the attributes
|
||||
userinfo := request.URL.User
|
||||
request.URL.User = nil
|
||||
|
||||
attrs = append(attrs, HTTPURLKey.String(request.URL.String()))
|
||||
|
||||
// restore any username/password info that was removed
|
||||
request.URL.User = userinfo
|
||||
|
||||
return append(attrs, httpCommonAttributesFromHTTPRequest(request)...)
|
||||
}
|
||||
|
||||
func httpCommonAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
|
||||
attrs := []attribute.KeyValue{}
|
||||
if ua := request.UserAgent(); ua != "" {
|
||||
attrs = append(attrs, HTTPUserAgentKey.String(ua))
|
||||
}
|
||||
if request.ContentLength > 0 {
|
||||
attrs = append(attrs, HTTPRequestContentLengthKey.Int64(request.ContentLength))
|
||||
}
|
||||
|
||||
return append(attrs, httpBasicAttributesFromHTTPRequest(request)...)
|
||||
}
|
||||
|
||||
func httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
|
||||
// as these attributes are used by HTTPServerMetricAttributesFromHTTPRequest, they should be low-cardinality
|
||||
attrs := []attribute.KeyValue{}
|
||||
|
||||
if request.TLS != nil {
|
||||
attrs = append(attrs, HTTPSchemeHTTPS)
|
||||
} else {
|
||||
attrs = append(attrs, HTTPSchemeHTTP)
|
||||
}
|
||||
|
||||
if request.Host != "" {
|
||||
attrs = append(attrs, HTTPHostKey.String(request.Host))
|
||||
} else if request.URL != nil && request.URL.Host != "" {
|
||||
attrs = append(attrs, HTTPHostKey.String(request.URL.Host))
|
||||
}
|
||||
|
||||
flavor := ""
|
||||
if request.ProtoMajor == 1 {
|
||||
flavor = fmt.Sprintf("1.%d", request.ProtoMinor)
|
||||
} else if request.ProtoMajor == 2 {
|
||||
flavor = "2"
|
||||
}
|
||||
if flavor != "" {
|
||||
attrs = append(attrs, HTTPFlavorKey.String(flavor))
|
||||
}
|
||||
|
||||
return attrs
|
||||
}
|
||||
|
||||
// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes
|
||||
// to be used with server-side HTTP metrics.
|
||||
func HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue {
|
||||
attrs := []attribute.KeyValue{}
|
||||
if serverName != "" {
|
||||
attrs = append(attrs, HTTPServerNameKey.String(serverName))
|
||||
}
|
||||
return append(attrs, httpBasicAttributesFromHTTPRequest(request)...)
|
||||
}
|
||||
|
||||
// HTTPServerAttributesFromHTTPRequest generates attributes of the
|
||||
// http namespace as specified by the OpenTelemetry specification for
|
||||
// a span on the server side. Currently, only basic authentication is
|
||||
// supported.
|
||||
func HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue {
|
||||
attrs := []attribute.KeyValue{
|
||||
HTTPMethodKey.String(request.Method),
|
||||
HTTPTargetKey.String(request.RequestURI),
|
||||
}
|
||||
|
||||
if serverName != "" {
|
||||
attrs = append(attrs, HTTPServerNameKey.String(serverName))
|
||||
}
|
||||
if route != "" {
|
||||
attrs = append(attrs, HTTPRouteKey.String(route))
|
||||
}
|
||||
if values, ok := request.Header["X-Forwarded-For"]; ok && len(values) > 0 {
|
||||
if addresses := strings.SplitN(values[0], ",", 2); len(addresses) > 0 {
|
||||
attrs = append(attrs, HTTPClientIPKey.String(addresses[0]))
|
||||
}
|
||||
}
|
||||
|
||||
return append(attrs, httpCommonAttributesFromHTTPRequest(request)...)
|
||||
}
|
||||
|
||||
// HTTPAttributesFromHTTPStatusCode generates attributes of the http
|
||||
// namespace as specified by the OpenTelemetry specification for a
|
||||
// span.
|
||||
func HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {
|
||||
attrs := []attribute.KeyValue{
|
||||
HTTPStatusCodeKey.Int(code),
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
type codeRange struct {
|
||||
fromInclusive int
|
||||
toInclusive int
|
||||
}
|
||||
|
||||
func (r codeRange) contains(code int) bool {
|
||||
return r.fromInclusive <= code && code <= r.toInclusive
|
||||
}
|
||||
|
||||
var validRangesPerCategory = map[int][]codeRange{
|
||||
1: {
|
||||
{http.StatusContinue, http.StatusEarlyHints},
|
||||
},
|
||||
2: {
|
||||
{http.StatusOK, http.StatusAlreadyReported},
|
||||
{http.StatusIMUsed, http.StatusIMUsed},
|
||||
},
|
||||
3: {
|
||||
{http.StatusMultipleChoices, http.StatusUseProxy},
|
||||
{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},
|
||||
},
|
||||
4: {
|
||||
{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…
|
||||
{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},
|
||||
{http.StatusPreconditionRequired, http.StatusTooManyRequests},
|
||||
{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},
|
||||
{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},
|
||||
},
|
||||
5: {
|
||||
{http.StatusInternalServerError, http.StatusLoopDetected},
|
||||
{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},
|
||||
},
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCode generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
func validateHTTPStatusCode(code int) (codes.Code, bool) {
|
||||
category := code / 100
|
||||
ranges, ok := validRangesPerCategory[category]
|
||||
if !ok {
|
||||
return codes.Error, false
|
||||
}
|
||||
ok = false
|
||||
for _, crange := range ranges {
|
||||
ok = crange.contains(code)
|
||||
if ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
return codes.Error, false
|
||||
}
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset, true
|
||||
}
|
||||
return codes.Error, true
|
||||
}
|
946
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/resource.go
generated
vendored
Normal file
946
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/resource.go
generated
vendored
Normal file
@@ -0,0 +1,946 @@
|
||||
// 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.
|
||||
|
||||
// Code generated from semantic convention specification. DO NOT EDIT.
|
||||
|
||||
package semconv // import "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
|
||||
import "go.opentelemetry.io/otel/attribute"
|
||||
|
||||
// A cloud environment (e.g. GCP, Azure, AWS)
|
||||
const (
|
||||
// Name of the cloud provider.
|
||||
//
|
||||
// Type: Enum
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
CloudProviderKey = attribute.Key("cloud.provider")
|
||||
// The cloud account ID the resource is assigned to.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '111111111111', 'opentelemetry'
|
||||
CloudAccountIDKey = attribute.Key("cloud.account.id")
|
||||
// The geographical region the resource is running. Refer to your provider's docs
|
||||
// to see the available regions, for example [Alibaba Cloud
|
||||
// regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS
|
||||
// regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/),
|
||||
// [Azure regions](https://azure.microsoft.com/en-us/global-
|
||||
// infrastructure/geographies/), or [Google Cloud
|
||||
// regions](https://cloud.google.com/about/locations).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'us-central1', 'us-east-1'
|
||||
CloudRegionKey = attribute.Key("cloud.region")
|
||||
// Cloud regions often have multiple, isolated locations known as zones to
|
||||
// increase availability. Availability zone represents the zone where the resource
|
||||
// is running.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'us-east-1c'
|
||||
// Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud.
|
||||
CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone")
|
||||
// The cloud platform in use.
|
||||
//
|
||||
// Type: Enum
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Note: The prefix of the service SHOULD match the one specified in
|
||||
// `cloud.provider`.
|
||||
CloudPlatformKey = attribute.Key("cloud.platform")
|
||||
)
|
||||
|
||||
var (
|
||||
// Alibaba Cloud
|
||||
CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud")
|
||||
// Amazon Web Services
|
||||
CloudProviderAWS = CloudProviderKey.String("aws")
|
||||
// Microsoft Azure
|
||||
CloudProviderAzure = CloudProviderKey.String("azure")
|
||||
// Google Cloud Platform
|
||||
CloudProviderGCP = CloudProviderKey.String("gcp")
|
||||
)
|
||||
|
||||
var (
|
||||
// Alibaba Cloud Elastic Compute Service
|
||||
CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs")
|
||||
// Alibaba Cloud Function Compute
|
||||
CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc")
|
||||
// AWS Elastic Compute Cloud
|
||||
CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2")
|
||||
// AWS Elastic Container Service
|
||||
CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs")
|
||||
// AWS Elastic Kubernetes Service
|
||||
CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks")
|
||||
// AWS Lambda
|
||||
CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda")
|
||||
// AWS Elastic Beanstalk
|
||||
CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk")
|
||||
// Azure Virtual Machines
|
||||
CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm")
|
||||
// Azure Container Instances
|
||||
CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure_container_instances")
|
||||
// Azure Kubernetes Service
|
||||
CloudPlatformAzureAKS = CloudPlatformKey.String("azure_aks")
|
||||
// Azure Functions
|
||||
CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions")
|
||||
// Azure App Service
|
||||
CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service")
|
||||
// Google Cloud Compute Engine (GCE)
|
||||
CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine")
|
||||
// Google Cloud Run
|
||||
CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run")
|
||||
// Google Cloud Kubernetes Engine (GKE)
|
||||
CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine")
|
||||
// Google Cloud Functions (GCF)
|
||||
CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions")
|
||||
// Google Cloud App Engine (GAE)
|
||||
CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine")
|
||||
)
|
||||
|
||||
// Resources used by AWS Elastic Container Service (ECS).
|
||||
const (
|
||||
// The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.
|
||||
// amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:ecs:us-
|
||||
// west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'
|
||||
AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn")
|
||||
// The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/develo
|
||||
// perguide/clusters.html).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
|
||||
AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
|
||||
// The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/l
|
||||
// aunch_types.html) for an ECS task.
|
||||
//
|
||||
// Type: Enum
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
|
||||
// The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates
|
||||
// t/developerguide/task_definitions.html).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:ecs:us-
|
||||
// west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'
|
||||
AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn")
|
||||
// The task definition family this task definition is a member of.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry-family'
|
||||
AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
|
||||
// The revision for this task definition.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '8', '26'
|
||||
AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
|
||||
)
|
||||
|
||||
var (
|
||||
// ec2
|
||||
AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2")
|
||||
// fargate
|
||||
AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate")
|
||||
)
|
||||
|
||||
// Resources used by AWS Elastic Kubernetes Service (EKS).
|
||||
const (
|
||||
// The ARN of an EKS cluster.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
|
||||
AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
|
||||
)
|
||||
|
||||
// Resources specific to Amazon Web Services.
|
||||
const (
|
||||
// The name(s) of the AWS log group(s) an application is writing to.
|
||||
//
|
||||
// Type: string[]
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '/aws/lambda/my-function', 'opentelemetry-service'
|
||||
// Note: Multiple log groups must be supported for cases like multi-container
|
||||
// applications, where a single application has sidecar containers, and each write
|
||||
// to their own log group.
|
||||
AWSLogGroupNamesKey = attribute.Key("aws.log.group.names")
|
||||
// The Amazon Resource Name(s) (ARN) of the AWS log group(s).
|
||||
//
|
||||
// Type: string[]
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'
|
||||
// Note: See the [log group ARN format
|
||||
// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-
|
||||
// access-control-overview-cwl.html#CWL_ARN_Format).
|
||||
AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns")
|
||||
// The name(s) of the AWS log stream(s) an application is writing to.
|
||||
//
|
||||
// Type: string[]
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
|
||||
AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
|
||||
// The ARN(s) of the AWS log stream(s).
|
||||
//
|
||||
// Type: string[]
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-
|
||||
// stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
|
||||
// Note: See the [log stream ARN format
|
||||
// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-
|
||||
// access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain
|
||||
// several log streams, so these ARNs necessarily identify both a log group and a
|
||||
// log stream.
|
||||
AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns")
|
||||
)
|
||||
|
||||
// A container instance.
|
||||
const (
|
||||
// Container name.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry-autoconf'
|
||||
ContainerNameKey = attribute.Key("container.name")
|
||||
// Container ID. Usually a UUID, as for example used to [identify Docker
|
||||
// containers](https://docs.docker.com/engine/reference/run/#container-
|
||||
// identification). The UUID might be abbreviated.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'a3bf90e006b2'
|
||||
ContainerIDKey = attribute.Key("container.id")
|
||||
// The container runtime managing this container.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'docker', 'containerd', 'rkt'
|
||||
ContainerRuntimeKey = attribute.Key("container.runtime")
|
||||
// Name of the image the container was built on.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'gcr.io/opentelemetry/operator'
|
||||
ContainerImageNameKey = attribute.Key("container.image.name")
|
||||
// Container image tag.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '0.1'
|
||||
ContainerImageTagKey = attribute.Key("container.image.tag")
|
||||
)
|
||||
|
||||
// The software deployment.
|
||||
const (
|
||||
// Name of the [deployment
|
||||
// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka
|
||||
// deployment tier).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'staging', 'production'
|
||||
DeploymentEnvironmentKey = attribute.Key("deployment.environment")
|
||||
)
|
||||
|
||||
// The device on which the process represented by this resource is running.
|
||||
const (
|
||||
// A unique identifier representing the device
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'
|
||||
// Note: The device identifier MUST only be defined using the values outlined
|
||||
// below. This value is not an advertising identifier and MUST NOT be used as
|
||||
// such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor id
|
||||
// entifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-iden
|
||||
// tifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the
|
||||
// Firebase Installation ID or a globally unique UUID which is persisted across
|
||||
// sessions in your application. More information can be found
|
||||
// [here](https://developer.android.com/training/articles/user-data-ids) on best
|
||||
// practices and exact implementation details. Caution should be taken when
|
||||
// storing personal data or anything which can identify a user. GDPR and data
|
||||
// protection laws may apply, ensure you do your own due diligence.
|
||||
DeviceIDKey = attribute.Key("device.id")
|
||||
// The model identifier for the device
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'iPhone3,4', 'SM-G920F'
|
||||
// Note: It's recommended this value represents a machine readable version of the
|
||||
// model identifier rather than the market or consumer-friendly name of the
|
||||
// device.
|
||||
DeviceModelIdentifierKey = attribute.Key("device.model.identifier")
|
||||
// The marketing name for the device model
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'
|
||||
// Note: It's recommended this value represents a human readable version of the
|
||||
// device model rather than a machine readable alternative.
|
||||
DeviceModelNameKey = attribute.Key("device.model.name")
|
||||
)
|
||||
|
||||
// A serverless instance.
|
||||
const (
|
||||
// The name of the single function that this runtime instance executes.
|
||||
//
|
||||
// Type: string
|
||||
// Required: Always
|
||||
// Stability: stable
|
||||
// Examples: 'my-function'
|
||||
// Note: This is the name of the function as configured/deployed on the FaaS
|
||||
// platform and is usually different from the name of the callback function (which
|
||||
// may be stored in the
|
||||
// [`code.namespace`/`code.function`](../../trace/semantic_conventions/span-
|
||||
// general.md#source-code-attributes) span attributes).
|
||||
FaaSNameKey = attribute.Key("faas.name")
|
||||
// The unique ID of the single function that this runtime instance executes.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'
|
||||
// Note: Depending on the cloud provider, use:
|
||||
|
||||
// * **AWS Lambda:** The function
|
||||
// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-
|
||||
// namespaces.html).
|
||||
// Take care not to use the "invoked ARN" directly but replace any
|
||||
// [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-
|
||||
// aliases.html) with the resolved function version, as the same runtime instance
|
||||
// may be invokable with multiple
|
||||
// different aliases.
|
||||
// * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-
|
||||
// resource-names)
|
||||
// * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-
|
||||
// us/rest/api/resources/resources/get-by-id).
|
||||
|
||||
// On some providers, it may not be possible to determine the full ID at startup,
|
||||
// which is why this field cannot be made required. For example, on AWS the
|
||||
// account ID
|
||||
// part of the ARN is not available without calling another AWS API
|
||||
// which may be deemed too slow for a short-running lambda function.
|
||||
// As an alternative, consider setting `faas.id` as a span attribute instead.
|
||||
FaaSIDKey = attribute.Key("faas.id")
|
||||
// The immutable version of the function being executed.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '26', 'pinkfroid-00002'
|
||||
// Note: Depending on the cloud provider and platform, use:
|
||||
|
||||
// * **AWS Lambda:** The [function
|
||||
// version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-
|
||||
// versions.html)
|
||||
// (an integer represented as a decimal string).
|
||||
// * **Google Cloud Run:** The
|
||||
// [revision](https://cloud.google.com/run/docs/managing/revisions)
|
||||
// (i.e., the function name plus the revision suffix).
|
||||
// * **Google Cloud Functions:** The value of the
|
||||
// [`K_REVISION` environment
|
||||
// variable](https://cloud.google.com/functions/docs/env-
|
||||
// var#runtime_environment_variables_set_automatically).
|
||||
// * **Azure Functions:** Not applicable. Do not set this attribute.
|
||||
FaaSVersionKey = attribute.Key("faas.version")
|
||||
// The execution environment ID as a string, that will be potentially reused for
|
||||
// other invocations to the same function/function version.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'
|
||||
// Note: * **AWS Lambda:** Use the (full) log stream name.
|
||||
FaaSInstanceKey = attribute.Key("faas.instance")
|
||||
// The amount of memory available to the serverless function in MiB.
|
||||
//
|
||||
// Type: int
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 128
|
||||
// Note: It's recommended to set this attribute since e.g. too little memory can
|
||||
// easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,
|
||||
// the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this
|
||||
// information.
|
||||
FaaSMaxMemoryKey = attribute.Key("faas.max_memory")
|
||||
)
|
||||
|
||||
// A host is defined as a general computing instance.
|
||||
const (
|
||||
// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud
|
||||
// provider.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry-test'
|
||||
HostIDKey = attribute.Key("host.id")
|
||||
// Name of the host. On Unix systems, it may contain what the hostname command
|
||||
// returns, or the fully qualified hostname, or another name specified by the
|
||||
// user.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry-test'
|
||||
HostNameKey = attribute.Key("host.name")
|
||||
// Type of host. For Cloud, this must be the machine type.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'n1-standard-1'
|
||||
HostTypeKey = attribute.Key("host.type")
|
||||
// The CPU architecture the host system is running on.
|
||||
//
|
||||
// Type: Enum
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
HostArchKey = attribute.Key("host.arch")
|
||||
// Name of the VM image or OS install the host was instantiated from.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'
|
||||
HostImageNameKey = attribute.Key("host.image.name")
|
||||
// VM image ID. For Cloud, this value is from the provider.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'ami-07b06b442921831e5'
|
||||
HostImageIDKey = attribute.Key("host.image.id")
|
||||
// The version string of the VM image as defined in [Version
|
||||
// Attributes](README.md#version-attributes).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '0.1'
|
||||
HostImageVersionKey = attribute.Key("host.image.version")
|
||||
)
|
||||
|
||||
var (
|
||||
// AMD64
|
||||
HostArchAMD64 = HostArchKey.String("amd64")
|
||||
// ARM32
|
||||
HostArchARM32 = HostArchKey.String("arm32")
|
||||
// ARM64
|
||||
HostArchARM64 = HostArchKey.String("arm64")
|
||||
// Itanium
|
||||
HostArchIA64 = HostArchKey.String("ia64")
|
||||
// 32-bit PowerPC
|
||||
HostArchPPC32 = HostArchKey.String("ppc32")
|
||||
// 64-bit PowerPC
|
||||
HostArchPPC64 = HostArchKey.String("ppc64")
|
||||
// 32-bit x86
|
||||
HostArchX86 = HostArchKey.String("x86")
|
||||
)
|
||||
|
||||
// A Kubernetes Cluster.
|
||||
const (
|
||||
// The name of the cluster.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry-cluster'
|
||||
K8SClusterNameKey = attribute.Key("k8s.cluster.name")
|
||||
)
|
||||
|
||||
// A Kubernetes Node object.
|
||||
const (
|
||||
// The name of the Node.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'node-1'
|
||||
K8SNodeNameKey = attribute.Key("k8s.node.name")
|
||||
// The UID of the Node.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'
|
||||
K8SNodeUIDKey = attribute.Key("k8s.node.uid")
|
||||
)
|
||||
|
||||
// A Kubernetes Namespace.
|
||||
const (
|
||||
// The name of the namespace that the pod is running in.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'default'
|
||||
K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
|
||||
)
|
||||
|
||||
// A Kubernetes Pod object.
|
||||
const (
|
||||
// The UID of the Pod.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SPodUIDKey = attribute.Key("k8s.pod.uid")
|
||||
// The name of the Pod.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry-pod-autoconf'
|
||||
K8SPodNameKey = attribute.Key("k8s.pod.name")
|
||||
)
|
||||
|
||||
// A container in a [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates).
|
||||
const (
|
||||
// The name of the Container in a Pod template.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'redis'
|
||||
K8SContainerNameKey = attribute.Key("k8s.container.name")
|
||||
)
|
||||
|
||||
// A Kubernetes ReplicaSet object.
|
||||
const (
|
||||
// The UID of the ReplicaSet.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid")
|
||||
// The name of the ReplicaSet.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name")
|
||||
)
|
||||
|
||||
// A Kubernetes Deployment object.
|
||||
const (
|
||||
// The UID of the Deployment.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
|
||||
// The name of the Deployment.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
|
||||
)
|
||||
|
||||
// A Kubernetes StatefulSet object.
|
||||
const (
|
||||
// The UID of the StatefulSet.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid")
|
||||
// The name of the StatefulSet.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name")
|
||||
)
|
||||
|
||||
// A Kubernetes DaemonSet object.
|
||||
const (
|
||||
// The UID of the DaemonSet.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid")
|
||||
// The name of the DaemonSet.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name")
|
||||
)
|
||||
|
||||
// A Kubernetes Job object.
|
||||
const (
|
||||
// The UID of the Job.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SJobUIDKey = attribute.Key("k8s.job.uid")
|
||||
// The name of the Job.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
K8SJobNameKey = attribute.Key("k8s.job.name")
|
||||
)
|
||||
|
||||
// A Kubernetes CronJob object.
|
||||
const (
|
||||
// The UID of the CronJob.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
|
||||
K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
|
||||
// The name of the CronJob.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
|
||||
)
|
||||
|
||||
// The operating system (OS) on which the process represented by this resource is running.
|
||||
const (
|
||||
// The operating system type.
|
||||
//
|
||||
// Type: Enum
|
||||
// Required: Always
|
||||
// Stability: stable
|
||||
OSTypeKey = attribute.Key("os.type")
|
||||
// Human readable (not intended to be parsed) OS version information, like e.g.
|
||||
// reported by `ver` or `lsb_release -a` commands.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'
|
||||
OSDescriptionKey = attribute.Key("os.description")
|
||||
// Human readable operating system name.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'iOS', 'Android', 'Ubuntu'
|
||||
OSNameKey = attribute.Key("os.name")
|
||||
// The version string of the operating system as defined in [Version
|
||||
// Attributes](../../resource/semantic_conventions/README.md#version-attributes).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '14.2.1', '18.04.1'
|
||||
OSVersionKey = attribute.Key("os.version")
|
||||
)
|
||||
|
||||
var (
|
||||
// Microsoft Windows
|
||||
OSTypeWindows = OSTypeKey.String("windows")
|
||||
// Linux
|
||||
OSTypeLinux = OSTypeKey.String("linux")
|
||||
// Apple Darwin
|
||||
OSTypeDarwin = OSTypeKey.String("darwin")
|
||||
// FreeBSD
|
||||
OSTypeFreeBSD = OSTypeKey.String("freebsd")
|
||||
// NetBSD
|
||||
OSTypeNetBSD = OSTypeKey.String("netbsd")
|
||||
// OpenBSD
|
||||
OSTypeOpenBSD = OSTypeKey.String("openbsd")
|
||||
// DragonFly BSD
|
||||
OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd")
|
||||
// HP-UX (Hewlett Packard Unix)
|
||||
OSTypeHPUX = OSTypeKey.String("hpux")
|
||||
// AIX (Advanced Interactive eXecutive)
|
||||
OSTypeAIX = OSTypeKey.String("aix")
|
||||
// Oracle Solaris
|
||||
OSTypeSolaris = OSTypeKey.String("solaris")
|
||||
// IBM z/OS
|
||||
OSTypeZOS = OSTypeKey.String("z_os")
|
||||
)
|
||||
|
||||
// An operating system process.
|
||||
const (
|
||||
// Process identifier (PID).
|
||||
//
|
||||
// Type: int
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 1234
|
||||
ProcessPIDKey = attribute.Key("process.pid")
|
||||
// The name of the process executable. On Linux based systems, can be set to the
|
||||
// `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of
|
||||
// `GetProcessImageFileNameW`.
|
||||
//
|
||||
// Type: string
|
||||
// Required: See below
|
||||
// Stability: stable
|
||||
// Examples: 'otelcol'
|
||||
ProcessExecutableNameKey = attribute.Key("process.executable.name")
|
||||
// The full path to the process executable. On Linux based systems, can be set to
|
||||
// the target of `proc/[pid]/exe`. On Windows, can be set to the result of
|
||||
// `GetProcessImageFileNameW`.
|
||||
//
|
||||
// Type: string
|
||||
// Required: See below
|
||||
// Stability: stable
|
||||
// Examples: '/usr/bin/cmd/otelcol'
|
||||
ProcessExecutablePathKey = attribute.Key("process.executable.path")
|
||||
// The command used to launch the process (i.e. the command name). On Linux based
|
||||
// systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows,
|
||||
// can be set to the first parameter extracted from `GetCommandLineW`.
|
||||
//
|
||||
// Type: string
|
||||
// Required: See below
|
||||
// Stability: stable
|
||||
// Examples: 'cmd/otelcol'
|
||||
ProcessCommandKey = attribute.Key("process.command")
|
||||
// The full command used to launch the process as a single string representing the
|
||||
// full command. On Windows, can be set to the result of `GetCommandLineW`. Do not
|
||||
// set this if you have to assemble it just for monitoring; use
|
||||
// `process.command_args` instead.
|
||||
//
|
||||
// Type: string
|
||||
// Required: See below
|
||||
// Stability: stable
|
||||
// Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"'
|
||||
ProcessCommandLineKey = attribute.Key("process.command_line")
|
||||
// All the command arguments (including the command/executable itself) as received
|
||||
// by the process. On Linux-based systems (and some other Unixoid systems
|
||||
// supporting procfs), can be set according to the list of null-delimited strings
|
||||
// extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be
|
||||
// the full argv vector passed to `main`.
|
||||
//
|
||||
// Type: string[]
|
||||
// Required: See below
|
||||
// Stability: stable
|
||||
// Examples: 'cmd/otecol', '--config=config.yaml'
|
||||
ProcessCommandArgsKey = attribute.Key("process.command_args")
|
||||
// The username of the user that owns the process.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'root'
|
||||
ProcessOwnerKey = attribute.Key("process.owner")
|
||||
)
|
||||
|
||||
// The single (language) runtime instance which is monitored.
|
||||
const (
|
||||
// The name of the runtime of this process. For compiled native binaries, this
|
||||
// SHOULD be the name of the compiler.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'OpenJDK Runtime Environment'
|
||||
ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
|
||||
// The version of the runtime of this process, as returned by the runtime without
|
||||
// modification.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '14.0.2'
|
||||
ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
|
||||
// An additional description about the runtime of the process, for example a
|
||||
// specific vendor customization of the runtime environment.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'
|
||||
ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
|
||||
)
|
||||
|
||||
// A service instance.
|
||||
const (
|
||||
// Logical name of the service.
|
||||
//
|
||||
// Type: string
|
||||
// Required: Always
|
||||
// Stability: stable
|
||||
// Examples: 'shoppingcart'
|
||||
// Note: MUST be the same for all instances of horizontally scaled services. If
|
||||
// the value was not specified, SDKs MUST fallback to `unknown_service:`
|
||||
// concatenated with [`process.executable.name`](process.md#process), e.g.
|
||||
// `unknown_service:bash`. If `process.executable.name` is not available, the
|
||||
// value MUST be set to `unknown_service`.
|
||||
ServiceNameKey = attribute.Key("service.name")
|
||||
// A namespace for `service.name`.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'Shop'
|
||||
// Note: A string value having a meaning that helps to distinguish a group of
|
||||
// services, for example the team name that owns a group of services.
|
||||
// `service.name` is expected to be unique within the same namespace. If
|
||||
// `service.namespace` is not specified in the Resource then `service.name` is
|
||||
// expected to be unique for all services that have no explicit namespace defined
|
||||
// (so the empty/unspecified namespace is simply one more valid namespace). Zero-
|
||||
// length namespace string is assumed equal to unspecified namespace.
|
||||
ServiceNamespaceKey = attribute.Key("service.namespace")
|
||||
// The string ID of the service instance.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '627cc493-f310-47de-96bd-71410b7dec09'
|
||||
// Note: MUST be unique for each instance of the same
|
||||
// `service.namespace,service.name` pair (in other words
|
||||
// `service.namespace,service.name,service.instance.id` triplet MUST be globally
|
||||
// unique). The ID helps to distinguish instances of the same service that exist
|
||||
// at the same time (e.g. instances of a horizontally scaled service). It is
|
||||
// preferable for the ID to be persistent and stay the same for the lifetime of
|
||||
// the service instance, however it is acceptable that the ID is ephemeral and
|
||||
// changes during important lifetime events for the service (e.g. service
|
||||
// restarts). If the service has no inherent unique ID that can be used as the
|
||||
// value of this attribute it is recommended to generate a random Version 1 or
|
||||
// Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use
|
||||
// Version 5, see RFC 4122 for more recommendations).
|
||||
ServiceInstanceIDKey = attribute.Key("service.instance.id")
|
||||
// The version string of the service API or implementation.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '2.0.0'
|
||||
ServiceVersionKey = attribute.Key("service.version")
|
||||
)
|
||||
|
||||
// The telemetry SDK used to capture data recorded by the instrumentation libraries.
|
||||
const (
|
||||
// The name of the telemetry SDK as defined above.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'opentelemetry'
|
||||
TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
|
||||
// The language of the telemetry SDK.
|
||||
//
|
||||
// Type: Enum
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
|
||||
// The version string of the telemetry SDK.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '1.2.3'
|
||||
TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
|
||||
// The version string of the auto instrumentation agent, if used.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '1.2.3'
|
||||
TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version")
|
||||
)
|
||||
|
||||
var (
|
||||
// cpp
|
||||
TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp")
|
||||
// dotnet
|
||||
TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet")
|
||||
// erlang
|
||||
TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang")
|
||||
// go
|
||||
TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go")
|
||||
// java
|
||||
TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java")
|
||||
// nodejs
|
||||
TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs")
|
||||
// php
|
||||
TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php")
|
||||
// python
|
||||
TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python")
|
||||
// ruby
|
||||
TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby")
|
||||
// webjs
|
||||
TelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String("webjs")
|
||||
)
|
||||
|
||||
// Resource describing the packaged software running the application code. Web engines are typically executed using process.runtime.
|
||||
const (
|
||||
// The name of the web engine.
|
||||
//
|
||||
// Type: string
|
||||
// Required: Always
|
||||
// Stability: stable
|
||||
// Examples: 'WildFly'
|
||||
WebEngineNameKey = attribute.Key("webengine.name")
|
||||
// The version of the web engine.
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: '21.0.0'
|
||||
WebEngineVersionKey = attribute.Key("webengine.version")
|
||||
// Additional description of the web engine (e.g. detailed version and edition
|
||||
// information).
|
||||
//
|
||||
// Type: string
|
||||
// Required: No
|
||||
// Stability: stable
|
||||
// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'
|
||||
WebEngineDescriptionKey = attribute.Key("webengine.description")
|
||||
)
|
20
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/schema.go
generated
vendored
Normal file
20
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/schema.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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 semconv // import "go.opentelemetry.io/otel/semconv/v1.7.0"
|
||||
|
||||
// SchemaURL is the schema URL that matches the version of the semantic conventions
|
||||
// that this package defines. Semconv packages starting from v1.4.0 must declare
|
||||
// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>
|
||||
const SchemaURL = "https://opentelemetry.io/schemas/1.7.0"
|
1558
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/trace.go
generated
vendored
Normal file
1558
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/trace.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
44
vendor/go.opentelemetry.io/otel/trace.go
generated
vendored
Normal file
44
vendor/go.opentelemetry.io/otel/trace.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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 otel // import "go.opentelemetry.io/otel"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Tracer creates a named tracer that implements Tracer interface.
|
||||
// If the name is an empty string then provider uses default name.
|
||||
//
|
||||
// This is short for GetTracerProvider().Tracer(name, opts...)
|
||||
func Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
|
||||
return GetTracerProvider().Tracer(name, opts...)
|
||||
}
|
||||
|
||||
// GetTracerProvider returns the registered global trace provider.
|
||||
// If none is registered then an instance of NoopTracerProvider is returned.
|
||||
//
|
||||
// Use the trace provider to create a named tracer. E.g.
|
||||
// tracer := otel.GetTracerProvider().Tracer("example.com/foo")
|
||||
// or
|
||||
// tracer := otel.Tracer("example.com/foo")
|
||||
func GetTracerProvider() trace.TracerProvider {
|
||||
return global.TracerProvider()
|
||||
}
|
||||
|
||||
// SetTracerProvider registers `tp` as the global trace provider.
|
||||
func SetTracerProvider(tp trace.TracerProvider) {
|
||||
global.SetTracerProvider(tp)
|
||||
}
|
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.
|
316
vendor/go.opentelemetry.io/otel/trace/config.go
generated
vendored
Normal file
316
vendor/go.opentelemetry.io/otel/trace/config.go
generated
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
// 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 {
|
||||
config = option.apply(config)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// TracerOption applies an option to a TracerConfig.
|
||||
type TracerOption interface {
|
||||
apply(TracerConfig) TracerConfig
|
||||
}
|
||||
|
||||
type tracerOptionFunc func(TracerConfig) TracerConfig
|
||||
|
||||
func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig {
|
||||
return 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 {
|
||||
c = 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 {
|
||||
c = 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) SpanConfig
|
||||
}
|
||||
|
||||
type spanOptionFunc func(SpanConfig) SpanConfig
|
||||
|
||||
func (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig {
|
||||
return fn(cfg)
|
||||
}
|
||||
|
||||
// SpanEndOption applies an option to a SpanConfig. These options are
|
||||
// applicable only when the span is ended.
|
||||
type SpanEndOption interface {
|
||||
applySpanEnd(SpanConfig) 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 {
|
||||
c = 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) 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) SpanConfig {
|
||||
c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
|
||||
return c
|
||||
}
|
||||
func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
func (o attributeOption) applyEvent(c EventConfig) EventConfig {
|
||||
c.attributes = append(c.attributes, []attribute.KeyValue(o)...)
|
||||
return c
|
||||
}
|
||||
|
||||
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) SpanConfig {
|
||||
c.timestamp = time.Time(o)
|
||||
return c
|
||||
}
|
||||
func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }
|
||||
func (o timestampOption) applyEvent(c EventConfig) EventConfig {
|
||||
c.timestamp = time.Time(o)
|
||||
return c
|
||||
}
|
||||
|
||||
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) EventConfig {
|
||||
c.stackTrace = bool(o)
|
||||
return c
|
||||
}
|
||||
func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
|
||||
c.stackTrace = bool(o)
|
||||
return c
|
||||
}
|
||||
func (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return 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) SpanConfig {
|
||||
cfg.links = append(cfg.links, links...)
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// 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) SpanConfig {
|
||||
cfg.newRoot = true
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanKind sets the SpanKind of a Span.
|
||||
func WithSpanKind(kind SpanKind) SpanStartOption {
|
||||
return spanOptionFunc(func(cfg SpanConfig) SpanConfig {
|
||||
cfg.spanKind = kind
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithInstrumentationVersion sets the instrumentation version.
|
||||
func WithInstrumentationVersion(version string) TracerOption {
|
||||
return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
|
||||
cfg.instrumentationVersion = version
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithSchemaURL sets the schema URL for the Tracer.
|
||||
func WithSchemaURL(schemaURL string) TracerOption {
|
||||
return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
|
||||
cfg.schemaURL = schemaURL
|
||||
return cfg
|
||||
})
|
||||
}
|
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()
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user