mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
vendor: update buildkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
@ -122,8 +122,7 @@ type streamEvent struct {
|
||||
}
|
||||
|
||||
const (
|
||||
closeEvent streamEventType = iota
|
||||
receiveEndEvent
|
||||
receiveEndEvent streamEventType = iota
|
||||
errorEvent
|
||||
)
|
||||
|
||||
@ -188,19 +187,12 @@ func (w *clientStream) CloseSend() error {
|
||||
|
||||
if err != nil {
|
||||
w.sendStreamEvent(errorEvent, err)
|
||||
} else {
|
||||
w.sendStreamEvent(closeEvent, nil)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
const (
|
||||
clientClosedState byte = 1 << iota
|
||||
receiveEndedState
|
||||
)
|
||||
|
||||
func wrapClientStream(s grpc.ClientStream, desc *grpc.StreamDesc) *clientStream {
|
||||
func wrapClientStream(ctx context.Context, s grpc.ClientStream, desc *grpc.StreamDesc) *clientStream {
|
||||
events := make(chan streamEvent)
|
||||
eventsDone := make(chan struct{})
|
||||
finished := make(chan error)
|
||||
@ -208,23 +200,20 @@ func wrapClientStream(s grpc.ClientStream, desc *grpc.StreamDesc) *clientStream
|
||||
go func() {
|
||||
defer close(eventsDone)
|
||||
|
||||
// Both streams have to be closed
|
||||
state := byte(0)
|
||||
|
||||
for event := range events {
|
||||
switch event.Type {
|
||||
case closeEvent:
|
||||
state |= clientClosedState
|
||||
case receiveEndEvent:
|
||||
state |= receiveEndedState
|
||||
case errorEvent:
|
||||
finished <- event.Err
|
||||
return
|
||||
}
|
||||
|
||||
if state == clientClosedState|receiveEndedState {
|
||||
finished <- nil
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
finished <- ctx.Err()
|
||||
return
|
||||
case event := <-events:
|
||||
switch event.Type {
|
||||
case receiveEndEvent:
|
||||
finished <- nil
|
||||
return
|
||||
case errorEvent:
|
||||
finished <- event.Err
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
@ -284,7 +273,7 @@ func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor {
|
||||
span.End()
|
||||
return s, err
|
||||
}
|
||||
stream := wrapClientStream(s, desc)
|
||||
stream := wrapClientStream(ctx, s, desc)
|
||||
|
||||
go func() {
|
||||
err := <-stream.finished
|
||||
|
201
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/LICENSE
generated
vendored
Normal file
201
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/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.
|
28
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/api.go
generated
vendored
Normal file
28
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/api.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 otelhttptrace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
)
|
||||
|
||||
// W3C client.
|
||||
func W3C(ctx context.Context, req *http.Request) (context.Context, *http.Request) {
|
||||
ctx = httptrace.WithClientTrace(ctx, NewClientTrace(ctx))
|
||||
req = req.WithContext(ctx)
|
||||
return ctx, req
|
||||
}
|
370
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go
generated
vendored
Normal file
370
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go
generated
vendored
Normal file
@ -0,0 +1,370 @@
|
||||
// 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 otelhttptrace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net/http/httptrace"
|
||||
"net/textproto"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/contrib"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP attributes.
|
||||
var (
|
||||
HTTPStatus = attribute.Key("http.status")
|
||||
HTTPHeaderMIME = attribute.Key("http.mime")
|
||||
HTTPRemoteAddr = attribute.Key("http.remote")
|
||||
HTTPLocalAddr = attribute.Key("http.local")
|
||||
HTTPConnectionReused = attribute.Key("http.conn.reused")
|
||||
HTTPConnectionWasIdle = attribute.Key("http.conn.wasidle")
|
||||
HTTPConnectionIdleTime = attribute.Key("http.conn.idletime")
|
||||
HTTPConnectionStartNetwork = attribute.Key("http.conn.start.network")
|
||||
HTTPConnectionDoneNetwork = attribute.Key("http.conn.done.network")
|
||||
HTTPConnectionDoneAddr = attribute.Key("http.conn.done.addr")
|
||||
HTTPDNSAddrs = attribute.Key("http.dns.addrs")
|
||||
)
|
||||
|
||||
var (
|
||||
hookMap = map[string]string{
|
||||
"http.dns": "http.getconn",
|
||||
"http.connect": "http.getconn",
|
||||
"http.tls": "http.getconn",
|
||||
}
|
||||
)
|
||||
|
||||
func parentHook(hook string) string {
|
||||
if strings.HasPrefix(hook, "http.connect") {
|
||||
return hookMap["http.connect"]
|
||||
}
|
||||
return hookMap[hook]
|
||||
}
|
||||
|
||||
// ClientTraceOption allows customizations to how the httptrace.Client
|
||||
// collects information.
|
||||
type ClientTraceOption func(*clientTracer)
|
||||
|
||||
// WithoutSubSpans will modify the httptrace.Client to only collect data
|
||||
// as Events and Attributes on a span found in the context. By default
|
||||
// sub-spans will be generated.
|
||||
func WithoutSubSpans() ClientTraceOption {
|
||||
return func(ct *clientTracer) {
|
||||
ct.useSpans = false
|
||||
}
|
||||
}
|
||||
|
||||
// WithRedactedHeaders will be replaced by fixed '****' values for the header
|
||||
// names provided. These are in addition to the sensitive headers already
|
||||
// redacted by default: Authorization, WWW-Authenticate, Proxy-Authenticate
|
||||
// Proxy-Authorization, Cookie, Set-Cookie
|
||||
func WithRedactedHeaders(headers ...string) ClientTraceOption {
|
||||
return func(ct *clientTracer) {
|
||||
for _, header := range headers {
|
||||
ct.redactedHeaders[strings.ToLower(header)] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithoutHeaders will disable adding span annotations for the http headers
|
||||
// and values.
|
||||
func WithoutHeaders() ClientTraceOption {
|
||||
return func(ct *clientTracer) {
|
||||
ct.addHeaders = false
|
||||
}
|
||||
}
|
||||
|
||||
type clientTracer struct {
|
||||
context.Context
|
||||
|
||||
tr trace.Tracer
|
||||
|
||||
activeHooks map[string]context.Context
|
||||
root trace.Span
|
||||
mtx sync.Mutex
|
||||
redactedHeaders map[string]struct{}
|
||||
addHeaders bool
|
||||
useSpans bool
|
||||
}
|
||||
|
||||
func NewClientTrace(ctx context.Context, opts ...ClientTraceOption) *httptrace.ClientTrace {
|
||||
ct := &clientTracer{
|
||||
Context: ctx,
|
||||
activeHooks: make(map[string]context.Context),
|
||||
redactedHeaders: map[string]struct{}{
|
||||
"authorization": {},
|
||||
"www-authenticate": {},
|
||||
"proxy-authenticate": {},
|
||||
"proxy-authorization": {},
|
||||
"cookie": {},
|
||||
"set-cookie": {},
|
||||
},
|
||||
addHeaders: true,
|
||||
useSpans: true,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(ct)
|
||||
}
|
||||
|
||||
var tp trace.TracerProvider
|
||||
if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
|
||||
tp = span.TracerProvider()
|
||||
} else {
|
||||
tp = otel.GetTracerProvider()
|
||||
}
|
||||
|
||||
ct.tr = tp.Tracer(
|
||||
"go.opentelemetry.io/otel/instrumentation/httptrace",
|
||||
trace.WithInstrumentationVersion(contrib.SemVersion()),
|
||||
)
|
||||
|
||||
return &httptrace.ClientTrace{
|
||||
GetConn: ct.getConn,
|
||||
GotConn: ct.gotConn,
|
||||
PutIdleConn: ct.putIdleConn,
|
||||
GotFirstResponseByte: ct.gotFirstResponseByte,
|
||||
Got100Continue: ct.got100Continue,
|
||||
Got1xxResponse: ct.got1xxResponse,
|
||||
DNSStart: ct.dnsStart,
|
||||
DNSDone: ct.dnsDone,
|
||||
ConnectStart: ct.connectStart,
|
||||
ConnectDone: ct.connectDone,
|
||||
TLSHandshakeStart: ct.tlsHandshakeStart,
|
||||
TLSHandshakeDone: ct.tlsHandshakeDone,
|
||||
WroteHeaderField: ct.wroteHeaderField,
|
||||
WroteHeaders: ct.wroteHeaders,
|
||||
Wait100Continue: ct.wait100Continue,
|
||||
WroteRequest: ct.wroteRequest,
|
||||
}
|
||||
}
|
||||
|
||||
func (ct *clientTracer) start(hook, spanName string, attrs ...attribute.KeyValue) {
|
||||
if !ct.useSpans {
|
||||
if ct.root == nil {
|
||||
ct.root = trace.SpanFromContext(ct.Context)
|
||||
}
|
||||
ct.root.AddEvent(hook+".start", trace.WithAttributes(attrs...))
|
||||
return
|
||||
}
|
||||
|
||||
ct.mtx.Lock()
|
||||
defer ct.mtx.Unlock()
|
||||
|
||||
if hookCtx, found := ct.activeHooks[hook]; !found {
|
||||
var sp trace.Span
|
||||
ct.activeHooks[hook], sp = ct.tr.Start(ct.getParentContext(hook), spanName, trace.WithAttributes(attrs...), trace.WithSpanKind(trace.SpanKindClient))
|
||||
if ct.root == nil {
|
||||
ct.root = sp
|
||||
}
|
||||
} else {
|
||||
// end was called before start finished, add the start attributes and end the span here
|
||||
span := trace.SpanFromContext(hookCtx)
|
||||
span.SetAttributes(attrs...)
|
||||
span.End()
|
||||
|
||||
delete(ct.activeHooks, hook)
|
||||
}
|
||||
}
|
||||
|
||||
func (ct *clientTracer) end(hook string, err error, attrs ...attribute.KeyValue) {
|
||||
if !ct.useSpans {
|
||||
if err != nil {
|
||||
attrs = append(attrs, attribute.String(hook+".error", err.Error()))
|
||||
}
|
||||
ct.root.AddEvent(hook+".done", trace.WithAttributes(attrs...))
|
||||
return
|
||||
}
|
||||
|
||||
ct.mtx.Lock()
|
||||
defer ct.mtx.Unlock()
|
||||
if ctx, ok := ct.activeHooks[hook]; ok {
|
||||
span := trace.SpanFromContext(ctx)
|
||||
if err != nil {
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
span.SetAttributes(attrs...)
|
||||
span.End()
|
||||
delete(ct.activeHooks, hook)
|
||||
} else {
|
||||
// start is not finished before end is called.
|
||||
// Start a span here with the ending attributes that will be finished when start finishes.
|
||||
// Yes, it's backwards. v0v
|
||||
ctx, span := ct.tr.Start(ct.getParentContext(hook), hook, trace.WithAttributes(attrs...), trace.WithSpanKind(trace.SpanKindClient))
|
||||
if err != nil {
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
ct.activeHooks[hook] = ctx
|
||||
}
|
||||
}
|
||||
|
||||
func (ct *clientTracer) getParentContext(hook string) context.Context {
|
||||
ctx, ok := ct.activeHooks[parentHook(hook)]
|
||||
if !ok {
|
||||
return ct.Context
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (ct *clientTracer) span(hook string) trace.Span {
|
||||
ct.mtx.Lock()
|
||||
defer ct.mtx.Unlock()
|
||||
if ctx, ok := ct.activeHooks[hook]; ok {
|
||||
return trace.SpanFromContext(ctx)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ct *clientTracer) getConn(host string) {
|
||||
ct.start("http.getconn", "http.getconn", semconv.HTTPHostKey.String(host))
|
||||
}
|
||||
|
||||
func (ct *clientTracer) gotConn(info httptrace.GotConnInfo) {
|
||||
attrs := []attribute.KeyValue{
|
||||
HTTPRemoteAddr.String(info.Conn.RemoteAddr().String()),
|
||||
HTTPLocalAddr.String(info.Conn.LocalAddr().String()),
|
||||
HTTPConnectionReused.Bool(info.Reused),
|
||||
HTTPConnectionWasIdle.Bool(info.WasIdle),
|
||||
}
|
||||
if info.WasIdle {
|
||||
attrs = append(attrs, HTTPConnectionIdleTime.String(info.IdleTime.String()))
|
||||
}
|
||||
ct.end("http.getconn", nil, attrs...)
|
||||
}
|
||||
|
||||
func (ct *clientTracer) putIdleConn(err error) {
|
||||
ct.end("http.receive", err)
|
||||
}
|
||||
|
||||
func (ct *clientTracer) gotFirstResponseByte() {
|
||||
ct.start("http.receive", "http.receive")
|
||||
}
|
||||
|
||||
func (ct *clientTracer) dnsStart(info httptrace.DNSStartInfo) {
|
||||
ct.start("http.dns", "http.dns", semconv.HTTPHostKey.String(info.Host))
|
||||
}
|
||||
|
||||
func (ct *clientTracer) dnsDone(info httptrace.DNSDoneInfo) {
|
||||
var addrs []string
|
||||
for _, netAddr := range info.Addrs {
|
||||
addrs = append(addrs, netAddr.String())
|
||||
}
|
||||
ct.end("http.dns", info.Err, HTTPDNSAddrs.String(sliceToString(addrs)))
|
||||
}
|
||||
|
||||
func (ct *clientTracer) connectStart(network, addr string) {
|
||||
ct.start("http.connect."+addr, "http.connect",
|
||||
HTTPRemoteAddr.String(addr),
|
||||
HTTPConnectionStartNetwork.String(network),
|
||||
)
|
||||
}
|
||||
|
||||
func (ct *clientTracer) connectDone(network, addr string, err error) {
|
||||
ct.end("http.connect."+addr, err,
|
||||
HTTPConnectionDoneAddr.String(addr),
|
||||
HTTPConnectionDoneNetwork.String(network),
|
||||
)
|
||||
}
|
||||
|
||||
func (ct *clientTracer) tlsHandshakeStart() {
|
||||
ct.start("http.tls", "http.tls")
|
||||
}
|
||||
|
||||
func (ct *clientTracer) tlsHandshakeDone(_ tls.ConnectionState, err error) {
|
||||
ct.end("http.tls", err)
|
||||
}
|
||||
|
||||
func (ct *clientTracer) wroteHeaderField(k string, v []string) {
|
||||
if ct.useSpans && ct.span("http.headers") == nil {
|
||||
ct.start("http.headers", "http.headers")
|
||||
}
|
||||
if !ct.addHeaders {
|
||||
return
|
||||
}
|
||||
k = strings.ToLower(k)
|
||||
value := sliceToString(v)
|
||||
if _, ok := ct.redactedHeaders[k]; ok {
|
||||
value = "****"
|
||||
}
|
||||
ct.root.SetAttributes(attribute.String("http."+k, value))
|
||||
}
|
||||
|
||||
func (ct *clientTracer) wroteHeaders() {
|
||||
if ct.useSpans && ct.span("http.headers") != nil {
|
||||
ct.end("http.headers", nil)
|
||||
}
|
||||
ct.start("http.send", "http.send")
|
||||
}
|
||||
|
||||
func (ct *clientTracer) wroteRequest(info httptrace.WroteRequestInfo) {
|
||||
if info.Err != nil {
|
||||
ct.root.SetStatus(codes.Error, info.Err.Error())
|
||||
}
|
||||
ct.end("http.send", info.Err)
|
||||
}
|
||||
|
||||
func (ct *clientTracer) got100Continue() {
|
||||
span := ct.root
|
||||
if ct.useSpans {
|
||||
span = ct.span("http.receive")
|
||||
}
|
||||
span.AddEvent("GOT 100 - Continue")
|
||||
}
|
||||
|
||||
func (ct *clientTracer) wait100Continue() {
|
||||
span := ct.root
|
||||
if ct.useSpans {
|
||||
span = ct.span("http.receive")
|
||||
}
|
||||
span.AddEvent("GOT 100 - Wait")
|
||||
}
|
||||
|
||||
func (ct *clientTracer) got1xxResponse(code int, header textproto.MIMEHeader) error {
|
||||
span := ct.root
|
||||
if ct.useSpans {
|
||||
span = ct.span("http.receive")
|
||||
}
|
||||
span.AddEvent("GOT 1xx", trace.WithAttributes(
|
||||
HTTPStatus.Int(code),
|
||||
HTTPHeaderMIME.String(sm2s(header)),
|
||||
))
|
||||
return nil
|
||||
}
|
||||
|
||||
func sliceToString(value []string) string {
|
||||
if len(value) == 0 {
|
||||
return "undefined"
|
||||
}
|
||||
return strings.Join(value, ",")
|
||||
}
|
||||
|
||||
func sm2s(value map[string][]string) string {
|
||||
var buf strings.Builder
|
||||
for k, v := range value {
|
||||
if buf.Len() != 0 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
buf.WriteString(k)
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(sliceToString(v))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
14
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/go.mod
generated
vendored
Normal file
14
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/go.mod
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
module go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace
|
||||
|
||||
go 1.15
|
||||
|
||||
replace go.opentelemetry.io/contrib => ../../../../..
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.6
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.opentelemetry.io/contrib v0.21.0
|
||||
go.opentelemetry.io/otel v1.0.0-RC1
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1
|
||||
)
|
21
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/go.sum
generated
vendored
Normal file
21
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/go.sum
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc=
|
||||
go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I=
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk=
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
68
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/httptrace.go
generated
vendored
Normal file
68
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/httptrace.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
// 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 otelhttptrace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/baggage"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Option is a function that allows configuration of the httptrace Extract()
|
||||
// and Inject() functions
|
||||
type Option func(*config)
|
||||
|
||||
type config struct {
|
||||
propagators propagation.TextMapPropagator
|
||||
}
|
||||
|
||||
func newConfig(opts []Option) *config {
|
||||
c := &config{propagators: otel.GetTextMapPropagator()}
|
||||
for _, o := range opts {
|
||||
o(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// WithPropagators sets the propagators to use for Extraction and Injection
|
||||
func WithPropagators(props propagation.TextMapPropagator) Option {
|
||||
return func(c *config) {
|
||||
c.propagators = props
|
||||
}
|
||||
}
|
||||
|
||||
// Extract returns the Attributes, Context Entries, and SpanContext that were encoded by Inject.
|
||||
func Extract(ctx context.Context, req *http.Request, opts ...Option) ([]attribute.KeyValue, baggage.Baggage, trace.SpanContext) {
|
||||
c := newConfig(opts)
|
||||
ctx = c.propagators.Extract(ctx, propagation.HeaderCarrier(req.Header))
|
||||
|
||||
attrs := append(
|
||||
semconv.HTTPServerAttributesFromHTTPRequest("", "", req),
|
||||
semconv.NetAttributesFromHTTPRequest("tcp", req)...,
|
||||
)
|
||||
|
||||
return attrs, baggage.FromContext(ctx), trace.SpanContextFromContext(ctx)
|
||||
}
|
||||
|
||||
func Inject(ctx context.Context, req *http.Request, opts ...Option) {
|
||||
c := newConfig(opts)
|
||||
c.propagators.Inject(ctx, propagation.HeaderCarrier(req.Header))
|
||||
}
|
201
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/LICENSE
generated
vendored
Normal file
201
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/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.
|
61
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go
generated
vendored
Normal file
61
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.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 otelhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DefaultClient is the default Client and is used by Get, Head, Post and PostForm.
|
||||
// Please be careful of intitialization order - for example, if you change
|
||||
// the global propagator, the DefaultClient might still be using the old one
|
||||
var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)}
|
||||
|
||||
// Get is a convenient replacement for http.Get that adds a span around the request.
|
||||
func Get(ctx context.Context, url string) (resp *http.Response, err error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return DefaultClient.Do(req)
|
||||
}
|
||||
|
||||
// Head is a convenient replacement for http.Head that adds a span around the request.
|
||||
func Head(ctx context.Context, url string) (resp *http.Response, err error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return DefaultClient.Do(req)
|
||||
}
|
||||
|
||||
// Post is a convenient replacement for http.Post that adds a span around the request.
|
||||
func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *http.Response, err error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
return DefaultClient.Do(req)
|
||||
}
|
||||
|
||||
// PostForm is a convenient replacement for http.PostForm that adds a span around the request.
|
||||
func PostForm(ctx context.Context, url string, data url.Values) (resp *http.Response, err error) {
|
||||
return Post(ctx, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||
}
|
47
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go
generated
vendored
Normal file
47
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.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 otelhttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/contrib"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Attribute keys that can be added to a span.
|
||||
const (
|
||||
ReadBytesKey = attribute.Key("http.read_bytes") // if anything was read from the request body, the total number of bytes read
|
||||
ReadErrorKey = attribute.Key("http.read_error") // If an error occurred while reading a request, the string of the error (io.EOF is not recorded)
|
||||
WroteBytesKey = attribute.Key("http.wrote_bytes") // if anything was written to the response writer, the total number of bytes written
|
||||
WriteErrorKey = attribute.Key("http.write_error") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded)
|
||||
)
|
||||
|
||||
// Server HTTP metrics
|
||||
const (
|
||||
RequestCount = "http.server.request_count" // Incoming request count total
|
||||
RequestContentLength = "http.server.request_content_length" // Incoming request bytes total
|
||||
ResponseContentLength = "http.server.response_content_length" // Incoming response bytes total
|
||||
ServerLatency = "http.server.duration" // Incoming end to end duration, microseconds
|
||||
)
|
||||
|
||||
// Filter is a predicate used to determine whether a given http.request should
|
||||
// be traced. A Filter must return true if the request should be traced.
|
||||
type Filter func(*http.Request) bool
|
||||
|
||||
func newTracer(tp trace.TracerProvider) trace.Tracer {
|
||||
return tp.Tracer(instrumentationName, trace.WithInstrumentationVersion(contrib.SemVersion()))
|
||||
}
|
181
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go
generated
vendored
Normal file
181
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
// 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 otelhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
|
||||
"go.opentelemetry.io/contrib"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/global"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
instrumentationName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
// config represents the configuration options available for the http.Handler
|
||||
// and http.Transport types.
|
||||
type config struct {
|
||||
Tracer trace.Tracer
|
||||
Meter metric.Meter
|
||||
Propagators propagation.TextMapPropagator
|
||||
SpanStartOptions []trace.SpanStartOption
|
||||
ReadEvent bool
|
||||
WriteEvent bool
|
||||
Filters []Filter
|
||||
SpanNameFormatter func(string, *http.Request) string
|
||||
ClientTrace func(context.Context) *httptrace.ClientTrace
|
||||
|
||||
TracerProvider trace.TracerProvider
|
||||
MeterProvider metric.MeterProvider
|
||||
}
|
||||
|
||||
// Option interface used for setting optional config properties.
|
||||
type Option interface {
|
||||
apply(*config)
|
||||
}
|
||||
|
||||
type optionFunc func(*config)
|
||||
|
||||
func (o optionFunc) apply(c *config) {
|
||||
o(c)
|
||||
}
|
||||
|
||||
// newConfig creates a new config struct and applies opts to it.
|
||||
func newConfig(opts ...Option) *config {
|
||||
c := &config{
|
||||
Propagators: otel.GetTextMapPropagator(),
|
||||
MeterProvider: global.GetMeterProvider(),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt.apply(c)
|
||||
}
|
||||
|
||||
// Tracer is only initialized if manually specified. Otherwise, can be passed with the tracing context.
|
||||
if c.TracerProvider != nil {
|
||||
c.Tracer = newTracer(c.TracerProvider)
|
||||
}
|
||||
c.Meter = c.MeterProvider.Meter(
|
||||
instrumentationName,
|
||||
metric.WithInstrumentationVersion(contrib.SemVersion()),
|
||||
)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// WithTracerProvider specifies a tracer provider to use for creating a tracer.
|
||||
// If none is specified, the global provider is used.
|
||||
func WithTracerProvider(provider trace.TracerProvider) Option {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.TracerProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
// WithMeterProvider specifies a meter provider to use for creating a meter.
|
||||
// If none is specified, the global provider is used.
|
||||
func WithMeterProvider(provider metric.MeterProvider) Option {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.MeterProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
// WithPublicEndpoint configures the Handler to link the span with an incoming
|
||||
// span context. If this option is not provided, then the association is a child
|
||||
// association instead of a link.
|
||||
func WithPublicEndpoint() Option {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanStartOptions = append(c.SpanStartOptions, trace.WithNewRoot())
|
||||
})
|
||||
}
|
||||
|
||||
// WithPropagators configures specific propagators. If this
|
||||
// option isn't specified then
|
||||
func WithPropagators(ps propagation.TextMapPropagator) Option {
|
||||
return optionFunc(func(c *config) {
|
||||
c.Propagators = ps
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanOptions configures an additional set of
|
||||
// trace.SpanOptions, which are applied to each new span.
|
||||
func WithSpanOptions(opts ...trace.SpanStartOption) Option {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanStartOptions = append(c.SpanStartOptions, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// WithFilter adds a filter to the list of filters used by the handler.
|
||||
// If any filter indicates to exclude a request then the request will not be
|
||||
// traced. All filters must allow a request to be traced for a Span to be created.
|
||||
// If no filters are provided then all requests are traced.
|
||||
// Filters will be invoked for each processed request, it is advised to make them
|
||||
// simple and fast.
|
||||
func WithFilter(f Filter) Option {
|
||||
return optionFunc(func(c *config) {
|
||||
c.Filters = append(c.Filters, f)
|
||||
})
|
||||
}
|
||||
|
||||
type event int
|
||||
|
||||
// Different types of events that can be recorded, see WithMessageEvents
|
||||
const (
|
||||
ReadEvents event = iota
|
||||
WriteEvents
|
||||
)
|
||||
|
||||
// WithMessageEvents configures the Handler to record the specified events
|
||||
// (span.AddEvent) on spans. By default only summary attributes are added at the
|
||||
// end of the request.
|
||||
//
|
||||
// Valid events are:
|
||||
// * ReadEvents: Record the number of bytes read after every http.Request.Body.Read
|
||||
// using the ReadBytesKey
|
||||
// * WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write
|
||||
// using the WriteBytesKey
|
||||
func WithMessageEvents(events ...event) Option {
|
||||
return optionFunc(func(c *config) {
|
||||
for _, e := range events {
|
||||
switch e {
|
||||
case ReadEvents:
|
||||
c.ReadEvent = true
|
||||
case WriteEvents:
|
||||
c.WriteEvent = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanNameFormatter takes a function that will be called on every
|
||||
// request and the returned string will become the Span Name
|
||||
func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanNameFormatter = f
|
||||
})
|
||||
}
|
||||
|
||||
// WithClientTrace takes a function that returns client trace instance that will be
|
||||
// applied to the requests sent through the otelhttp Transport.
|
||||
func WithClientTrace(f func(context.Context) *httptrace.ClientTrace) Option {
|
||||
return optionFunc(func(c *config) {
|
||||
c.ClientTrace = f
|
||||
})
|
||||
}
|
18
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go
generated
vendored
Normal file
18
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// 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 otelhttp provides an http.Handler and functions that are intended
|
||||
// to be used to add tracing by wrapping existing handlers (with Handler) and
|
||||
// routes WithRouteTag.
|
||||
package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
15
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/go.mod
generated
vendored
Normal file
15
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/go.mod
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
module go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
|
||||
|
||||
go 1.15
|
||||
|
||||
replace go.opentelemetry.io/contrib => ../../../..
|
||||
|
||||
require (
|
||||
github.com/felixge/httpsnoop v1.0.2
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.opentelemetry.io/contrib v0.21.0
|
||||
go.opentelemetry.io/otel v1.0.0-RC1
|
||||
go.opentelemetry.io/otel/metric v0.21.0
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1
|
||||
)
|
27
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/go.sum
generated
vendored
Normal file
27
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/go.sum
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
||||
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc=
|
||||
go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I=
|
||||
go.opentelemetry.io/otel/internal/metric v0.21.0 h1:gZlIBo5O51hZOOZz8vEcuRx/l5dnADadKfpT70AELoo=
|
||||
go.opentelemetry.io/otel/internal/metric v0.21.0/go.mod h1:iOfAaY2YycsXfYD4kaRSbLx2LKmfpKObWBEv9QK5zFo=
|
||||
go.opentelemetry.io/otel/metric v0.21.0 h1:ZtcJlHqVE4l8Su0WOLOd9fEPheJuYEiQ0wr9wv2p25I=
|
||||
go.opentelemetry.io/otel/metric v0.21.0/go.mod h1:JWCt1bjivC4iCrz/aCrM1GSw+ZcvY44KCbaeeRhzHnc=
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk=
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
235
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
generated
vendored
Normal file
235
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
generated
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
// 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 otelhttp
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/felixge/httpsnoop"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
var _ http.Handler = &Handler{}
|
||||
|
||||
// Handler is http middleware that corresponds to the http.Handler interface and
|
||||
// is designed to wrap a http.Mux (or equivalent), while individual routes on
|
||||
// the mux are wrapped with WithRouteTag. A Handler will add various attributes
|
||||
// to the span using the attribute.Keys defined in this package.
|
||||
type Handler struct {
|
||||
operation string
|
||||
handler http.Handler
|
||||
|
||||
tracer trace.Tracer
|
||||
meter metric.Meter
|
||||
propagators propagation.TextMapPropagator
|
||||
spanStartOptions []trace.SpanStartOption
|
||||
readEvent bool
|
||||
writeEvent bool
|
||||
filters []Filter
|
||||
spanNameFormatter func(string, *http.Request) string
|
||||
counters map[string]metric.Int64Counter
|
||||
valueRecorders map[string]metric.Int64ValueRecorder
|
||||
}
|
||||
|
||||
func defaultHandlerFormatter(operation string, _ *http.Request) string {
|
||||
return operation
|
||||
}
|
||||
|
||||
// NewHandler wraps the passed handler, functioning like middleware, in a span
|
||||
// named after the operation and with any provided Options.
|
||||
func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler {
|
||||
h := Handler{
|
||||
handler: handler,
|
||||
operation: operation,
|
||||
}
|
||||
|
||||
defaultOpts := []Option{
|
||||
WithSpanOptions(trace.WithSpanKind(trace.SpanKindServer)),
|
||||
WithSpanNameFormatter(defaultHandlerFormatter),
|
||||
}
|
||||
|
||||
c := newConfig(append(defaultOpts, opts...)...)
|
||||
h.configure(c)
|
||||
h.createMeasures()
|
||||
|
||||
return &h
|
||||
}
|
||||
|
||||
func (h *Handler) configure(c *config) {
|
||||
h.tracer = c.Tracer
|
||||
h.meter = c.Meter
|
||||
h.propagators = c.Propagators
|
||||
h.spanStartOptions = c.SpanStartOptions
|
||||
h.readEvent = c.ReadEvent
|
||||
h.writeEvent = c.WriteEvent
|
||||
h.filters = c.Filters
|
||||
h.spanNameFormatter = c.SpanNameFormatter
|
||||
}
|
||||
|
||||
func handleErr(err error) {
|
||||
if err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) createMeasures() {
|
||||
h.counters = make(map[string]metric.Int64Counter)
|
||||
h.valueRecorders = make(map[string]metric.Int64ValueRecorder)
|
||||
|
||||
requestBytesCounter, err := h.meter.NewInt64Counter(RequestContentLength)
|
||||
handleErr(err)
|
||||
|
||||
responseBytesCounter, err := h.meter.NewInt64Counter(ResponseContentLength)
|
||||
handleErr(err)
|
||||
|
||||
serverLatencyMeasure, err := h.meter.NewInt64ValueRecorder(ServerLatency)
|
||||
handleErr(err)
|
||||
|
||||
h.counters[RequestContentLength] = requestBytesCounter
|
||||
h.counters[ResponseContentLength] = responseBytesCounter
|
||||
h.valueRecorders[ServerLatency] = serverLatencyMeasure
|
||||
}
|
||||
|
||||
// ServeHTTP serves HTTP requests (http.Handler)
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
requestStartTime := time.Now()
|
||||
for _, f := range h.filters {
|
||||
if !f(r) {
|
||||
// Simply pass through to the handler if a filter rejects the request
|
||||
h.handler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
opts := append([]trace.SpanStartOption{
|
||||
trace.WithAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...),
|
||||
trace.WithAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...),
|
||||
trace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest(h.operation, "", r)...),
|
||||
}, h.spanStartOptions...) // start with the configured options
|
||||
|
||||
tracer := h.tracer
|
||||
|
||||
if tracer == nil {
|
||||
if span := trace.SpanFromContext(r.Context()); span.SpanContext().IsValid() {
|
||||
tracer = newTracer(span.TracerProvider())
|
||||
} else {
|
||||
tracer = newTracer(otel.GetTracerProvider())
|
||||
}
|
||||
}
|
||||
|
||||
ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
|
||||
ctx, span := tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...)
|
||||
defer span.End()
|
||||
|
||||
readRecordFunc := func(int64) {}
|
||||
if h.readEvent {
|
||||
readRecordFunc = func(n int64) {
|
||||
span.AddEvent("read", trace.WithAttributes(ReadBytesKey.Int64(n)))
|
||||
}
|
||||
}
|
||||
|
||||
var bw bodyWrapper
|
||||
// if request body is nil we don't want to mutate the body as it will affect
|
||||
// the identity of it in a unforeseeable way because we assert ReadCloser
|
||||
// fullfills a certain interface and it is indeed nil.
|
||||
if r.Body != nil {
|
||||
bw.ReadCloser = r.Body
|
||||
bw.record = readRecordFunc
|
||||
r.Body = &bw
|
||||
}
|
||||
|
||||
writeRecordFunc := func(int64) {}
|
||||
if h.writeEvent {
|
||||
writeRecordFunc = func(n int64) {
|
||||
span.AddEvent("write", trace.WithAttributes(WroteBytesKey.Int64(n)))
|
||||
}
|
||||
}
|
||||
|
||||
rww := &respWriterWrapper{ResponseWriter: w, record: writeRecordFunc, ctx: ctx, props: h.propagators}
|
||||
|
||||
// Wrap w to use our ResponseWriter methods while also exposing
|
||||
// other interfaces that w may implement (http.CloseNotifier,
|
||||
// http.Flusher, http.Hijacker, http.Pusher, io.ReaderFrom).
|
||||
|
||||
w = httpsnoop.Wrap(w, httpsnoop.Hooks{
|
||||
Header: func(httpsnoop.HeaderFunc) httpsnoop.HeaderFunc {
|
||||
return rww.Header
|
||||
},
|
||||
Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
|
||||
return rww.Write
|
||||
},
|
||||
WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
|
||||
return rww.WriteHeader
|
||||
},
|
||||
})
|
||||
|
||||
labeler := &Labeler{}
|
||||
ctx = injectLabeler(ctx, labeler)
|
||||
|
||||
h.handler.ServeHTTP(w, r.WithContext(ctx))
|
||||
|
||||
setAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err)
|
||||
|
||||
// Add metrics
|
||||
attributes := append(labeler.Get(), semconv.HTTPServerMetricAttributesFromHTTPRequest(h.operation, r)...)
|
||||
h.counters[RequestContentLength].Add(ctx, bw.read, attributes...)
|
||||
h.counters[ResponseContentLength].Add(ctx, rww.written, attributes...)
|
||||
|
||||
elapsedTime := time.Since(requestStartTime).Microseconds()
|
||||
|
||||
h.valueRecorders[ServerLatency].Record(ctx, elapsedTime, attributes...)
|
||||
}
|
||||
|
||||
func setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int, rerr, werr error) {
|
||||
attributes := []attribute.KeyValue{}
|
||||
|
||||
// TODO: Consider adding an event after each read and write, possibly as an
|
||||
// option (defaulting to off), so as to not create needlessly verbose spans.
|
||||
if read > 0 {
|
||||
attributes = append(attributes, ReadBytesKey.Int64(read))
|
||||
}
|
||||
if rerr != nil && rerr != io.EOF {
|
||||
attributes = append(attributes, ReadErrorKey.String(rerr.Error()))
|
||||
}
|
||||
if wrote > 0 {
|
||||
attributes = append(attributes, WroteBytesKey.Int64(wrote))
|
||||
}
|
||||
if statusCode > 0 {
|
||||
attributes = append(attributes, semconv.HTTPAttributesFromHTTPStatusCode(statusCode)...)
|
||||
span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(statusCode))
|
||||
}
|
||||
if werr != nil && werr != io.EOF {
|
||||
attributes = append(attributes, WriteErrorKey.String(werr.Error()))
|
||||
}
|
||||
span.SetAttributes(attributes...)
|
||||
}
|
||||
|
||||
// WithRouteTag annotates a span with the provided route name using the
|
||||
// RouteKey Tag.
|
||||
func WithRouteTag(route string, h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
span := trace.SpanFromContext(r.Context())
|
||||
span.SetAttributes(semconv.HTTPRouteKey.String(route))
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
65
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go
generated
vendored
Normal file
65
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
// 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 otelhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
// Labeler is used to allow instrumented HTTP handlers to add custom attributes to
|
||||
// the metrics recorded by the net/http instrumentation.
|
||||
type Labeler struct {
|
||||
mu sync.Mutex
|
||||
attributes []attribute.KeyValue
|
||||
}
|
||||
|
||||
// Add attributes to a Labeler.
|
||||
func (l *Labeler) Add(ls ...attribute.KeyValue) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.attributes = append(l.attributes, ls...)
|
||||
}
|
||||
|
||||
// Get returns a copy of the attributes added to the Labeler.
|
||||
func (l *Labeler) Get() []attribute.KeyValue {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
ret := make([]attribute.KeyValue, len(l.attributes))
|
||||
copy(ret, l.attributes)
|
||||
return ret
|
||||
}
|
||||
|
||||
type labelerContextKeyType int
|
||||
|
||||
const lablelerContextKey labelerContextKeyType = 0
|
||||
|
||||
func injectLabeler(ctx context.Context, l *Labeler) context.Context {
|
||||
return context.WithValue(ctx, lablelerContextKey, l)
|
||||
}
|
||||
|
||||
// LabelerFromContext retrieves a Labeler instance from the provided context if
|
||||
// one is available. If no Labeler was found in the provided context a new, empty
|
||||
// Labeler is returned and the second return value is false. In this case it is
|
||||
// safe to use the Labeler but any attributes added to it will not be used.
|
||||
func LabelerFromContext(ctx context.Context) (*Labeler, bool) {
|
||||
l, ok := ctx.Value(lablelerContextKey).(*Labeler)
|
||||
if !ok {
|
||||
l = &Labeler{}
|
||||
}
|
||||
return l, ok
|
||||
}
|
154
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
generated
vendored
Normal file
154
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.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.
|
||||
|
||||
package otelhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Transport implements the http.RoundTripper interface and wraps
|
||||
// outbound HTTP(S) requests with a span.
|
||||
type Transport struct {
|
||||
rt http.RoundTripper
|
||||
|
||||
tracer trace.Tracer
|
||||
propagators propagation.TextMapPropagator
|
||||
spanStartOptions []trace.SpanStartOption
|
||||
filters []Filter
|
||||
spanNameFormatter func(string, *http.Request) string
|
||||
clientTrace func(context.Context) *httptrace.ClientTrace
|
||||
}
|
||||
|
||||
var _ http.RoundTripper = &Transport{}
|
||||
|
||||
// NewTransport wraps the provided http.RoundTripper with one that
|
||||
// starts a span and injects the span context into the outbound request headers.
|
||||
//
|
||||
// If the provided http.RoundTripper is nil, http.DefaultTransport will be used
|
||||
// as the base http.RoundTripper
|
||||
func NewTransport(base http.RoundTripper, opts ...Option) *Transport {
|
||||
if base == nil {
|
||||
base = http.DefaultTransport
|
||||
}
|
||||
|
||||
t := Transport{
|
||||
rt: base,
|
||||
}
|
||||
|
||||
defaultOpts := []Option{
|
||||
WithSpanOptions(trace.WithSpanKind(trace.SpanKindClient)),
|
||||
WithSpanNameFormatter(defaultTransportFormatter),
|
||||
}
|
||||
|
||||
c := newConfig(append(defaultOpts, opts...)...)
|
||||
t.applyConfig(c)
|
||||
|
||||
return &t
|
||||
}
|
||||
|
||||
func (t *Transport) applyConfig(c *config) {
|
||||
t.tracer = c.Tracer
|
||||
t.propagators = c.Propagators
|
||||
t.spanStartOptions = c.SpanStartOptions
|
||||
t.filters = c.Filters
|
||||
t.spanNameFormatter = c.SpanNameFormatter
|
||||
t.clientTrace = c.ClientTrace
|
||||
}
|
||||
|
||||
func defaultTransportFormatter(_ string, r *http.Request) string {
|
||||
return "HTTP " + r.Method
|
||||
}
|
||||
|
||||
// RoundTrip creates a Span and propagates its context via the provided request's headers
|
||||
// before handing the request to the configured base RoundTripper. The created span will
|
||||
// end when the response body is closed or when a read from the body returns io.EOF.
|
||||
func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
for _, f := range t.filters {
|
||||
if !f(r) {
|
||||
// Simply pass through to the base RoundTripper if a filter rejects the request
|
||||
return t.rt.RoundTrip(r)
|
||||
}
|
||||
}
|
||||
|
||||
tracer := t.tracer
|
||||
|
||||
if tracer == nil {
|
||||
if span := trace.SpanFromContext(r.Context()); span.SpanContext().IsValid() {
|
||||
tracer = newTracer(span.TracerProvider())
|
||||
} else {
|
||||
tracer = newTracer(otel.GetTracerProvider())
|
||||
}
|
||||
}
|
||||
|
||||
opts := append([]trace.SpanStartOption{}, t.spanStartOptions...) // start with the configured options
|
||||
|
||||
ctx, span := tracer.Start(r.Context(), t.spanNameFormatter("", r), opts...)
|
||||
|
||||
if t.clientTrace != nil {
|
||||
ctx = httptrace.WithClientTrace(ctx, t.clientTrace(ctx))
|
||||
}
|
||||
|
||||
r = r.WithContext(ctx)
|
||||
span.SetAttributes(semconv.HTTPClientAttributesFromHTTPRequest(r)...)
|
||||
t.propagators.Inject(ctx, propagation.HeaderCarrier(r.Header))
|
||||
|
||||
res, err := t.rt.RoundTrip(r)
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.End()
|
||||
return res, err
|
||||
}
|
||||
|
||||
span.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(res.StatusCode)...)
|
||||
span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(res.StatusCode))
|
||||
res.Body = &wrappedBody{ctx: ctx, span: span, body: res.Body}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
type wrappedBody struct {
|
||||
ctx context.Context
|
||||
span trace.Span
|
||||
body io.ReadCloser
|
||||
}
|
||||
|
||||
var _ io.ReadCloser = &wrappedBody{}
|
||||
|
||||
func (wb *wrappedBody) Read(b []byte) (int, error) {
|
||||
n, err := wb.body.Read(b)
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
// nothing to do here but fall through to the return
|
||||
case io.EOF:
|
||||
wb.span.End()
|
||||
default:
|
||||
wb.span.RecordError(err)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (wb *wrappedBody) Close() error {
|
||||
wb.span.End()
|
||||
return wb.body.Close()
|
||||
}
|
96
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go
generated
vendored
Normal file
96
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
// 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 otelhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
)
|
||||
|
||||
var _ io.ReadCloser = &bodyWrapper{}
|
||||
|
||||
// bodyWrapper wraps a http.Request.Body (an io.ReadCloser) to track the number
|
||||
// of bytes read and the last error
|
||||
type bodyWrapper struct {
|
||||
io.ReadCloser
|
||||
record func(n int64) // must not be nil
|
||||
|
||||
read int64
|
||||
err error
|
||||
}
|
||||
|
||||
func (w *bodyWrapper) Read(b []byte) (int, error) {
|
||||
n, err := w.ReadCloser.Read(b)
|
||||
n1 := int64(n)
|
||||
w.read += n1
|
||||
w.err = err
|
||||
w.record(n1)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (w *bodyWrapper) Close() error {
|
||||
return w.ReadCloser.Close()
|
||||
}
|
||||
|
||||
var _ http.ResponseWriter = &respWriterWrapper{}
|
||||
|
||||
// respWriterWrapper wraps a http.ResponseWriter in order to track the number of
|
||||
// bytes written, the last error, and to catch the returned statusCode
|
||||
// TODO: The wrapped http.ResponseWriter doesn't implement any of the optional
|
||||
// types (http.Hijacker, http.Pusher, http.CloseNotifier, http.Flusher, etc)
|
||||
// that may be useful when using it in real life situations.
|
||||
type respWriterWrapper struct {
|
||||
http.ResponseWriter
|
||||
record func(n int64) // must not be nil
|
||||
|
||||
// used to inject the header
|
||||
ctx context.Context
|
||||
|
||||
props propagation.TextMapPropagator
|
||||
|
||||
written int64
|
||||
statusCode int
|
||||
err error
|
||||
wroteHeader bool
|
||||
}
|
||||
|
||||
func (w *respWriterWrapper) Header() http.Header {
|
||||
return w.ResponseWriter.Header()
|
||||
}
|
||||
|
||||
func (w *respWriterWrapper) Write(p []byte) (int, error) {
|
||||
if !w.wroteHeader {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
n, err := w.ResponseWriter.Write(p)
|
||||
n1 := int64(n)
|
||||
w.record(n1)
|
||||
w.written += n1
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (w *respWriterWrapper) WriteHeader(statusCode int) {
|
||||
if w.wroteHeader {
|
||||
return
|
||||
}
|
||||
w.wroteHeader = true
|
||||
w.statusCode = statusCode
|
||||
w.props.Inject(w.ctx, propagation.HeaderCarrier(w.Header()))
|
||||
w.ResponseWriter.WriteHeader(statusCode)
|
||||
}
|
Reference in New Issue
Block a user