mirror of
https://github.com/weaveworks/scope.git
synced 2026-08-18 03:46:45 +00:00
Update github.com/opentracing/opentracing-go
This commit is contained in:
+197
-17
@@ -1,21 +1,201 @@
|
||||
The MIT License (MIT)
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
Copyright (c) 2016 The OpenTracing Authors
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
1. Definitions.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"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 2016 The OpenTracing 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.
|
||||
|
||||
+55
-3
@@ -15,7 +15,7 @@ import opentracing "github.com/opentracing/opentracing-go"
|
||||
//
|
||||
var (
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SpanKind (client/server)
|
||||
// SpanKind (client/server or producer/consumer)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// SpanKind hints at relationship between spans, e.g. client/server
|
||||
@@ -31,6 +31,16 @@ var (
|
||||
SpanKindRPCServerEnum = SpanKindEnum("server")
|
||||
SpanKindRPCServer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCServerEnum}
|
||||
|
||||
// SpanKindProducer marks a span representing the producer-side of a
|
||||
// message bus
|
||||
SpanKindProducerEnum = SpanKindEnum("producer")
|
||||
SpanKindProducer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindProducerEnum}
|
||||
|
||||
// SpanKindConsumer marks a span representing the consumer-side of a
|
||||
// message bus
|
||||
SpanKindConsumerEnum = SpanKindEnum("consumer")
|
||||
SpanKindConsumer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindConsumerEnum}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Component name
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -52,14 +62,19 @@ var (
|
||||
// communications, like an RPC call.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// PeerService records the service name of the peer
|
||||
// PeerService records the service name of the peer.
|
||||
PeerService = stringTagName("peer.service")
|
||||
|
||||
// PeerAddress records the address name of the peer. This may be a "ip:port",
|
||||
// a bare "hostname", a FQDN or even a database DSN substring
|
||||
// like "mysql://username@127.0.0.1:3306/dbname"
|
||||
PeerAddress = stringTagName("peer.address")
|
||||
|
||||
// PeerHostname records the host name of the peer
|
||||
PeerHostname = stringTagName("peer.hostname")
|
||||
|
||||
// PeerHostIPv4 records IP v4 host address of the peer
|
||||
PeerHostIPv4 = uint32TagName("peer.ipv4")
|
||||
PeerHostIPv4 = ipv4Tag("peer.ipv4")
|
||||
|
||||
// PeerHostIPv6 records IP v6 host address of the peer
|
||||
PeerHostIPv6 = stringTagName("peer.ipv6")
|
||||
@@ -82,6 +97,31 @@ var (
|
||||
// HTTP response.
|
||||
HTTPStatusCode = uint16TagName("http.status_code")
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DB Tags
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// DBInstance is database instance name.
|
||||
DBInstance = stringTagName("db.instance")
|
||||
|
||||
// DBStatement is a database statement for the given database type.
|
||||
// It can be a query or a prepared statement (i.e., before substitution).
|
||||
DBStatement = stringTagName("db.statement")
|
||||
|
||||
// DBType is a database type. For any SQL database, "sql".
|
||||
// For others, the lower-case database category, e.g. "redis"
|
||||
DBType = stringTagName("db.type")
|
||||
|
||||
// DBUser is a username for accessing database.
|
||||
DBUser = stringTagName("db.user")
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Message Bus Tag
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// MessageBusDestination is an address at which messages can be exchanged
|
||||
MessageBusDestination = stringTagName("message_bus.destination")
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Error Tag
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -156,3 +196,15 @@ type boolTagName string
|
||||
func (tag boolTagName) Set(span opentracing.Span, value bool) {
|
||||
span.SetTag(string(tag), value)
|
||||
}
|
||||
|
||||
type ipv4Tag string
|
||||
|
||||
// Set adds IP v4 host address of the peer as an uint32 value to the `span`, keep this for backward and zipkin compatibility
|
||||
func (tag ipv4Tag) Set(span opentracing.Span, value uint32) {
|
||||
span.SetTag(string(tag), value)
|
||||
}
|
||||
|
||||
// SetString records IP v4 host address of the peer as a .-separated tuple to the `span`. E.g., "127.0.0.1"
|
||||
func (tag ipv4Tag) SetString(span opentracing.Span, value string) {
|
||||
span.SetTag(string(tag), value)
|
||||
}
|
||||
|
||||
+10
-5
@@ -4,18 +4,18 @@ var (
|
||||
globalTracer Tracer = NoopTracer{}
|
||||
)
|
||||
|
||||
// InitGlobalTracer sets the [singleton] opentracing.Tracer returned by
|
||||
// SetGlobalTracer sets the [singleton] opentracing.Tracer returned by
|
||||
// GlobalTracer(). Those who use GlobalTracer (rather than directly manage an
|
||||
// opentracing.Tracer instance) should call InitGlobalTracer as early as
|
||||
// opentracing.Tracer instance) should call SetGlobalTracer as early as
|
||||
// possible in main(), prior to calling the `StartSpan` global func below.
|
||||
// Prior to calling `InitGlobalTracer`, any Spans started via the `StartSpan`
|
||||
// Prior to calling `SetGlobalTracer`, any Spans started via the `StartSpan`
|
||||
// (etc) globals are noops.
|
||||
func InitGlobalTracer(tracer Tracer) {
|
||||
func SetGlobalTracer(tracer Tracer) {
|
||||
globalTracer = tracer
|
||||
}
|
||||
|
||||
// GlobalTracer returns the global singleton `Tracer` implementation.
|
||||
// Before `InitGlobalTracer()` is called, the `GlobalTracer()` is a noop
|
||||
// Before `SetGlobalTracer()` is called, the `GlobalTracer()` is a noop
|
||||
// implementation that drops all data handed to it.
|
||||
func GlobalTracer() Tracer {
|
||||
return globalTracer
|
||||
@@ -25,3 +25,8 @@ func GlobalTracer() Tracer {
|
||||
func StartSpan(operationName string, opts ...StartSpanOption) Span {
|
||||
return globalTracer.StartSpan(operationName, opts...)
|
||||
}
|
||||
|
||||
// InitGlobalTracer is deprecated. Please use SetGlobalTracer.
|
||||
func InitGlobalTracer(tracer Tracer) {
|
||||
SetGlobalTracer(tracer)
|
||||
}
|
||||
|
||||
+2
-5
@@ -1,6 +1,6 @@
|
||||
package opentracing
|
||||
|
||||
import "golang.org/x/net/context"
|
||||
import "context"
|
||||
|
||||
type contextKey struct{}
|
||||
|
||||
@@ -46,12 +46,9 @@ func StartSpanFromContext(ctx context.Context, operationName string, opts ...Sta
|
||||
|
||||
// startSpanFromContextWithTracer is factored out for testing purposes.
|
||||
func startSpanFromContextWithTracer(ctx context.Context, tracer Tracer, operationName string, opts ...StartSpanOption) (Span, context.Context) {
|
||||
var span Span
|
||||
if parentSpan := SpanFromContext(ctx); parentSpan != nil {
|
||||
opts = append(opts, ChildOf(parentSpan.Context()))
|
||||
span = tracer.StartSpan(operationName, opts...)
|
||||
} else {
|
||||
span = tracer.StartSpan(operationName, opts...)
|
||||
}
|
||||
span := tracer.StartSpan(operationName, opts...)
|
||||
return span, ContextWithSpan(ctx, span)
|
||||
}
|
||||
|
||||
+472
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
|
||||
Package harness provides a suite of API compatibility checks. They were originally ported from the
|
||||
OpenTracing Python library's "harness" module.
|
||||
|
||||
To run this test suite against your tracer, call harness.RunAPIChecks and provide it a function
|
||||
that returns a Tracer implementation and a function to call to close it. The function will be
|
||||
called to create a new tracer before each test in the suite is run, and the returned closer function
|
||||
will be called after each test is finished.
|
||||
|
||||
Several options provide additional checks for your Tracer's behavior: CheckBaggageValues(true)
|
||||
indicates your tracer supports baggage propagation, CheckExtract(true) tells the suite to test if
|
||||
the Tracer can extract a trace context from text and binary carriers, and CheckInject(true) tests
|
||||
if the Tracer can inject the trace context into a carrier.
|
||||
|
||||
The UseProbe option provides an APICheckProbe implementation that allows the test suite to
|
||||
additionally check if two Spans are part of the same trace, and if a Span and a SpanContext
|
||||
are part of the same trace. Implementing an APICheckProbe provides additional assertions that
|
||||
your tracer is working properly.
|
||||
|
||||
*/
|
||||
package harness
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
// APICheckCapabilities describes capabilities of a Tracer that should be checked by APICheckSuite.
|
||||
type APICheckCapabilities struct {
|
||||
CheckBaggageValues bool // whether to check for propagation of baggage values
|
||||
CheckExtract bool // whether to check if extracting contexts from carriers works
|
||||
CheckInject bool // whether to check if injecting contexts works
|
||||
Probe APICheckProbe // optional interface providing methods to check recorded data
|
||||
}
|
||||
|
||||
// APICheckProbe exposes methods for testing data recorded by a Tracer.
|
||||
type APICheckProbe interface {
|
||||
// SameTrace helps tests assert that this tracer's spans are from the same trace.
|
||||
SameTrace(first, second opentracing.Span) bool
|
||||
// SameSpanContext helps tests assert that a span and a context are from the same trace and span.
|
||||
SameSpanContext(opentracing.Span, opentracing.SpanContext) bool
|
||||
}
|
||||
|
||||
// APICheckSuite is a testify suite for checking a Tracer against the OpenTracing API.
|
||||
type APICheckSuite struct {
|
||||
suite.Suite
|
||||
opts APICheckCapabilities
|
||||
newTracer func() (tracer opentracing.Tracer, closer func())
|
||||
tracer opentracing.Tracer
|
||||
closer func()
|
||||
}
|
||||
|
||||
// RunAPIChecks runs a test suite to check a Tracer against the OpenTracing API.
|
||||
// It is provided a function that will be executed to create and destroy a tracer for each test
|
||||
// in the suite, and the given APICheckOption functional options `opts`.
|
||||
func RunAPIChecks(
|
||||
t *testing.T,
|
||||
newTracer func() (tracer opentracing.Tracer, closer func()),
|
||||
opts ...APICheckOption,
|
||||
) {
|
||||
s := &APICheckSuite{newTracer: newTracer}
|
||||
for _, opt := range opts {
|
||||
opt(s)
|
||||
}
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
// APICheckOption instances may be passed to NewAPICheckSuite.
|
||||
type APICheckOption func(*APICheckSuite)
|
||||
|
||||
// CheckBaggageValues returns an option that sets whether to check for propagation of baggage values.
|
||||
func CheckBaggageValues(val bool) APICheckOption {
|
||||
return func(s *APICheckSuite) {
|
||||
s.opts.CheckBaggageValues = val
|
||||
}
|
||||
}
|
||||
|
||||
// CheckExtract returns an option that sets whether to check if extracting contexts from carriers works.
|
||||
func CheckExtract(val bool) APICheckOption {
|
||||
return func(s *APICheckSuite) {
|
||||
s.opts.CheckExtract = val
|
||||
}
|
||||
}
|
||||
|
||||
// CheckInject returns an option that sets whether to check if injecting contexts works.
|
||||
func CheckInject(val bool) APICheckOption {
|
||||
return func(s *APICheckSuite) {
|
||||
s.opts.CheckInject = val
|
||||
}
|
||||
}
|
||||
|
||||
// CheckEverything returns an option that enables all API checks.
|
||||
func CheckEverything() APICheckOption {
|
||||
return func(s *APICheckSuite) {
|
||||
s.opts.CheckBaggageValues = true
|
||||
s.opts.CheckExtract = true
|
||||
s.opts.CheckInject = true
|
||||
}
|
||||
}
|
||||
|
||||
// UseProbe returns an option that specifies an APICheckProbe implementation to use.
|
||||
func UseProbe(probe APICheckProbe) APICheckOption {
|
||||
return func(s *APICheckSuite) {
|
||||
s.opts.Probe = probe
|
||||
}
|
||||
}
|
||||
|
||||
// SetupTest creates a tracer for this specific test invocation.
|
||||
func (s *APICheckSuite) SetupTest() {
|
||||
s.tracer, s.closer = s.newTracer()
|
||||
if s.tracer == nil {
|
||||
s.T().Fatalf("newTracer returned nil Tracer")
|
||||
}
|
||||
}
|
||||
|
||||
// TearDownTest closes the tracer, and clears the test-specific tracer.
|
||||
func (s *APICheckSuite) TearDownTest() {
|
||||
if s.closer != nil {
|
||||
s.closer()
|
||||
}
|
||||
s.tracer, s.closer = nil, nil
|
||||
}
|
||||
|
||||
// TestStartSpan checks if a Tracer can start a span and calls some span API methods.
|
||||
func (s *APICheckSuite) TestStartSpan() {
|
||||
span := s.tracer.StartSpan(
|
||||
"Fry",
|
||||
opentracing.Tag{Key: "birthday", Value: "August 14 1974"})
|
||||
span.LogFields(
|
||||
log.String("hospital", "Brooklyn Pre-Med Hospital"),
|
||||
log.String("city", "Old New York"))
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestStartSpanWithParent checks if a Tracer can start a span with a specified parent.
|
||||
func (s *APICheckSuite) TestStartSpanWithParent() {
|
||||
parentSpan := s.tracer.StartSpan("Turanga Munda")
|
||||
s.NotNil(parentSpan)
|
||||
|
||||
childFns := []func(opentracing.SpanContext) opentracing.SpanReference{
|
||||
opentracing.ChildOf,
|
||||
opentracing.FollowsFrom,
|
||||
}
|
||||
for _, childFn := range childFns {
|
||||
span := s.tracer.StartSpan(
|
||||
"Leela",
|
||||
childFn(parentSpan.Context()),
|
||||
opentracing.Tag{Key: "birthplace", Value: "sewers"})
|
||||
span.Finish()
|
||||
if s.opts.Probe != nil {
|
||||
s.True(s.opts.Probe.SameTrace(parentSpan, span))
|
||||
} else {
|
||||
s.T().Log("harness.Probe not specified, skipping")
|
||||
}
|
||||
}
|
||||
|
||||
parentSpan.Finish()
|
||||
}
|
||||
|
||||
// TestSetOperationName attempts to set the operation name on a span after it has been created.
|
||||
func (s *APICheckSuite) TestSetOperationName() {
|
||||
span := s.tracer.StartSpan("").SetOperationName("Farnsworth")
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestSpanTagValueTypes sets tags using values of different types.
|
||||
func (s *APICheckSuite) TestSpanTagValueTypes() {
|
||||
span := s.tracer.StartSpan("ManyTypes")
|
||||
span.
|
||||
SetTag("an_int", 9).
|
||||
SetTag("a_bool", true).
|
||||
SetTag("a_string", "aoeuidhtns")
|
||||
}
|
||||
|
||||
// TestSpanTagsWithChaining tests chaining of calls to SetTag.
|
||||
func (s *APICheckSuite) TestSpanTagsWithChaining() {
|
||||
span := s.tracer.StartSpan("Farnsworth")
|
||||
span.
|
||||
SetTag("birthday", "9 April, 2841").
|
||||
SetTag("loves", "different lengths of wires")
|
||||
span.
|
||||
SetTag("unicode_val", "non-ascii: \u200b").
|
||||
SetTag("unicode_key_\u200b", "ascii val")
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestSpanLogs tests calls to log keys and values with spans.
|
||||
func (s *APICheckSuite) TestSpanLogs() {
|
||||
span := s.tracer.StartSpan("Fry")
|
||||
span.LogKV(
|
||||
"event", "frozen",
|
||||
"year", 1999,
|
||||
"place", "Cryogenics Labs")
|
||||
span.LogKV(
|
||||
"event", "defrosted",
|
||||
"year", 2999,
|
||||
"place", "Cryogenics Labs")
|
||||
|
||||
ts := time.Now()
|
||||
span.FinishWithOptions(opentracing.FinishOptions{
|
||||
LogRecords: []opentracing.LogRecord{
|
||||
{
|
||||
Timestamp: ts,
|
||||
Fields: []log.Field{
|
||||
log.String("event", "job-assignment"),
|
||||
log.String("type", "delivery boy"),
|
||||
},
|
||||
},
|
||||
}})
|
||||
|
||||
// Test deprecated log methods
|
||||
span.LogEvent("an arbitrary event")
|
||||
span.LogEventWithPayload("y", "z")
|
||||
span.Log(opentracing.LogData{Event: "y", Payload: "z"})
|
||||
}
|
||||
|
||||
func assertEmptyBaggage(t *testing.T, spanContext opentracing.SpanContext) {
|
||||
if !assert.NotNil(t, spanContext, "assertEmptyBaggage got empty context") {
|
||||
return
|
||||
}
|
||||
spanContext.ForeachBaggageItem(func(k, v string) bool {
|
||||
assert.Fail(t, "new span shouldn't have baggage")
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
// TestSpanBaggage tests calls to set and get span baggage, and if the CheckBaggageValues option
|
||||
// is set, asserts that baggage values were successfully retrieved.
|
||||
func (s *APICheckSuite) TestSpanBaggage() {
|
||||
span := s.tracer.StartSpan("Fry")
|
||||
assertEmptyBaggage(s.T(), span.Context())
|
||||
|
||||
spanRef := span.SetBaggageItem("Kiff-loves", "Amy")
|
||||
s.Exactly(spanRef, span)
|
||||
|
||||
val := span.BaggageItem("Kiff-loves")
|
||||
if s.opts.CheckBaggageValues {
|
||||
s.Equal("Amy", val)
|
||||
} else {
|
||||
s.T().Log("CheckBaggageValues capability not set, skipping")
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestContextBaggage tests calls to set and get span baggage, and if the CheckBaggageValues option
|
||||
// is set, asserts that baggage values were successfully retrieved from the span's SpanContext.
|
||||
func (s *APICheckSuite) TestContextBaggage() {
|
||||
span := s.tracer.StartSpan("Fry")
|
||||
assertEmptyBaggage(s.T(), span.Context())
|
||||
|
||||
span.SetBaggageItem("Kiff-loves", "Amy")
|
||||
if s.opts.CheckBaggageValues {
|
||||
called := false
|
||||
span.Context().ForeachBaggageItem(func(k, v string) bool {
|
||||
s.False(called)
|
||||
called = true
|
||||
s.Equal("Kiff-loves", k)
|
||||
s.Equal("Amy", v)
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
s.T().Log("CheckBaggageValues capability not set, skipping")
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestTextPropagation tests if the Tracer can Inject a span into a TextMapCarrier, and later Extract it.
|
||||
// If CheckExtract is set, it will check if Extract was successful (returned no error). If a Probe is set,
|
||||
// it will check if the extracted context is in the same trace as the original span.
|
||||
func (s *APICheckSuite) TestTextPropagation() {
|
||||
span := s.tracer.StartSpan("Bender")
|
||||
textCarrier := opentracing.TextMapCarrier{}
|
||||
err := span.Tracer().Inject(span.Context(), opentracing.TextMap, textCarrier)
|
||||
assert.NoError(s.T(), err)
|
||||
|
||||
extractedContext, err := s.tracer.Extract(opentracing.TextMap, textCarrier)
|
||||
if s.opts.CheckExtract {
|
||||
s.NoError(err)
|
||||
assertEmptyBaggage(s.T(), extractedContext)
|
||||
} else {
|
||||
s.T().Log("CheckExtract capability not set, skipping")
|
||||
}
|
||||
if s.opts.Probe != nil {
|
||||
s.True(s.opts.Probe.SameSpanContext(span, extractedContext))
|
||||
} else {
|
||||
s.T().Log("harness.Probe not specified, skipping")
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestHTTPPropagation tests if the Tracer can Inject a span into HTTP headers, and later Extract it.
|
||||
// If CheckExtract is set, it will check if Extract was successful (returned no error). If a Probe is set,
|
||||
// it will check if the extracted context is in the same trace as the original span.
|
||||
func (s *APICheckSuite) TestHTTPPropagation() {
|
||||
span := s.tracer.StartSpan("Bender")
|
||||
textCarrier := opentracing.HTTPHeadersCarrier{}
|
||||
err := span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, textCarrier)
|
||||
s.NoError(err)
|
||||
|
||||
extractedContext, err := s.tracer.Extract(opentracing.HTTPHeaders, textCarrier)
|
||||
if s.opts.CheckExtract {
|
||||
s.NoError(err)
|
||||
assertEmptyBaggage(s.T(), extractedContext)
|
||||
} else {
|
||||
s.T().Log("CheckExtract capability not set, skipping")
|
||||
}
|
||||
if s.opts.Probe != nil {
|
||||
s.True(s.opts.Probe.SameSpanContext(span, extractedContext))
|
||||
} else {
|
||||
s.T().Log("harness.Probe not specified, skipping")
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestBinaryPropagation tests if the Tracer can Inject a span into a binary buffer, and later Extract it.
|
||||
// If CheckExtract is set, it will check if Extract was successful (returned no error). If a Probe is set,
|
||||
// it will check if the extracted context is in the same trace as the original span.
|
||||
func (s *APICheckSuite) TestBinaryPropagation() {
|
||||
span := s.tracer.StartSpan("Bender")
|
||||
buf := new(bytes.Buffer)
|
||||
err := span.Tracer().Inject(span.Context(), opentracing.Binary, buf)
|
||||
s.NoError(err)
|
||||
|
||||
extractedContext, err := s.tracer.Extract(opentracing.Binary, buf)
|
||||
if s.opts.CheckExtract {
|
||||
s.NoError(err)
|
||||
assertEmptyBaggage(s.T(), extractedContext)
|
||||
} else {
|
||||
s.T().Log("CheckExtract capability not set, skipping")
|
||||
}
|
||||
if s.opts.Probe != nil {
|
||||
s.True(s.opts.Probe.SameSpanContext(span, extractedContext))
|
||||
} else {
|
||||
s.T().Log("harness.Probe not specified, skipping")
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestMandatoryFormats tests if all mandatory carrier formats are supported. If CheckExtract is set, it
|
||||
// will check if the call to Extract was successful (returned no error such as ErrUnsupportedFormat).
|
||||
func (s *APICheckSuite) TestMandatoryFormats() {
|
||||
formats := []struct{ Format, Carrier interface{} }{
|
||||
{opentracing.TextMap, opentracing.TextMapCarrier{}},
|
||||
{opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier{}},
|
||||
{opentracing.Binary, new(bytes.Buffer)},
|
||||
}
|
||||
span := s.tracer.StartSpan("Bender")
|
||||
for _, fmtCarrier := range formats {
|
||||
err := span.Tracer().Inject(span.Context(), fmtCarrier.Format, fmtCarrier.Carrier)
|
||||
s.NoError(err)
|
||||
spanCtx, err := s.tracer.Extract(fmtCarrier.Format, fmtCarrier.Carrier)
|
||||
if s.opts.CheckExtract {
|
||||
s.NoError(err)
|
||||
assertEmptyBaggage(s.T(), spanCtx)
|
||||
} else {
|
||||
s.T().Log("CheckExtract capability not set, skipping")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestUnknownFormat checks if attempting to Inject or Extract using an unsupported format
|
||||
// returns ErrUnsupportedFormat, if CheckInject and CheckExtract are set.
|
||||
func (s *APICheckSuite) TestUnknownFormat() {
|
||||
customFormat := "kiss my shiny metal ..."
|
||||
span := s.tracer.StartSpan("Bender")
|
||||
|
||||
err := span.Tracer().Inject(span.Context(), customFormat, nil)
|
||||
if s.opts.CheckInject {
|
||||
s.Equal(opentracing.ErrUnsupportedFormat, err)
|
||||
} else {
|
||||
s.T().Log("CheckInject capability not set, skipping")
|
||||
}
|
||||
ctx, err := s.tracer.Extract(customFormat, nil)
|
||||
s.Nil(ctx)
|
||||
if s.opts.CheckExtract {
|
||||
s.Equal(opentracing.ErrUnsupportedFormat, err)
|
||||
} else {
|
||||
s.T().Log("CheckExtract capability not set, skipping")
|
||||
}
|
||||
}
|
||||
|
||||
// ForeignSpanContext satisfies the opentracing.SpanContext interface, but otherwise does nothing.
|
||||
type ForeignSpanContext struct{}
|
||||
|
||||
// ForeachBaggageItem could call handler for each baggage KV, but does nothing.
|
||||
func (f ForeignSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
|
||||
|
||||
// NotACarrier does not satisfy any of the opentracing carrier interfaces.
|
||||
type NotACarrier struct{}
|
||||
|
||||
// TestInvalidInject checks if errors are returned when Inject is called with invalid inputs.
|
||||
func (s *APICheckSuite) TestInvalidInject() {
|
||||
if !s.opts.CheckInject {
|
||||
s.T().Skip("CheckInject capability not set, skipping")
|
||||
}
|
||||
span := s.tracer.StartSpan("op")
|
||||
|
||||
// binary inject
|
||||
err := span.Tracer().Inject(ForeignSpanContext{}, opentracing.Binary, new(bytes.Buffer))
|
||||
s.Equal(opentracing.ErrInvalidSpanContext, err, "Foreign SpanContext should return invalid error")
|
||||
err = span.Tracer().Inject(span.Context(), opentracing.Binary, NotACarrier{})
|
||||
s.Equal(opentracing.ErrInvalidCarrier, err, "Carrier that's not io.Writer should return error")
|
||||
|
||||
// text inject
|
||||
err = span.Tracer().Inject(ForeignSpanContext{}, opentracing.TextMap, opentracing.TextMapCarrier{})
|
||||
s.Equal(opentracing.ErrInvalidSpanContext, err, "Foreign SpanContext should return invalid error")
|
||||
err = span.Tracer().Inject(span.Context(), opentracing.TextMap, NotACarrier{})
|
||||
s.Equal(opentracing.ErrInvalidCarrier, err, "Carrier that's not TextMapWriter should return error")
|
||||
|
||||
// HTTP inject
|
||||
err = span.Tracer().Inject(ForeignSpanContext{}, opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier{})
|
||||
s.Equal(opentracing.ErrInvalidSpanContext, err, "Foreign SpanContext should return invalid error")
|
||||
err = span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, NotACarrier{})
|
||||
s.Equal(opentracing.ErrInvalidCarrier, err, "Carrier that's not TextMapWriter should return error")
|
||||
}
|
||||
|
||||
// TestInvalidExtract checks if errors are returned when Extract is called with invalid inputs.
|
||||
func (s *APICheckSuite) TestInvalidExtract() {
|
||||
if !s.opts.CheckExtract {
|
||||
s.T().Skip("CheckExtract capability not set, skipping")
|
||||
}
|
||||
span := s.tracer.StartSpan("op")
|
||||
|
||||
// binary extract
|
||||
ctx, err := span.Tracer().Extract(opentracing.Binary, NotACarrier{})
|
||||
s.Equal(opentracing.ErrInvalidCarrier, err, "Carrier that's not io.Reader should return error")
|
||||
s.Nil(ctx)
|
||||
|
||||
// text extract
|
||||
ctx, err = span.Tracer().Extract(opentracing.TextMap, NotACarrier{})
|
||||
s.Equal(opentracing.ErrInvalidCarrier, err, "Carrier that's not TextMapReader should return error")
|
||||
s.Nil(ctx)
|
||||
|
||||
// HTTP extract
|
||||
ctx, err = span.Tracer().Extract(opentracing.HTTPHeaders, NotACarrier{})
|
||||
s.Equal(opentracing.ErrInvalidCarrier, err, "Carrier that's not TextMapReader should return error")
|
||||
s.Nil(ctx)
|
||||
|
||||
span.Finish()
|
||||
}
|
||||
|
||||
// TestMultiBaggage tests calls to set multiple baggage items, and if the CheckBaggageValues option
|
||||
// is set, asserts that a baggage value was successfully retrieved from the span's SpanContext.
|
||||
// It also ensures that returning false from the ForeachBaggageItem handler aborts iteration.
|
||||
func (s *APICheckSuite) TestMultiBaggage() {
|
||||
span := s.tracer.StartSpan("op")
|
||||
assertEmptyBaggage(s.T(), span.Context())
|
||||
|
||||
span.SetBaggageItem("Bag1", "BaggageVal1")
|
||||
span.SetBaggageItem("Bag2", "BaggageVal2")
|
||||
if s.opts.CheckBaggageValues {
|
||||
s.Equal("BaggageVal1", span.BaggageItem("Bag1"))
|
||||
s.Equal("BaggageVal2", span.BaggageItem("Bag2"))
|
||||
called := false
|
||||
span.Context().ForeachBaggageItem(func(k, v string) bool {
|
||||
s.False(called) // should only be called once
|
||||
called = true
|
||||
return false
|
||||
})
|
||||
s.True(called)
|
||||
} else {
|
||||
s.T().Log("CheckBaggageValues capability not set, skipping")
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
+29
-1
@@ -20,6 +20,7 @@ const (
|
||||
errorType
|
||||
objectType
|
||||
lazyLoggerType
|
||||
noopType
|
||||
)
|
||||
|
||||
// Field instances are constructed via LogBool, LogString, and so on.
|
||||
@@ -152,6 +153,25 @@ func Lazy(ll LazyLogger) Field {
|
||||
}
|
||||
}
|
||||
|
||||
// Noop creates a no-op log field that should be ignored by the tracer.
|
||||
// It can be used to capture optional fields, for example those that should
|
||||
// only be logged in non-production environment:
|
||||
//
|
||||
// func customerField(order *Order) log.Field {
|
||||
// if os.Getenv("ENVIRONMENT") == "dev" {
|
||||
// return log.String("customer", order.Customer.ID)
|
||||
// }
|
||||
// return log.Noop()
|
||||
// }
|
||||
//
|
||||
// span.LogFields(log.String("event", "purchase"), customerField(order))
|
||||
//
|
||||
func Noop() Field {
|
||||
return Field{
|
||||
fieldType: noopType,
|
||||
}
|
||||
}
|
||||
|
||||
// Encoder allows access to the contents of a Field (via a call to
|
||||
// Field.Marshal).
|
||||
//
|
||||
@@ -194,11 +214,17 @@ func (lf Field) Marshal(visitor Encoder) {
|
||||
case float64Type:
|
||||
visitor.EmitFloat64(lf.key, math.Float64frombits(uint64(lf.numericVal)))
|
||||
case errorType:
|
||||
visitor.EmitString(lf.key, lf.interfaceVal.(error).Error())
|
||||
if err, ok := lf.interfaceVal.(error); ok {
|
||||
visitor.EmitString(lf.key, err.Error())
|
||||
} else {
|
||||
visitor.EmitString(lf.key, "<nil>")
|
||||
}
|
||||
case objectType:
|
||||
visitor.EmitObject(lf.key, lf.interfaceVal)
|
||||
case lazyLoggerType:
|
||||
visitor.EmitLazyLogger(lf.interfaceVal.(LazyLogger))
|
||||
case noopType:
|
||||
// intentionally left blank
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +256,8 @@ func (lf Field) Value() interface{} {
|
||||
return math.Float64frombits(uint64(lf.numericVal))
|
||||
case errorType, objectType, lazyLoggerType:
|
||||
return lf.interfaceVal
|
||||
case noopType:
|
||||
return nil
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
+3
-2
@@ -28,8 +28,7 @@ type MockSpanContext struct {
|
||||
var mockIDSource = uint32(42)
|
||||
|
||||
func nextMockID() int {
|
||||
atomic.AddUint32(&mockIDSource, 1)
|
||||
return int(atomic.LoadUint32(&mockIDSource))
|
||||
return int(atomic.AddUint32(&mockIDSource, 1))
|
||||
}
|
||||
|
||||
// ForeachBaggageItem belongs to the SpanContext interface
|
||||
@@ -136,6 +135,8 @@ func (s *MockSpan) Logs() []MockLogRecord {
|
||||
|
||||
// Context belongs to the Span interface
|
||||
func (s *MockSpan) Context() opentracing.SpanContext {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
return s.SpanContext
|
||||
}
|
||||
|
||||
|
||||
+13
-2
@@ -2,8 +2,19 @@ package opentracing
|
||||
|
||||
import "github.com/opentracing/opentracing-go/log"
|
||||
|
||||
// A NoopTracer is a trivial implementation of Tracer for which all operations
|
||||
// are no-ops.
|
||||
// A NoopTracer is a trivial, minimum overhead implementation of Tracer
|
||||
// for which all operations are no-ops.
|
||||
//
|
||||
// The primary use of this implementation is in libraries, such as RPC
|
||||
// frameworks, that make tracing an optional feature controlled by the
|
||||
// end user. A no-op implementation allows said libraries to use it
|
||||
// as the default Tracer and to write instrumentation that does
|
||||
// not need to keep checking if the tracer instance is nil.
|
||||
//
|
||||
// For the same reason, the NoopTracer is the default "global" tracer
|
||||
// (see GlobalTracer and SetGlobalTracer functions).
|
||||
//
|
||||
// WARNING: NoopTracer does not support baggage propagation.
|
||||
type NoopTracer struct{}
|
||||
|
||||
type noopSpan struct{}
|
||||
|
||||
+6
-6
@@ -72,18 +72,18 @@ const (
|
||||
//
|
||||
// For Tracer.Extract(): the carrier must be a `TextMapReader`.
|
||||
//
|
||||
// See HTTPHeaderCarrier for an implementation of both TextMapWriter
|
||||
// See HTTPHeadersCarrier for an implementation of both TextMapWriter
|
||||
// and TextMapReader that defers to an http.Header instance for storage.
|
||||
// For example, Inject():
|
||||
//
|
||||
// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
|
||||
// err := span.Tracer().Inject(
|
||||
// span, opentracing.HTTPHeaders, carrier)
|
||||
// span.Context(), opentracing.HTTPHeaders, carrier)
|
||||
//
|
||||
// Or Extract():
|
||||
//
|
||||
// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
|
||||
// span, err := tracer.Extract(
|
||||
// clientContext, err := tracer.Extract(
|
||||
// opentracing.HTTPHeaders, carrier)
|
||||
//
|
||||
HTTPHeaders
|
||||
@@ -144,15 +144,15 @@ func (c TextMapCarrier) Set(key, val string) {
|
||||
//
|
||||
// Example usage for server side:
|
||||
//
|
||||
// carrier := opentracing.HttpHeadersCarrier(httpReq.Header)
|
||||
// spanContext, err := tracer.Extract(opentracing.HttpHeaders, carrier)
|
||||
// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
|
||||
// clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
|
||||
//
|
||||
// Example usage for client side:
|
||||
//
|
||||
// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
|
||||
// err := tracer.Inject(
|
||||
// span.Context(),
|
||||
// opentracing.HttpHeaders,
|
||||
// opentracing.HTTPHeaders,
|
||||
// carrier)
|
||||
//
|
||||
type HTTPHeadersCarrier http.Header
|
||||
|
||||
+4
@@ -41,6 +41,8 @@ type Span interface {
|
||||
Context() SpanContext
|
||||
|
||||
// Sets or changes the operation name.
|
||||
//
|
||||
// Returns a reference to this Span for chaining.
|
||||
SetOperationName(operationName string) Span
|
||||
|
||||
// Adds a tag to the span.
|
||||
@@ -51,6 +53,8 @@ type Span interface {
|
||||
// other tag value types is undefined at the OpenTracing level. If a
|
||||
// tracing system does not know how to handle a particular value type, it
|
||||
// may ignore the tag, but shall not panic.
|
||||
//
|
||||
// Returns a reference to this Span for chaining.
|
||||
SetTag(key string, value interface{}) Span
|
||||
|
||||
// LogFields is an efficient and type-checked way to record key:value
|
||||
|
||||
+4
-4
@@ -30,7 +30,7 @@ type Tracer interface {
|
||||
// sp := tracer.StartSpan(
|
||||
// "GetFeed",
|
||||
// opentracing.ChildOf(parentSpan.Context()),
|
||||
// opentracing.Tag("user_agent", loggedReq.UserAgent),
|
||||
// opentracing.Tag{"user_agent", loggedReq.UserAgent},
|
||||
// opentracing.StartTime(loggedReq.Timestamp),
|
||||
// )
|
||||
//
|
||||
@@ -52,7 +52,7 @@ type Tracer interface {
|
||||
// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
|
||||
// err := tracer.Inject(
|
||||
// span.Context(),
|
||||
// opentracing.HttpHeaders,
|
||||
// opentracing.HTTPHeaders,
|
||||
// carrier)
|
||||
//
|
||||
// NOTE: All opentracing.Tracer implementations MUST support all
|
||||
@@ -80,8 +80,8 @@ type Tracer interface {
|
||||
// Example usage (with StartSpan):
|
||||
//
|
||||
//
|
||||
// carrier := opentracing.HttpHeadersCarrier(httpReq.Header)
|
||||
// clientContext, err := tracer.Extract(opentracing.HttpHeaders, carrier)
|
||||
// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header)
|
||||
// clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier)
|
||||
//
|
||||
// // ... assuming the ultimate goal here is to resume the trace with a
|
||||
// // server-side Span:
|
||||
|
||||
Vendored
+1
-1
@@ -1655,7 +1655,7 @@
|
||||
"importpath": "github.com/opentracing/opentracing-go",
|
||||
"repository": "https://github.com/opentracing/opentracing-go",
|
||||
"vcs": "git",
|
||||
"revision": "902ca977fd85455c364050f985eba376b44315f0",
|
||||
"revision": "bd9c3193394760d98b2fa6ebb2291f0cd1d06a7d",
|
||||
"branch": "master",
|
||||
"notests": true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user