You've already forked opentelemetry-go
							
							
				mirror of
				https://github.com/open-telemetry/opentelemetry-go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	WIP: Named tracer prototype (#227)
* named tracer prototype * rename Manager to Provider. * fix compile error after merge. * rename Tracer method to GetTracer * provider with options. * update test. * cleanup make circl-ci * remove global config. * some cleanup. * use provider for bridge * update propagation test. * update examples and plugins. * remove GlobalTracer methods. * fix review comments. * some more cleanup. * remove unnecessary getTracer call in benchmark test.
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -7,4 +7,5 @@ coverage.* | ||||
| /example/basic/basic | ||||
| /example/http/client/client | ||||
| /example/http/server/server | ||||
| /example/namedtracer/namedtracer | ||||
| /experimental/streaming/example/basic/basic | ||||
|   | ||||
| @@ -24,6 +24,12 @@ import ( | ||||
| 	"go.opentelemetry.io/api/distributedcontext" | ||||
| ) | ||||
|  | ||||
| type Provider interface { | ||||
| 	// GetTracer creates a named tracer that implements Tracer interface. | ||||
| 	// If the name is an empty string then provider uses default name. | ||||
| 	GetTracer(name string) Tracer | ||||
| } | ||||
|  | ||||
| type Tracer interface { | ||||
| 	// Start a span. | ||||
| 	Start(context.Context, string, ...SpanOption) (context.Context, Span) | ||||
| @@ -137,11 +143,6 @@ type Link struct { | ||||
| 	Attributes []core.KeyValue | ||||
| } | ||||
|  | ||||
| // Start starts a new span using registered global tracer. | ||||
| func Start(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) { | ||||
| 	return GlobalTracer().Start(ctx, name, opts...) | ||||
| } | ||||
|  | ||||
| // WithStartTime sets the start time of the span to provided time t, when it is started. | ||||
| // In absensce of this option, wall clock time is used as start time. | ||||
| // This option is typically used when starting of the span is delayed. | ||||
|   | ||||
| @@ -16,21 +16,24 @@ package trace | ||||
|  | ||||
| import "sync/atomic" | ||||
|  | ||||
| // The process global tracer could have process-wide resource | ||||
| // tags applied directly, or we can have a SetGlobal tracer to | ||||
| // install a default tracer w/ resources. | ||||
| var global atomic.Value | ||||
| type globalProvider struct { | ||||
| 	p Provider | ||||
| } | ||||
|  | ||||
| // GlobalTracer return tracer registered with global registry. | ||||
| // If no tracer is registered then an instance of noop Tracer is returned. | ||||
| func GlobalTracer() Tracer { | ||||
| 	if t := global.Load(); t != nil { | ||||
| 		return t.(Tracer) | ||||
| var globalP atomic.Value | ||||
|  | ||||
| // GlobalProvider returns trace provider registered with global registry. | ||||
| // If no trace provider is registered then an instance of NoopTraceProvider is returned. | ||||
| // Use the trace provider to create a named tracer. E.g. | ||||
| //     tracer := trace.GlobalProvider().GetTracer("example.com/foo") | ||||
| func GlobalProvider() Provider { | ||||
| 	if gp := globalP.Load(); gp != nil { | ||||
| 		return gp.(globalProvider).p | ||||
| 	} | ||||
| 	return NoopTracer{} | ||||
| 	return NoopTraceProvider{} | ||||
| } | ||||
|  | ||||
| // SetGlobalTracer sets provided tracer as a global tracer. | ||||
| func SetGlobalTracer(t Tracer) { | ||||
| 	global.Store(t) | ||||
| // SetGlobalProvider sets the provider as a global trace provider. | ||||
| func SetGlobalProvider(m Provider) { | ||||
| 	globalP.Store(globalProvider{p: m}) | ||||
| } | ||||
|   | ||||
| @@ -15,27 +15,30 @@ | ||||
| package trace_test | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"go.opentelemetry.io/api/trace" | ||||
| ) | ||||
| 
 | ||||
| // This example shows how to use trace.Start and (*Span).End to capture | ||||
| // a function execution in a Span. It assumes that the function | ||||
| // has a context.Context argument. | ||||
| func ExampleStart() { | ||||
| 	printEvens := func(ctx context.Context) { | ||||
| 		_, span := trace.GlobalTracer().Start(ctx, "my/package.Function") | ||||
| 		defer span.End() | ||||
| 
 | ||||
| 		for i := 0; i < 10; i++ { | ||||
| 			if i%2 == 0 { | ||||
| 				fmt.Printf("Even!\n") | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ctx := context.Background() | ||||
| 	printEvens(ctx) | ||||
| type TestProvider1 struct { | ||||
| } | ||||
| 
 | ||||
| var _ trace.Provider = &TestProvider1{} | ||||
| 
 | ||||
| func (tp *TestProvider1) GetTracer(name string) trace.Tracer { | ||||
| 	return &trace.NoopTracer{} | ||||
| } | ||||
| 
 | ||||
| func TestMulitpleGlobalProvider(t *testing.T) { | ||||
| 
 | ||||
| 	p1 := TestProvider1{} | ||||
| 	p2 := trace.NoopTraceProvider{} | ||||
| 	trace.SetGlobalProvider(&p1) | ||||
| 	trace.SetGlobalProvider(&p2) | ||||
| 
 | ||||
| 	got := trace.GlobalProvider() | ||||
| 	want := &p2 | ||||
| 	if got != want { | ||||
| 		t.Fatalf("Provider: got %p, want %p\n", got, want) | ||||
| 	} | ||||
| } | ||||
| @@ -14,15 +14,11 @@ | ||||
| 
 | ||||
| package trace | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| ) | ||||
| type NoopTraceProvider struct{} | ||||
| 
 | ||||
| // GlobalTracer return tracer registered with global registry. | ||||
| // If no tracer is registered then an instance of noop Tracer is returned. | ||||
| func TestGlobalTracer(t *testing.T) { | ||||
| 	tracer := GlobalTracer() | ||||
| 	if tracer == nil { | ||||
| 		t.Fatalf("Failed to get tracer\n") | ||||
| 	} | ||||
| var _ Provider = NoopTraceProvider{} | ||||
| 
 | ||||
| // GetTracer returns noop implementation of Tracer. | ||||
| func (p NoopTraceProvider) GetTracer(name string) Tracer { | ||||
| 	return NoopTracer{} | ||||
| } | ||||
| @@ -24,7 +24,7 @@ import ( | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	tracer = trace.GlobalTracer() | ||||
| 	tracer = trace.GlobalProvider().GetTracer("ex.com/basic") | ||||
|  | ||||
| 	meter = metric.GlobalMeter() // TODO: should share resources ^^^? | ||||
|  | ||||
|   | ||||
| @@ -35,9 +35,6 @@ import ( | ||||
| ) | ||||
|  | ||||
| func initTracer() { | ||||
| 	// Register SDK as trace provider. | ||||
| 	sdktrace.Register() | ||||
|  | ||||
| 	projectID := os.Getenv("PROJECT_ID") | ||||
|  | ||||
| 	// Create Stackdriver exporter to be able to retrieve | ||||
| @@ -48,15 +45,20 @@ func initTracer() { | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	exporter.RegisterSimpleSpanProcessor() | ||||
|  | ||||
| 	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. | ||||
| 	// In a production application, use sdktrace.ProbabilitySampler with a desired probability. | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||||
| 		sdktrace.WithSyncer(exporter)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	trace.SetGlobalProvider(tp) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	initTracer() | ||||
| 	tr := trace.GlobalProvider().GetTracer("stackdriver/example/client") | ||||
|  | ||||
| 	client := http.DefaultClient | ||||
| 	ctx := distributedcontext.NewContext(context.Background(), | ||||
| @@ -65,7 +67,7 @@ func main() { | ||||
|  | ||||
| 	var body []byte | ||||
|  | ||||
| 	err := trace.GlobalTracer().WithSpan(ctx, "say hello", | ||||
| 	err := tr.WithSpan(ctx, "say hello", | ||||
| 		func(ctx context.Context) error { | ||||
| 			req, _ := http.NewRequest("GET", "http://localhost:7777/hello", nil) | ||||
|  | ||||
|   | ||||
| @@ -28,8 +28,6 @@ import ( | ||||
| ) | ||||
|  | ||||
| func initTracer() { | ||||
| 	sdktrace.Register() | ||||
|  | ||||
| 	projectID := os.Getenv("PROJECT_ID") | ||||
|  | ||||
| 	// Create Stackdriver exporter to be able to retrieve | ||||
| @@ -40,18 +38,22 @@ func initTracer() { | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	if err := exporter.RegisterBatchSpanProcessor(); err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. | ||||
| 	// In a production application, use sdktrace.ProbabilitySampler with a desired probability. | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||||
| 		sdktrace.WithSyncer(exporter)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	trace.SetGlobalProvider(tp) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	initTracer() | ||||
|  | ||||
| 	tr := trace.GlobalProvider().GetTracer("stackdriver/example/server") | ||||
|  | ||||
| 	helloHandler := func(w http.ResponseWriter, req *http.Request) { | ||||
| 		attrs, entries, spanCtx := httptrace.Extract(req.Context(), req) | ||||
|  | ||||
| @@ -59,7 +61,7 @@ func main() { | ||||
| 			MultiKV: entries, | ||||
| 		}))) | ||||
|  | ||||
| 		ctx, span := trace.GlobalTracer().Start( | ||||
| 		ctx, span := tr.Start( | ||||
| 			req.Context(), | ||||
| 			"hello", | ||||
| 			trace.WithAttributes(attrs...), | ||||
|   | ||||
| @@ -34,9 +34,6 @@ import ( | ||||
| ) | ||||
|  | ||||
| func initTracer() { | ||||
| 	// Register SDK as trace provider. | ||||
| 	sdktrace.Register() | ||||
|  | ||||
| 	// Create stdout exporter to be able to retrieve | ||||
| 	// the collected spans. | ||||
| 	exporter, err := stdout.NewExporter(stdout.Options{PrettyPrint: true}) | ||||
| @@ -47,7 +44,12 @@ func initTracer() { | ||||
|  | ||||
| 	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. | ||||
| 	// In a production application, use sdktrace.ProbabilitySampler with a desired probability. | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||||
| 		sdktrace.WithSyncer(exporter)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	trace.SetGlobalProvider(tp) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| @@ -60,7 +62,8 @@ func main() { | ||||
|  | ||||
| 	var body []byte | ||||
|  | ||||
| 	err := trace.GlobalTracer().WithSpan(ctx, "say hello", | ||||
| 	tr := trace.GlobalProvider().GetTracer("example/client") | ||||
| 	err := tr.WithSpan(ctx, "say hello", | ||||
| 		func(ctx context.Context) error { | ||||
| 			req, _ := http.NewRequest("GET", "http://localhost:7777/hello", nil) | ||||
|  | ||||
|   | ||||
| @@ -27,8 +27,6 @@ import ( | ||||
| ) | ||||
|  | ||||
| func initTracer() { | ||||
| 	sdktrace.Register() | ||||
|  | ||||
| 	// Create stdout exporter to be able to retrieve | ||||
| 	// the collected spans. | ||||
| 	exporter, err := stdout.NewExporter(stdout.Options{PrettyPrint: true}) | ||||
| @@ -39,11 +37,17 @@ func initTracer() { | ||||
|  | ||||
| 	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. | ||||
| 	// In a production application, use sdktrace.ProbabilitySampler with a desired probability. | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||||
| 		sdktrace.WithSyncer(exporter)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	trace.SetGlobalProvider(tp) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	initTracer() | ||||
| 	tr := trace.GlobalProvider().GetTracer("example/server") | ||||
|  | ||||
| 	helloHandler := func(w http.ResponseWriter, req *http.Request) { | ||||
| 		attrs, entries, spanCtx := httptrace.Extract(req.Context(), req) | ||||
| @@ -52,7 +56,7 @@ func main() { | ||||
| 			MultiKV: entries, | ||||
| 		}))) | ||||
|  | ||||
| 		ctx, span := trace.GlobalTracer().Start( | ||||
| 		ctx, span := tr.Start( | ||||
| 			req.Context(), | ||||
| 			"hello", | ||||
| 			trace.WithAttributes(attrs...), | ||||
|   | ||||
							
								
								
									
										46
									
								
								example/namedtracer/foo/foo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								example/namedtracer/foo/foo.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| // Copyright 2019, 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 foo | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.opentelemetry.io/api/key" | ||||
| 	"go.opentelemetry.io/api/trace" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	lemonsKey = key.New("ex.com/lemons") | ||||
| ) | ||||
|  | ||||
| // SubOperation is an example to demonstrate the use of named tracer. | ||||
| // It creates a named tracer with its package path. | ||||
| func SubOperation(ctx context.Context) error { | ||||
|  | ||||
| 	// Using global provider. Alternative is to have application provide a getter | ||||
| 	// for its component to get the instance of the provider. | ||||
| 	tr := trace.GlobalProvider().GetTracer("example/namedtracer/foo") | ||||
| 	return tr.WithSpan( | ||||
| 		ctx, | ||||
| 		"Sub operation...", | ||||
| 		func(ctx context.Context) error { | ||||
| 			trace.CurrentSpan(ctx).SetAttribute(lemonsKey.String("five")) | ||||
|  | ||||
| 			trace.CurrentSpan(ctx).AddEvent(ctx, "Sub span event") | ||||
|  | ||||
| 			return nil | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
							
								
								
									
										7
									
								
								example/namedtracer/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								example/namedtracer/go.mod
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| module go.opentelemetry.io/example/namedtracer | ||||
|  | ||||
| go 1.12 | ||||
|  | ||||
| replace go.opentelemetry.io => ../.. | ||||
|  | ||||
| require go.opentelemetry.io v0.0.0-00010101000000-000000000000 | ||||
							
								
								
									
										371
									
								
								example/namedtracer/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								example/namedtracer/go.sum
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,371 @@ | ||||
| cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
| cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
| cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= | ||||
| cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= | ||||
| cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= | ||||
| cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= | ||||
| cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= | ||||
| cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= | ||||
| cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= | ||||
| cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | ||||
| github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= | ||||
| github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= | ||||
| github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= | ||||
| github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | ||||
| github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= | ||||
| github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | ||||
| github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | ||||
| github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||
| github.com/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM= | ||||
| github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= | ||||
| github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | ||||
| github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= | ||||
| github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= | ||||
| github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= | ||||
| github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | ||||
| github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= | ||||
| github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= | ||||
| github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= | ||||
| github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||||
| github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||
| github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= | ||||
| github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | ||||
| github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= | ||||
| github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= | ||||
| github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= | ||||
| github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= | ||||
| github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||||
| github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= | ||||
| github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= | ||||
| github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= | ||||
| github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= | ||||
| github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= | ||||
| github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= | ||||
| github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= | ||||
| github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= | ||||
| github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= | ||||
| github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= | ||||
| github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= | ||||
| github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= | ||||
| github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= | ||||
| github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= | ||||
| github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= | ||||
| github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
| github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= | ||||
| github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= | ||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||
| github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||
| github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= | ||||
| github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= | ||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= | ||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= | ||||
| github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= | ||||
| github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= | ||||
| github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= | ||||
| github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= | ||||
| github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= | ||||
| github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= | ||||
| github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= | ||||
| github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= | ||||
| github.com/golangci/golangci-lint v1.21.0/go.mod h1:phxpHK52q7SE+5KpPnti4oZTdFCEsn/tKN+nFvCKXfk= | ||||
| github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= | ||||
| github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= | ||||
| github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= | ||||
| github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= | ||||
| github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= | ||||
| github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= | ||||
| github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= | ||||
| github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= | ||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||
| github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= | ||||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||||
| github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= | ||||
| github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= | ||||
| github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= | ||||
| github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= | ||||
| github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= | ||||
| github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||
| github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= | ||||
| github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= | ||||
| github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= | ||||
| github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= | ||||
| github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= | ||||
| github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= | ||||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | ||||
| github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||
| github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= | ||||
| github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= | ||||
| github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||
| github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= | ||||
| github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= | ||||
| github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= | ||||
| github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||||
| github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||
| github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= | ||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||||
| github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= | ||||
| github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | ||||
| github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | ||||
| github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= | ||||
| github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= | ||||
| github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||||
| github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= | ||||
| github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | ||||
| github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= | ||||
| github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | ||||
| github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= | ||||
| github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||
| github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= | ||||
| github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= | ||||
| github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | ||||
| github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= | ||||
| github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= | ||||
| github.com/pelletier/go-toml v1.5.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= | ||||
| github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | ||||
| github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= | ||||
| github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||||
| github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | ||||
| github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | ||||
| github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | ||||
| github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | ||||
| github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= | ||||
| github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= | ||||
| github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | ||||
| github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | ||||
| github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do= | ||||
| github.com/securego/gosec v0.0.0-20191008095658-28c1128b7336/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do= | ||||
| github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= | ||||
| github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= | ||||
| github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= | ||||
| github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= | ||||
| github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | ||||
| github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | ||||
| github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= | ||||
| github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= | ||||
| github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= | ||||
| github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | ||||
| github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= | ||||
| github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||
| github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= | ||||
| github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | ||||
| github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= | ||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||
| github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | ||||
| github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= | ||||
| github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | ||||
| github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= | ||||
| github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= | ||||
| github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= | ||||
| github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= | ||||
| github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= | ||||
| github.com/uudashr/gocognit v1.0.0/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= | ||||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||||
| github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= | ||||
| github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= | ||||
| github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= | ||||
| github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= | ||||
| github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= | ||||
| go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= | ||||
| go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= | ||||
| go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= | ||||
| go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||
| go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= | ||||
| go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | ||||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= | ||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||
| golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||
| golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= | ||||
| golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= | ||||
| golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= | ||||
| golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | ||||
| golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= | ||||
| golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= | ||||
| golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= | ||||
| golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= | ||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||||
| golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
| golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= | ||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
| golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= | ||||
| golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= | ||||
| golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= | ||||
| golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= | ||||
| golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= | ||||
| golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20190911151314-feee8acb394c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20191015211201-9c6d90b5a7d0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= | ||||
| google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= | ||||
| google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= | ||||
| google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= | ||||
| google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | ||||
| google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||||
| google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||||
| google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= | ||||
| google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= | ||||
| google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||||
| google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= | ||||
| google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= | ||||
| google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= | ||||
| google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= | ||||
| google.golang.org/genproto v0.0.0-20190925194540-b8fbc687dcfb h1:KyQ8P4ITs8M0jBWofeXBAlng8kJVbXKyliNX5w2w/ng= | ||||
| google.golang.org/genproto v0.0.0-20190925194540-b8fbc687dcfb/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= | ||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||
| google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||
| google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||
| google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= | ||||
| google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= | ||||
| gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||||
| gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | ||||
| gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | ||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||
| gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= | ||||
| gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= | ||||
| mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= | ||||
| mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= | ||||
| mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= | ||||
| mvdan.cc/unparam v0.0.0-20190917161559-b83a221c10a2/go.mod h1:rCqoQrfAmpTX/h2APczwM7UymU/uvaOluiVPIYCSY/k= | ||||
| rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= | ||||
| sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= | ||||
| sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4= | ||||
							
								
								
									
										77
									
								
								example/namedtracer/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								example/namedtracer/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // Copyright 2019, 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 main | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"log" | ||||
|  | ||||
| 	"go.opentelemetry.io/api/distributedcontext" | ||||
| 	"go.opentelemetry.io/api/key" | ||||
| 	"go.opentelemetry.io/api/trace" | ||||
| 	"go.opentelemetry.io/example/namedtracer/foo" | ||||
| 	"go.opentelemetry.io/exporter/trace/stdout" | ||||
| 	sdktrace "go.opentelemetry.io/sdk/trace" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	fooKey     = key.New("ex.com/foo") | ||||
| 	barKey     = key.New("ex.com/bar") | ||||
| 	anotherKey = key.New("ex.com/another") | ||||
| ) | ||||
|  | ||||
| var tp *sdktrace.Provider | ||||
|  | ||||
| // initTracer creates and registers trace provider instance. | ||||
| func initTracer() { | ||||
| 	var err error | ||||
| 	exp, err := stdout.NewExporter(stdout.Options{}) | ||||
| 	if err != nil { | ||||
| 		log.Panicf("failed to initialize stdout exporter %v\n", err) | ||||
| 		return | ||||
| 	} | ||||
| 	tp, err = sdktrace.NewProvider(sdktrace.WithSyncer(exp), | ||||
| 		sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()})) | ||||
| 	if err != nil { | ||||
| 		log.Panicf("failed to initialize trace provider %v\n", err) | ||||
| 	} | ||||
| 	trace.SetGlobalProvider(tp) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	// initialize trace provider. | ||||
| 	initTracer() | ||||
|  | ||||
| 	// Create a named tracer with package path as its name. | ||||
| 	tracer := tp.GetTracer("example/namedtracer/main") | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	ctx = distributedcontext.NewContext(ctx, | ||||
| 		distributedcontext.Insert(fooKey.String("foo1")), | ||||
| 		distributedcontext.Insert(barKey.String("bar1")), | ||||
| 	) | ||||
|  | ||||
| 	err := tracer.WithSpan(ctx, "operation", func(ctx context.Context) error { | ||||
|  | ||||
| 		trace.CurrentSpan(ctx).AddEvent(ctx, "Nice operation!", key.New("bogons").Int(100)) | ||||
|  | ||||
| 		trace.CurrentSpan(ctx).SetAttributes(anotherKey.String("yes")) | ||||
|  | ||||
| 		return foo.SubOperation(ctx) | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| } | ||||
| @@ -26,7 +26,7 @@ import ( | ||||
| 	otelcore "go.opentelemetry.io/api/core" | ||||
| 	oteltrace "go.opentelemetry.io/api/trace" | ||||
|  | ||||
| 	internal "go.opentelemetry.io/experimental/bridge/opentracing/internal" | ||||
| 	"go.opentelemetry.io/experimental/bridge/opentracing/internal" | ||||
| ) | ||||
|  | ||||
| type mixedAPIsTestCase struct { | ||||
| @@ -112,13 +112,13 @@ func TestMixedAPIs(t *testing.T) { | ||||
| 	for idx, tc := range getMixedAPIsTestCases() { | ||||
| 		t.Logf("Running test case %d: %s", idx, tc.desc) | ||||
| 		mockOtelTracer := internal.NewMockTracer() | ||||
| 		otTracer, otelTracer := NewTracerPair(mockOtelTracer) | ||||
| 		otTracer, otelProvider := NewTracerPair(mockOtelTracer) | ||||
| 		otTracer.SetWarningHandler(func(msg string) { | ||||
| 			t.Log(msg) | ||||
| 		}) | ||||
| 		ctx := context.Background() | ||||
|  | ||||
| 		oteltrace.SetGlobalTracer(otelTracer) | ||||
| 		oteltrace.SetGlobalProvider(otelProvider) | ||||
| 		ot.SetGlobalTracer(otTracer) | ||||
|  | ||||
| 		tc.setup(t, mockOtelTracer) | ||||
| @@ -424,7 +424,7 @@ func (tm *tracerMessTest) setup(t *testing.T, tracer *internal.MockTracer) { | ||||
|  | ||||
| func (tm *tracerMessTest) check(t *testing.T, tracer *internal.MockTracer) { | ||||
| 	globalOtTracer := ot.GlobalTracer() | ||||
| 	globalOtelTracer := oteltrace.GlobalTracer() | ||||
| 	globalOtelTracer := oteltrace.GlobalProvider().GetTracer("") | ||||
| 	if len(tm.recordedOTSpanTracers) != 3 { | ||||
| 		t.Errorf("Expected 3 recorded OpenTracing tracers from spans, got %d", len(tm.recordedOTSpanTracers)) | ||||
| 	} | ||||
| @@ -537,7 +537,8 @@ func min(a, b int) int { | ||||
| } | ||||
|  | ||||
| func runOtelOTOtel(t *testing.T, ctx context.Context, name string, callback func(*testing.T, context.Context)) { | ||||
| 	ctx, span := oteltrace.Start(ctx, fmt.Sprintf("%s_Otel_OTOtel", name)) | ||||
| 	tr := oteltrace.GlobalProvider().GetTracer("") | ||||
| 	ctx, span := tr.Start(ctx, fmt.Sprintf("%s_Otel_OTOtel", name)) | ||||
| 	defer span.End() | ||||
| 	callback(t, ctx) | ||||
| 	func(ctx2 context.Context) { | ||||
| @@ -545,7 +546,7 @@ func runOtelOTOtel(t *testing.T, ctx context.Context, name string, callback func | ||||
| 		defer span.Finish() | ||||
| 		callback(t, ctx2) | ||||
| 		func(ctx3 context.Context) { | ||||
| 			ctx3, span := oteltrace.Start(ctx3, fmt.Sprintf("%sOtelOT_Otel_", name)) | ||||
| 			ctx3, span := tr.Start(ctx3, fmt.Sprintf("%sOtelOT_Otel_", name)) | ||||
| 			defer span.End() | ||||
| 			callback(t, ctx3) | ||||
| 		}(ctx2) | ||||
| @@ -553,11 +554,12 @@ func runOtelOTOtel(t *testing.T, ctx context.Context, name string, callback func | ||||
| } | ||||
|  | ||||
| func runOTOtelOT(t *testing.T, ctx context.Context, name string, callback func(*testing.T, context.Context)) { | ||||
| 	tr := oteltrace.GlobalProvider().GetTracer("") | ||||
| 	span, ctx := ot.StartSpanFromContext(ctx, fmt.Sprintf("%s_OT_OtelOT", name)) | ||||
| 	defer span.Finish() | ||||
| 	callback(t, ctx) | ||||
| 	func(ctx2 context.Context) { | ||||
| 		ctx2, span := oteltrace.Start(ctx2, fmt.Sprintf("%sOT_Otel_OT", name)) | ||||
| 		ctx2, span := tr.Start(ctx2, fmt.Sprintf("%sOT_Otel_OT", name)) | ||||
| 		defer span.End() | ||||
| 		callback(t, ctx2) | ||||
| 		func(ctx3 context.Context) { | ||||
|   | ||||
| @@ -19,11 +19,14 @@ import ( | ||||
| ) | ||||
|  | ||||
| // NewTracerPair is a utility function that creates a BridgeTracer | ||||
| // that forwards the calls to the WrapperTracer that wraps the passed | ||||
| // tracer. | ||||
| func NewTracerPair(tracer oteltrace.Tracer) (*BridgeTracer, *WrapperTracer) { | ||||
| // and a WrapperProvider. WrapperProvider creates a single instance of | ||||
| // WrapperTracer. The BridgeTracer forwards the calls to the WrapperTracer | ||||
| // that wraps the passed tracer. BridgeTracer and WrapperProvider are returned to | ||||
| // the caller and the caller is expected to register BridgeTracer with opentracing and | ||||
| // WrapperProvider with opentelemetry. | ||||
| func NewTracerPair(tracer oteltrace.Tracer) (*BridgeTracer, *WrapperProvider) { | ||||
| 	bridgeTracer := NewBridgeTracer() | ||||
| 	wrapperTracer := NewWrapperTracer(bridgeTracer, tracer) | ||||
| 	bridgeTracer.SetOpenTelemetryTracer(wrapperTracer) | ||||
| 	return bridgeTracer, wrapperTracer | ||||
| 	wrapperProvider := NewWrappedProvider(bridgeTracer, tracer) | ||||
| 	bridgeTracer.SetOpenTelemetryTracer(wrapperProvider.GetTracer("")) | ||||
| 	return bridgeTracer, wrapperProvider | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,25 @@ import ( | ||||
| 	migration "go.opentelemetry.io/experimental/bridge/opentracing/migration" | ||||
| ) | ||||
|  | ||||
| type WrapperProvider struct { | ||||
| 	wTracer *WrapperTracer | ||||
| } | ||||
|  | ||||
| var _ oteltrace.Provider = (*WrapperProvider)(nil) | ||||
|  | ||||
| // GetTracer returns the WrapperTracer associated with the WrapperProvider. | ||||
| func (p *WrapperProvider) GetTracer(name string) oteltrace.Tracer { | ||||
| 	return p.wTracer | ||||
| } | ||||
|  | ||||
| // WrapperProvider creates a new trace provider that creates a single | ||||
| // instance of WrapperTracer that wraps OpenTelemetry tracer. | ||||
| func NewWrappedProvider(bridge *BridgeTracer, tracer oteltrace.Tracer) *WrapperProvider { | ||||
| 	return &WrapperProvider{ | ||||
| 		wTracer: NewWrapperTracer(bridge, tracer), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WrapperTracer is a wrapper around an OpenTelemetry tracer. It | ||||
| // mostly forwards the calls to the wrapped tracer, but also does some | ||||
| // extra steps like setting up a context with the active OpenTracing | ||||
|   | ||||
| @@ -25,13 +25,11 @@ import ( | ||||
|  | ||||
| 	apitrace "go.opentelemetry.io/api/trace" | ||||
| 	"go.opentelemetry.io/exporter/trace/jaeger" | ||||
| 	"go.opentelemetry.io/sdk/trace" | ||||
| 	sdktrace "go.opentelemetry.io/sdk/trace" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	trace.Register() | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| // initTracer creates a new trace provider instance and registers it as global trace provider. | ||||
| func initTracer() func() { | ||||
| 	// Create Jaeger Exporter | ||||
| 	exporter, err := jaeger.NewExporter( | ||||
| 		jaeger.WithCollectorEndpoint("http://localhost:14268/api/traces"), | ||||
| @@ -52,17 +50,33 @@ func main() { | ||||
| 	// For demoing purposes, always sample. In a production application, you should | ||||
| 	// configure this to a trace.ProbabilitySampler set at the desired | ||||
| 	// probability. | ||||
| 	trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) | ||||
| 	tp, err := sdktrace.NewProvider( | ||||
| 		sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||||
| 		sdktrace.WithSyncer(exporter)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	apitrace.SetGlobalProvider(tp) | ||||
| 	return func() { | ||||
| 		exporter.Flush() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 	ctx, span := apitrace.GlobalTracer().Start(ctx, "/foo") | ||||
| func main() { | ||||
| 	fn := initTracer() | ||||
| 	defer fn() | ||||
|  | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	tr := apitrace.GlobalProvider().GetTracer("component-main") | ||||
| 	ctx, span := tr.Start(ctx, "/foo") | ||||
| 	bar(ctx) | ||||
| 	span.End() | ||||
|  | ||||
| 	exporter.Flush() | ||||
| } | ||||
|  | ||||
| func bar(ctx context.Context) { | ||||
| 	_, span := apitrace.GlobalTracer().Start(ctx, "/bar") | ||||
| 	tr := apitrace.GlobalProvider().GetTracer("component-bar") | ||||
| 	_, span := tr.Start(ctx, "/bar") | ||||
| 	defer span.End() | ||||
|  | ||||
| 	// Do bar... | ||||
|   | ||||
| @@ -42,6 +42,8 @@ type clientTracer struct { | ||||
| 	context.Context | ||||
| 	httptrace.ClientTrace | ||||
|  | ||||
| 	tr trace.Tracer | ||||
|  | ||||
| 	levels map[string]trace.Span | ||||
| 	root   trace.Span | ||||
| 	mtx    sync.Mutex | ||||
| @@ -52,12 +54,13 @@ func newClientTracer(ctx context.Context) *clientTracer { | ||||
| 		Context: ctx, | ||||
| 		levels:  make(map[string]trace.Span), | ||||
| 	} | ||||
| 	ct.tr = trace.GlobalProvider().GetTracer("go.opentelemetry.io/plugin/httptrace") | ||||
| 	ct.open("http.request") | ||||
| 	return ct | ||||
| } | ||||
|  | ||||
| func (ct *clientTracer) open(name string, attrs ...core.KeyValue) { | ||||
| 	_, sp := trace.Start(ct.Context, name, trace.WithAttributes(attrs...)) | ||||
| 	_, sp := ct.tr.Start(ct.Context, name, trace.WithAttributes(attrs...)) | ||||
| 	ct.mtx.Lock() | ||||
| 	defer ct.mtx.Unlock() | ||||
| 	if ct.root == nil { | ||||
|   | ||||
| @@ -129,7 +129,7 @@ func WithMessageEvents(events ...event) Option { | ||||
| func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler { | ||||
| 	h := Handler{handler: handler, operation: operation} | ||||
| 	defaultOpts := []Option{ | ||||
| 		WithTracer(trace.GlobalTracer()), | ||||
| 		WithTracer(trace.GlobalProvider().GetTracer("go.opentelemtry.io/plugin/othttp")), | ||||
| 		WithPropagator(prop.HTTPTraceContextPropagator{}), | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -44,22 +44,18 @@ func ExampleNewHandler() { | ||||
| 	a painting | ||||
| 	*/ | ||||
|  | ||||
| 	//import sdktrace "go.opentelemetry.io/sdk/trace" | ||||
| 	sdktrace.Register() | ||||
|  | ||||
| 	// Write spans to stdout | ||||
| 	exporter, err := stdout.NewExporter(stdout.Options{PrettyPrint: true}) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Wrap stdout exporter with SimpleSpanProcessor and register the processor. | ||||
| 	ssp := sdktrace.NewSimpleSpanProcessor(exporter) | ||||
| 	sdktrace.RegisterSpanProcessor(ssp) | ||||
|  | ||||
| 	// For the example, use sdktrace.AlwaysSample sampler to sample all traces. | ||||
| 	// In a production application, use sdktrace.ProbabilitySampler with a desired probability. | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||||
| 		sdktrace.WithSyncer(exporter)) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	trace.SetGlobalProvider(tp) | ||||
|  | ||||
| 	figureOutName := func(ctx context.Context, s string) (string, error) { | ||||
| 		pp := strings.SplitN(s, "/", 2) | ||||
|   | ||||
| @@ -51,7 +51,6 @@ func BenchmarkExtractB3(b *testing.B) { | ||||
| 			tests:        extractInvalidB3SingleHeader, | ||||
| 		}, | ||||
| 	} | ||||
| 	trace.SetGlobalTracer(&mocktrace.MockTracer{}) | ||||
|  | ||||
| 	for _, tg := range testGroup { | ||||
| 		propagator := propagation.HTTPB3Propagator{tg.singleHeader} | ||||
| @@ -95,7 +94,6 @@ func BenchmarkInjectB3(b *testing.B) { | ||||
| 		Sampled:     false, | ||||
| 		StartSpanID: &id, | ||||
| 	} | ||||
| 	trace.SetGlobalTracer(mockTracer) | ||||
|  | ||||
| 	for _, tg := range testGroup { | ||||
| 		id = 0 | ||||
|   | ||||
| @@ -53,7 +53,6 @@ func TestExtractB3(t *testing.T) { | ||||
| 			tests:        extractInvalidB3SingleHeader, | ||||
| 		}, | ||||
| 	} | ||||
| 	trace.SetGlobalTracer(&mocktrace.MockTracer{}) | ||||
|  | ||||
| 	for _, tg := range testGroup { | ||||
| 		propagator := propagation.HTTPB3Propagator{tg.singleHeader} | ||||
| @@ -97,7 +96,6 @@ func TestInjectB3(t *testing.T) { | ||||
| 		Sampled:     false, | ||||
| 		StartSpanID: &id, | ||||
| 	} | ||||
| 	trace.SetGlobalTracer(mockTracer) | ||||
|  | ||||
| 	for _, tg := range testGroup { | ||||
| 		id = 0 | ||||
|   | ||||
| @@ -36,7 +36,6 @@ var ( | ||||
| ) | ||||
|  | ||||
| func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { | ||||
| 	trace.SetGlobalTracer(&mocktrace.MockTracer{}) | ||||
| 	var propagator propagation.HTTPTraceContextPropagator | ||||
| 	tests := []struct { | ||||
| 		name   string | ||||
| @@ -130,7 +129,6 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestExtractInvalidTraceContextFromHTTPReq(t *testing.T) { | ||||
| 	trace.SetGlobalTracer(&mocktrace.MockTracer{}) | ||||
| 	var propagator propagation.HTTPTraceContextPropagator | ||||
| 	wantSc := core.EmptySpanContext() | ||||
| 	tests := []struct { | ||||
| @@ -279,7 +277,6 @@ func TestInjectTraceContextToHTTPReq(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestExtractValidDistributedContextFromHTTPReq(t *testing.T) { | ||||
| 	trace.SetGlobalTracer(&mocktrace.MockTracer{}) | ||||
| 	propagator := propagation.HTTPTraceContextPropagator{} | ||||
| 	tests := []struct { | ||||
| 		name    string | ||||
| @@ -368,7 +365,6 @@ func TestExtractValidDistributedContextFromHTTPReq(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestExtractInvalidDistributedContextFromHTTPReq(t *testing.T) { | ||||
| 	trace.SetGlobalTracer(&mocktrace.MockTracer{}) | ||||
| 	propagator := propagation.HTTPTraceContextPropagator{} | ||||
| 	tests := []struct { | ||||
| 		name   string | ||||
|   | ||||
| @@ -62,11 +62,6 @@ func (t *testBatchExporter) get(idx int) *export.SpanData { | ||||
|  | ||||
| var _ export.SpanBatcher = (*testBatchExporter)(nil) | ||||
|  | ||||
| func init() { | ||||
| 	sdktrace.Register() | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| } | ||||
|  | ||||
| func TestNewBatchSpanProcessorWithNilExporter(t *testing.T) { | ||||
| 	_, err := sdktrace.NewBatchSpanProcessor(nil) | ||||
| 	if err == nil { | ||||
| @@ -143,13 +138,15 @@ func TestNewBatchSpanProcessorWithOptions(t *testing.T) { | ||||
| 	} | ||||
| 	for _, option := range options { | ||||
| 		te := testBatchExporter{} | ||||
| 		tp := basicProvider(t) | ||||
| 		ssp := createAndRegisterBatchSP(t, option, &te) | ||||
| 		if ssp == nil { | ||||
| 			t.Errorf("%s: Error creating new instance of BatchSpanProcessor\n", option.name) | ||||
| 		} | ||||
| 		sdktrace.RegisterSpanProcessor(ssp) | ||||
| 		tp.RegisterSpanProcessor(ssp) | ||||
| 		tr := tp.GetTracer("BatchSpanProcessorWithOptions") | ||||
|  | ||||
| 		generateSpan(t, option) | ||||
| 		generateSpan(t, tr, option) | ||||
|  | ||||
| 		time.Sleep(option.waitTime) | ||||
|  | ||||
| @@ -172,7 +169,7 @@ func TestNewBatchSpanProcessorWithOptions(t *testing.T) { | ||||
| 		if wantTraceID != gotTraceID { | ||||
| 			t.Errorf("%s: first exported span: got %+v, want %+v\n", option.name, gotTraceID, wantTraceID) | ||||
| 		} | ||||
| 		sdktrace.UnregisterSpanProcessor(ssp) | ||||
| 		tp.UnregisterSpanProcessor(ssp) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -181,16 +178,15 @@ func createAndRegisterBatchSP(t *testing.T, option testOption, te *testBatchExpo | ||||
| 	if ssp == nil { | ||||
| 		t.Errorf("%s: Error creating new instance of BatchSpanProcessor, error: %v\n", option.name, err) | ||||
| 	} | ||||
| 	sdktrace.RegisterSpanProcessor(ssp) | ||||
| 	return ssp | ||||
| } | ||||
|  | ||||
| func generateSpan(t *testing.T, option testOption) { | ||||
| func generateSpan(t *testing.T, tr apitrace.Tracer, option testOption) { | ||||
| 	sc := getSpanContext() | ||||
|  | ||||
| 	for i := 0; i < option.genNumSpans; i++ { | ||||
| 		sc.TraceID.High = uint64(i + 1) | ||||
| 		_, span := apitrace.GlobalTracer().Start(context.Background(), option.name, apitrace.ChildOf(sc)) | ||||
| 		_, span := tr.Start(context.Background(), option.name, apitrace.ChildOf(sc)) | ||||
| 		span.End() | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package trace | ||||
| package trace_test | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| @@ -20,10 +20,12 @@ import ( | ||||
|  | ||||
| 	"go.opentelemetry.io/api/core" | ||||
| 	"go.opentelemetry.io/api/key" | ||||
| 	apitrace "go.opentelemetry.io/api/trace" | ||||
| 	sdktrace "go.opentelemetry.io/sdk/trace" | ||||
| ) | ||||
|  | ||||
| func BenchmarkStartEndSpan(b *testing.B) { | ||||
| 	t := tracer{} | ||||
| 	t := getTracer(b, "Benchmark StartEndSpan") | ||||
|  | ||||
| 	traceBenchmark(b, func(b *testing.B) { | ||||
| 		ctx := context.Background() | ||||
| @@ -36,7 +38,7 @@ func BenchmarkStartEndSpan(b *testing.B) { | ||||
| } | ||||
|  | ||||
| func BenchmarkSpanWithAttributes_4(b *testing.B) { | ||||
| 	t := tracer{} | ||||
| 	t := getTracer(b, "Benchmark Start With 4 Attributes") | ||||
|  | ||||
| 	traceBenchmark(b, func(b *testing.B) { | ||||
| 		ctx := context.Background() | ||||
| @@ -56,7 +58,7 @@ func BenchmarkSpanWithAttributes_4(b *testing.B) { | ||||
| } | ||||
|  | ||||
| func BenchmarkSpanWithAttributes_8(b *testing.B) { | ||||
| 	t := tracer{} | ||||
| 	t := getTracer(b, "Benchmark Start With 8 Attributes") | ||||
|  | ||||
| 	traceBenchmark(b, func(b *testing.B) { | ||||
| 		ctx := context.Background() | ||||
| @@ -80,7 +82,7 @@ func BenchmarkSpanWithAttributes_8(b *testing.B) { | ||||
| } | ||||
|  | ||||
| func BenchmarkSpanWithAttributes_all(b *testing.B) { | ||||
| 	t := tracer{} | ||||
| 	t := getTracer(b, "Benchmark Start With all Attribute types") | ||||
|  | ||||
| 	traceBenchmark(b, func(b *testing.B) { | ||||
| 		ctx := context.Background() | ||||
| @@ -107,7 +109,7 @@ func BenchmarkSpanWithAttributes_all(b *testing.B) { | ||||
| } | ||||
|  | ||||
| func BenchmarkSpanWithAttributes_all_2x(b *testing.B) { | ||||
| 	t := tracer{} | ||||
| 	t := getTracer(b, "Benchmark Start With all Attributes types twice") | ||||
| 	traceBenchmark(b, func(b *testing.B) { | ||||
| 		ctx := context.Background() | ||||
| 		b.ResetTimer() | ||||
| @@ -171,12 +173,18 @@ func BenchmarkSpanID_DotString(b *testing.B) { | ||||
| func traceBenchmark(b *testing.B, fn func(*testing.B)) { | ||||
| 	b.Run("AlwaysSample", func(b *testing.B) { | ||||
| 		b.ReportAllocs() | ||||
| 		ApplyConfig(Config{DefaultSampler: AlwaysSample()}) | ||||
| 		fn(b) | ||||
| 	}) | ||||
| 	b.Run("NeverSample", func(b *testing.B) { | ||||
| 		b.ReportAllocs() | ||||
| 		ApplyConfig(Config{DefaultSampler: NeverSample()}) | ||||
| 		fn(b) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func getTracer(b *testing.B, name string) apitrace.Tracer { | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(testConfig)) | ||||
| 	if err != nil { | ||||
| 		b.Fatalf("Failed to create trace provider for test %s\n", name) | ||||
| 	} | ||||
| 	return tp.GetTracer(name) | ||||
| } | ||||
| @@ -15,8 +15,6 @@ | ||||
| package trace | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
|  | ||||
| 	"go.opentelemetry.io/sdk/trace/internal" | ||||
| ) | ||||
|  | ||||
| @@ -38,8 +36,6 @@ type Config struct { | ||||
| 	MaxLinksPerSpan int | ||||
| } | ||||
|  | ||||
| var configWriteMu sync.Mutex | ||||
|  | ||||
| const ( | ||||
| 	// DefaultMaxEventsPerSpan is default max number of message events per span | ||||
| 	DefaultMaxEventsPerSpan = 128 | ||||
| @@ -50,28 +46,3 @@ const ( | ||||
| 	// DefaultMaxLinksPerSpan is default max number of links per span | ||||
| 	DefaultMaxLinksPerSpan = 32 | ||||
| ) | ||||
|  | ||||
| // ApplyConfig applies changes to the global tracing configuration. | ||||
| // | ||||
| // Fields not provided in the given config are going to be preserved. | ||||
| func ApplyConfig(cfg Config) { | ||||
| 	configWriteMu.Lock() | ||||
| 	defer configWriteMu.Unlock() | ||||
| 	c := *config.Load().(*Config) | ||||
| 	if cfg.DefaultSampler != nil { | ||||
| 		c.DefaultSampler = cfg.DefaultSampler | ||||
| 	} | ||||
| 	if cfg.IDGenerator != nil { | ||||
| 		c.IDGenerator = cfg.IDGenerator | ||||
| 	} | ||||
| 	if cfg.MaxEventsPerSpan > 0 { | ||||
| 		c.MaxEventsPerSpan = cfg.MaxEventsPerSpan | ||||
| 	} | ||||
| 	if cfg.MaxAttributesPerSpan > 0 { | ||||
| 		c.MaxAttributesPerSpan = cfg.MaxAttributesPerSpan | ||||
| 	} | ||||
| 	if cfg.MaxLinksPerSpan > 0 { | ||||
| 		c.MaxLinksPerSpan = cfg.MaxLinksPerSpan | ||||
| 	} | ||||
| 	config.Store(&c) | ||||
| } | ||||
|   | ||||
| @@ -1,81 +0,0 @@ | ||||
| // Copyright 2019, OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package trace | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestApplyConfig(t *testing.T) { | ||||
| 	testCfgs := []Config{ | ||||
| 		{}, | ||||
| 		{ | ||||
| 			MaxAttributesPerSpan: 1, | ||||
| 			MaxEventsPerSpan:     3, | ||||
| 			MaxLinksPerSpan:      4, | ||||
| 		}, | ||||
| 		{ | ||||
| 			MaxAttributesPerSpan: -1, | ||||
| 			MaxEventsPerSpan:     -3, | ||||
| 			MaxLinksPerSpan:      5, | ||||
| 		}} | ||||
| 	cfg := config.Load().(*Config) | ||||
| 	wantCfgs := []Config{ | ||||
| 		{ | ||||
| 			DefaultSampler:       cfg.DefaultSampler, | ||||
| 			IDGenerator:          cfg.IDGenerator, | ||||
| 			MaxAttributesPerSpan: DefaultMaxAttributesPerSpan, | ||||
| 			MaxEventsPerSpan:     DefaultMaxEventsPerSpan, | ||||
| 			MaxLinksPerSpan:      DefaultMaxLinksPerSpan, | ||||
| 		}, | ||||
| 		{ | ||||
| 			DefaultSampler:       cfg.DefaultSampler, | ||||
| 			IDGenerator:          cfg.IDGenerator, | ||||
| 			MaxAttributesPerSpan: 1, | ||||
| 			MaxEventsPerSpan:     3, | ||||
| 			MaxLinksPerSpan:      4, | ||||
| 		}, | ||||
| 		{ | ||||
| 			DefaultSampler:       cfg.DefaultSampler, | ||||
| 			IDGenerator:          cfg.IDGenerator, | ||||
| 			MaxAttributesPerSpan: 1, | ||||
| 			MaxEventsPerSpan:     3, | ||||
| 			MaxLinksPerSpan:      5, | ||||
| 		}} | ||||
|  | ||||
| 	for i, newCfg := range testCfgs { | ||||
| 		ApplyConfig(newCfg) | ||||
| 		gotCfg := config.Load().(*Config) | ||||
| 		wantCfg := wantCfgs[i] | ||||
|  | ||||
| 		if got, want := reflect.ValueOf(gotCfg.DefaultSampler).Pointer(), reflect.ValueOf(wantCfg.DefaultSampler).Pointer(); got != want { | ||||
| 			t.Fatalf("testId = %d config.DefaultSampler = %#v; want %#v", i, got, want) | ||||
| 		} | ||||
| 		if got, want := gotCfg.IDGenerator, wantCfg.IDGenerator; got != want { | ||||
| 			t.Fatalf("testId = %d config.IDGenerator = %#v; want %#v", i, got, want) | ||||
| 		} | ||||
| 		if got, want := gotCfg.MaxAttributesPerSpan, wantCfg.MaxAttributesPerSpan; got != want { | ||||
| 			t.Fatalf("testId = %d config.MaxAttributesPerSpan = %#v; want %#v", i, got, want) | ||||
| 		} | ||||
| 		if got, want := gotCfg.MaxLinksPerSpan, wantCfg.MaxLinksPerSpan; got != want { | ||||
| 			t.Fatalf("testId = %d config.MaxLinksPerSpan = %#v; want %#v", i, got, want) | ||||
| 		} | ||||
| 		if got, want := gotCfg.MaxEventsPerSpan, wantCfg.MaxEventsPerSpan; got != want { | ||||
| 			t.Fatalf("testId = %d config.MaxEventsPerSpan = %#v; want %#v", i, got, want) | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										184
									
								
								sdk/trace/provider.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								sdk/trace/provider.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| // Copyright 2019, OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package trace | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
|  | ||||
| 	"go.opentelemetry.io/sdk/export" | ||||
|  | ||||
| 	apitrace "go.opentelemetry.io/api/trace" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	defaultTracerName = "go.opentelemetry.io/sdk/tracer" | ||||
| ) | ||||
|  | ||||
| // ProviderOptions | ||||
| type ProviderOptions struct { | ||||
| 	syncers  []export.SpanSyncer | ||||
| 	batchers []export.SpanBatcher | ||||
| 	config   Config | ||||
| } | ||||
|  | ||||
| type ProviderOption func(*ProviderOptions) | ||||
|  | ||||
| type Provider struct { | ||||
| 	mu             sync.Mutex | ||||
| 	namedTracer    map[string]*tracer | ||||
| 	spanProcessors atomic.Value | ||||
| 	config         atomic.Value // access atomically | ||||
| } | ||||
|  | ||||
| var _ apitrace.Provider = &Provider{} | ||||
|  | ||||
| // NewProvider creates an instance of trace provider. Optional | ||||
| // parameter configures the provider with common options applicable | ||||
| // to all tracer instances that will be created by this provider. | ||||
| func NewProvider(opts ...ProviderOption) (*Provider, error) { | ||||
|  | ||||
| 	o := &ProviderOptions{} | ||||
|  | ||||
| 	for _, opt := range opts { | ||||
| 		opt(o) | ||||
| 	} | ||||
|  | ||||
| 	tp := &Provider{ | ||||
| 		namedTracer: make(map[string]*tracer), | ||||
| 	} | ||||
| 	tp.config.Store(&Config{ | ||||
| 		DefaultSampler:       ProbabilitySampler(defaultSamplingProbability), | ||||
| 		IDGenerator:          defIDGenerator(), | ||||
| 		MaxAttributesPerSpan: DefaultMaxAttributesPerSpan, | ||||
| 		MaxEventsPerSpan:     DefaultMaxEventsPerSpan, | ||||
| 		MaxLinksPerSpan:      DefaultMaxLinksPerSpan, | ||||
| 	}) | ||||
|  | ||||
| 	for _, syncer := range o.syncers { | ||||
| 		ssp := NewSimpleSpanProcessor(syncer) | ||||
| 		tp.RegisterSpanProcessor(ssp) | ||||
| 	} | ||||
|  | ||||
| 	for _, batcher := range o.batchers { | ||||
| 		bsp, err := NewBatchSpanProcessor(batcher) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		tp.RegisterSpanProcessor(bsp) | ||||
| 	} | ||||
|  | ||||
| 	tp.ApplyConfig(o.config) | ||||
|  | ||||
| 	return tp, nil | ||||
| } | ||||
|  | ||||
| func (p *Provider) GetTracer(name string) apitrace.Tracer { | ||||
| 	p.mu.Lock() | ||||
| 	defer p.mu.Unlock() | ||||
| 	if name == "" { | ||||
| 		name = defaultTracerName | ||||
| 	} | ||||
| 	t, ok := p.namedTracer[name] | ||||
| 	if !ok { | ||||
| 		t = &tracer{name: name, provider: p} | ||||
| 		p.namedTracer[name] = t | ||||
| 	} | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| // RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors | ||||
| func (p *Provider) RegisterSpanProcessor(s SpanProcessor) { | ||||
| 	p.mu.Lock() | ||||
| 	defer p.mu.Unlock() | ||||
| 	new := make(spanProcessorMap) | ||||
| 	if old, ok := p.spanProcessors.Load().(spanProcessorMap); ok { | ||||
| 		for k, v := range old { | ||||
| 			new[k] = v | ||||
| 		} | ||||
| 	} | ||||
| 	new[s] = &sync.Once{} | ||||
| 	p.spanProcessors.Store(new) | ||||
| } | ||||
|  | ||||
| // UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors | ||||
| func (p *Provider) UnregisterSpanProcessor(s SpanProcessor) { | ||||
| 	mu.Lock() | ||||
| 	defer mu.Unlock() | ||||
| 	new := make(spanProcessorMap) | ||||
| 	if old, ok := p.spanProcessors.Load().(spanProcessorMap); ok { | ||||
| 		for k, v := range old { | ||||
| 			new[k] = v | ||||
| 		} | ||||
| 	} | ||||
| 	if stopOnce, ok := new[s]; ok && stopOnce != nil { | ||||
| 		stopOnce.Do(func() { | ||||
| 			s.Shutdown() | ||||
| 		}) | ||||
| 	} | ||||
| 	delete(new, s) | ||||
| 	p.spanProcessors.Store(new) | ||||
| } | ||||
|  | ||||
| // ApplyConfig changes the configuration of the provider. | ||||
| // If a field in the configuration is empty or nil then its original value is preserved. | ||||
| func (p *Provider) ApplyConfig(cfg Config) { | ||||
| 	p.mu.Lock() | ||||
| 	defer p.mu.Unlock() | ||||
| 	c := *p.config.Load().(*Config) | ||||
| 	if cfg.DefaultSampler != nil { | ||||
| 		c.DefaultSampler = cfg.DefaultSampler | ||||
| 	} | ||||
| 	if cfg.IDGenerator != nil { | ||||
| 		c.IDGenerator = cfg.IDGenerator | ||||
| 	} | ||||
| 	if cfg.MaxEventsPerSpan > 0 { | ||||
| 		c.MaxEventsPerSpan = cfg.MaxEventsPerSpan | ||||
| 	} | ||||
| 	if cfg.MaxAttributesPerSpan > 0 { | ||||
| 		c.MaxAttributesPerSpan = cfg.MaxAttributesPerSpan | ||||
| 	} | ||||
| 	if cfg.MaxLinksPerSpan > 0 { | ||||
| 		c.MaxLinksPerSpan = cfg.MaxLinksPerSpan | ||||
| 	} | ||||
| 	p.config.Store(&c) | ||||
| } | ||||
|  | ||||
| // WithSyncer options appends the syncer to the existing list of Syncers. | ||||
| // This option can be used multiple times. | ||||
| // The Syncers are wrapped into SimpleSpanProcessors and registered | ||||
| // with the provider. | ||||
| func WithSyncer(syncer export.SpanSyncer) ProviderOption { | ||||
| 	return func(opts *ProviderOptions) { | ||||
| 		opts.syncers = append(opts.syncers, syncer) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WithBatch options appends the batcher to the existing list of Batchers. | ||||
| // This option can be used multiple times. | ||||
| // The Batchers are wrapped into BatchedSpanProcessors and registered | ||||
| // with the provider. | ||||
| func WithBatcher(batcher export.SpanBatcher) ProviderOption { | ||||
| 	return func(opts *ProviderOptions) { | ||||
| 		opts.batchers = append(opts.batchers, batcher) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WithConfig option sets the configuration to provider. | ||||
| func WithConfig(config Config) ProviderOption { | ||||
| 	return func(opts *ProviderOptions) { | ||||
| 		opts.config = config | ||||
| 	} | ||||
| } | ||||
| @@ -34,11 +34,6 @@ func (t *testExporter) ExportSpan(ctx context.Context, s *export.SpanData) { | ||||
|  | ||||
| var _ export.SpanSyncer = (*testExporter)(nil) | ||||
|  | ||||
| func init() { | ||||
| 	sdktrace.Register() | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| } | ||||
|  | ||||
| func TestNewSimpleSpanProcessor(t *testing.T) { | ||||
| 	ssp := sdktrace.NewSimpleSpanProcessor(&testExporter{}) | ||||
| 	if ssp == nil { | ||||
| @@ -54,12 +49,14 @@ func TestNewSimpleSpanProcessorWithNilExporter(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestSimpleSpanProcessorOnEnd(t *testing.T) { | ||||
| 	tp := basicProvider(t) | ||||
| 	te := testExporter{} | ||||
| 	ssp := sdktrace.NewSimpleSpanProcessor(&te) | ||||
| 	if ssp == nil { | ||||
| 		t.Errorf("Error creating new instance of SimpleSpanProcessor with nil Exporter\n") | ||||
| 	} | ||||
| 	sdktrace.RegisterSpanProcessor(ssp) | ||||
| 	tp.RegisterSpanProcessor(ssp) | ||||
| 	tr := tp.GetTracer("SimpleSpanProcessor") | ||||
| 	tid := core.TraceID{High: 0x0102030405060708, Low: 0x0102040810203040} | ||||
| 	sid := uint64(0x0102040810203040) | ||||
| 	sc := core.SpanContext{ | ||||
| @@ -67,7 +64,7 @@ func TestSimpleSpanProcessorOnEnd(t *testing.T) { | ||||
| 		SpanID:     sid, | ||||
| 		TraceFlags: 0x1, | ||||
| 	} | ||||
| 	_, span := apitrace.GlobalTracer().Start(context.Background(), "OnEnd", apitrace.ChildOf(sc)) | ||||
| 	_, span := tr.Start(context.Background(), "OnEnd", apitrace.ChildOf(sc)) | ||||
| 	span.End() | ||||
|  | ||||
| 	wantTraceID := tid | ||||
|   | ||||
| @@ -53,8 +53,8 @@ type span struct { | ||||
| 	//*spanStore | ||||
| 	endOnce sync.Once | ||||
|  | ||||
| 	executionTracerTaskEnd func()          // ends the execution tracer span | ||||
| 	tracer                 apitrace.Tracer // tracer used to create span. | ||||
| 	executionTracerTaskEnd func()  // ends the execution tracer span | ||||
| 	tracer                 *tracer // tracer used to create span. | ||||
| } | ||||
|  | ||||
| var _ apitrace.Span = &span{} | ||||
| @@ -123,7 +123,7 @@ func (s *span) End(options ...apitrace.EndOption) { | ||||
| 		opt(&opts) | ||||
| 	} | ||||
| 	s.endOnce.Do(func() { | ||||
| 		sps, _ := spanProcessors.Load().(spanProcessorMap) | ||||
| 		sps, _ := s.tracer.provider.spanProcessors.Load().(spanProcessorMap) | ||||
| 		mustExportOrProcess := len(sps) > 0 | ||||
| 		if mustExportOrProcess { | ||||
| 			sd := s.makeSpanData() | ||||
| @@ -172,7 +172,8 @@ func (s *span) SetName(name string) { | ||||
| 		// TODO: now what? | ||||
| 		return | ||||
| 	} | ||||
| 	s.data.Name = name | ||||
| 	spanName := s.tracer.spanNameWithPrefix(name) | ||||
| 	s.data.Name = spanName | ||||
| 	// SAMPLING | ||||
| 	noParent := s.data.ParentSpanID == 0 | ||||
| 	var ctx core.SpanContext | ||||
| @@ -187,8 +188,8 @@ func (s *span) SetName(name string) { | ||||
| 		noParent:     noParent, | ||||
| 		remoteParent: s.data.HasRemoteParent, | ||||
| 		parent:       ctx, | ||||
| 		name:         name, | ||||
| 		cfg:          config.Load().(*Config), | ||||
| 		name:         spanName, | ||||
| 		cfg:          s.tracer.provider.config.Load().(*Config), | ||||
| 		span:         s, | ||||
| 	} | ||||
| 	makeSamplingDecision(data) | ||||
| @@ -294,12 +295,12 @@ func (s *span) addChild() { | ||||
| 	s.mu.Unlock() | ||||
| } | ||||
|  | ||||
| func startSpanInternal(name string, parent core.SpanContext, remoteParent bool, o apitrace.SpanOptions) *span { | ||||
| func startSpanInternal(tr *tracer, name string, parent core.SpanContext, remoteParent bool, o apitrace.SpanOptions) *span { | ||||
| 	var noParent bool | ||||
| 	span := &span{} | ||||
| 	span.spanContext = parent | ||||
|  | ||||
| 	cfg := config.Load().(*Config) | ||||
| 	cfg := tr.provider.config.Load().(*Config) | ||||
|  | ||||
| 	if parent == core.EmptySpanContext() { | ||||
| 		span.spanContext.TraceID = cfg.IDGenerator.NewTraceID() | ||||
|   | ||||
| @@ -18,9 +18,7 @@ import ( | ||||
| 	"context" | ||||
| 	"testing" | ||||
|  | ||||
| 	apitrace "go.opentelemetry.io/api/trace" | ||||
| 	"go.opentelemetry.io/sdk/export" | ||||
| 	sdktrace "go.opentelemetry.io/sdk/trace" | ||||
| ) | ||||
|  | ||||
| type testSpanProcesor struct { | ||||
| @@ -29,11 +27,6 @@ type testSpanProcesor struct { | ||||
| 	shutdownCount int | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	sdktrace.Register() | ||||
| 	sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}) | ||||
| } | ||||
|  | ||||
| func (t *testSpanProcesor) OnStart(s *export.SpanData) { | ||||
| 	t.spansStarted = append(t.spansStarted, s) | ||||
| } | ||||
| @@ -48,10 +41,12 @@ func (t *testSpanProcesor) Shutdown() { | ||||
|  | ||||
| func TestRegisterSpanProcessort(t *testing.T) { | ||||
| 	name := "Register span processor before span starts" | ||||
| 	tp := basicProvider(t) | ||||
| 	sp := NewTestSpanProcessor() | ||||
| 	sdktrace.RegisterSpanProcessor(sp) | ||||
| 	defer sdktrace.UnregisterSpanProcessor(sp) | ||||
| 	_, span := apitrace.GlobalTracer().Start(context.Background(), "OnStart") | ||||
| 	tp.RegisterSpanProcessor(sp) | ||||
|  | ||||
| 	tr := tp.GetTracer("SpanProcessor") | ||||
| 	_, span := tr.Start(context.Background(), "OnStart") | ||||
| 	span.End() | ||||
| 	wantCount := 1 | ||||
| 	gotCount := len(sp.spansStarted) | ||||
| @@ -66,14 +61,17 @@ func TestRegisterSpanProcessort(t *testing.T) { | ||||
|  | ||||
| func TestUnregisterSpanProcessor(t *testing.T) { | ||||
| 	name := "Start span after unregistering span processor" | ||||
| 	tp := basicProvider(t) | ||||
| 	sp := NewTestSpanProcessor() | ||||
| 	sdktrace.RegisterSpanProcessor(sp) | ||||
| 	_, span := apitrace.GlobalTracer().Start(context.Background(), "OnStart") | ||||
| 	tp.RegisterSpanProcessor(sp) | ||||
|  | ||||
| 	tr := tp.GetTracer("SpanProcessor") | ||||
| 	_, span := tr.Start(context.Background(), "OnStart") | ||||
| 	span.End() | ||||
| 	sdktrace.UnregisterSpanProcessor(sp) | ||||
| 	tp.UnregisterSpanProcessor(sp) | ||||
|  | ||||
| 	// start another span after unregistering span processor. | ||||
| 	_, span = apitrace.GlobalTracer().Start(context.Background(), "Start span after unregister") | ||||
| 	_, span = tr.Start(context.Background(), "Start span after unregister") | ||||
| 	span.End() | ||||
|  | ||||
| 	wantCount := 1 | ||||
| @@ -90,10 +88,13 @@ func TestUnregisterSpanProcessor(t *testing.T) { | ||||
|  | ||||
| func TestUnregisterSpanProcessorWhileSpanIsActive(t *testing.T) { | ||||
| 	name := "Unregister span processor while span is active" | ||||
| 	tp := basicProvider(t) | ||||
| 	sp := NewTestSpanProcessor() | ||||
| 	sdktrace.RegisterSpanProcessor(sp) | ||||
| 	_, span := apitrace.GlobalTracer().Start(context.Background(), "OnStart") | ||||
| 	sdktrace.UnregisterSpanProcessor(sp) | ||||
| 	tp.RegisterSpanProcessor(sp) | ||||
|  | ||||
| 	tr := tp.GetTracer("SpanProcessor") | ||||
| 	_, span := tr.Start(context.Background(), "OnStart") | ||||
| 	tp.UnregisterSpanProcessor(sp) | ||||
|  | ||||
| 	span.End() | ||||
|  | ||||
| @@ -112,10 +113,12 @@ func TestUnregisterSpanProcessorWhileSpanIsActive(t *testing.T) { | ||||
|  | ||||
| func TestSpanProcessorShutdown(t *testing.T) { | ||||
| 	name := "Increment shutdown counter of a span processor" | ||||
| 	tp := basicProvider(t) | ||||
| 	sp := NewTestSpanProcessor() | ||||
| 	if sp == nil { | ||||
| 		t.Fatalf("Error creating new instance of TestSpanProcessor\n") | ||||
| 	} | ||||
| 	tp.RegisterSpanProcessor(sp) | ||||
|  | ||||
| 	wantCount := 1 | ||||
| 	sp.Shutdown() | ||||
| @@ -128,6 +131,7 @@ func TestSpanProcessorShutdown(t *testing.T) { | ||||
|  | ||||
| func TestMultipleUnregisterSpanProcessorCalls(t *testing.T) { | ||||
| 	name := "Increment shutdown counter after first UnregisterSpanProcessor call" | ||||
| 	tp := basicProvider(t) | ||||
| 	sp := NewTestSpanProcessor() | ||||
| 	if sp == nil { | ||||
| 		t.Fatalf("Error creating new instance of TestSpanProcessor\n") | ||||
| @@ -135,8 +139,8 @@ func TestMultipleUnregisterSpanProcessorCalls(t *testing.T) { | ||||
|  | ||||
| 	wantCount := 1 | ||||
|  | ||||
| 	sdktrace.RegisterSpanProcessor(sp) | ||||
| 	sdktrace.UnregisterSpanProcessor(sp) | ||||
| 	tp.RegisterSpanProcessor(sp) | ||||
| 	tp.UnregisterSpanProcessor(sp) | ||||
|  | ||||
| 	gotCount := sp.shutdownCount | ||||
| 	if wantCount != gotCount { | ||||
| @@ -144,7 +148,7 @@ func TestMultipleUnregisterSpanProcessorCalls(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Multiple UnregisterSpanProcessor should not trigger multiple Shutdown calls. | ||||
| 	sdktrace.UnregisterSpanProcessor(sp) | ||||
| 	tp.UnregisterSpanProcessor(sp) | ||||
|  | ||||
| 	gotCount = sp.shutdownCount | ||||
| 	if wantCount != gotCount { | ||||
|   | ||||
| @@ -18,15 +18,11 @@ import ( | ||||
| 	crand "crypto/rand" | ||||
| 	"encoding/binary" | ||||
| 	"math/rand" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
|  | ||||
| 	apitrace "go.opentelemetry.io/api/trace" | ||||
| 	"go.opentelemetry.io/sdk/trace/internal" | ||||
| ) | ||||
|  | ||||
| var config atomic.Value // access atomically | ||||
|  | ||||
| func init() { | ||||
| func defIDGenerator() internal.IDGenerator { | ||||
| 	gen := &defaultIDGenerator{} | ||||
| 	// initialize traceID and spanID generators. | ||||
| 	var rngSeed int64 | ||||
| @@ -37,27 +33,5 @@ func init() { | ||||
| 	} | ||||
| 	gen.traceIDRand = rand.New(rand.NewSource(rngSeed)) | ||||
| 	gen.spanIDInc |= 1 | ||||
|  | ||||
| 	config.Store(&Config{ | ||||
| 		DefaultSampler:       ProbabilitySampler(defaultSamplingProbability), | ||||
| 		IDGenerator:          gen, | ||||
| 		MaxAttributesPerSpan: DefaultMaxAttributesPerSpan, | ||||
| 		MaxEventsPerSpan:     DefaultMaxEventsPerSpan, | ||||
| 		MaxLinksPerSpan:      DefaultMaxLinksPerSpan, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| var tr *tracer | ||||
| var registerOnce sync.Once | ||||
|  | ||||
| // Register registers tracer implementation as default Tracer. | ||||
| // It creates single instance of tracer and registers it once. | ||||
| // Recommended use is to call Register in main() of an | ||||
| // application before calling any tracing api. | ||||
| func Register() apitrace.Tracer { | ||||
| 	registerOnce.Do(func() { | ||||
| 		tr = &tracer{} | ||||
| 		apitrace.SetGlobalTracer(tr) | ||||
| 	}) | ||||
| 	return tr | ||||
| } | ||||
| 	return gen | ||||
| } | ||||
| @@ -38,25 +38,19 @@ var ( | ||||
| 	sid = uint64(0x0102040810203040) | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	Register() | ||||
| 	setupDefaultSamplerConfig() | ||||
| } | ||||
|  | ||||
| func TestTracerFollowsExpectedAPIBehaviour(t *testing.T) { | ||||
| 	tp, err := NewProvider(WithConfig(Config{DefaultSampler: ProbabilitySampler(0)})) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("failed to create provider, err: %v\n", err) | ||||
| 	} | ||||
| 	harness := testharness.NewHarness(t) | ||||
| 	subjectFactory := func() trace.Tracer { | ||||
| 		return apitrace.GlobalTracer() | ||||
| 		return tp.GetTracer("") | ||||
| 	} | ||||
|  | ||||
| 	harness.TestTracer(subjectFactory) | ||||
| } | ||||
|  | ||||
| func setupDefaultSamplerConfig() { | ||||
| 	// no random sampling, but sample children of sampled spans. | ||||
| 	ApplyConfig(Config{DefaultSampler: ProbabilitySampler(0)}) | ||||
| } | ||||
|  | ||||
| type testExporter struct { | ||||
| 	spans []*export.SpanData | ||||
| } | ||||
| @@ -70,10 +64,10 @@ func TestSetName(t *testing.T) { | ||||
| 	fooSampler := Sampler(func(p SamplingParameters) SamplingDecision { | ||||
| 		samplerIsCalled = true | ||||
| 		t.Logf("called sampler for name %q", p.Name) | ||||
| 		return SamplingDecision{Sample: strings.HasPrefix(p.Name, "foo")} | ||||
| 		return SamplingDecision{Sample: strings.HasPrefix(p.Name, "SetName/foo")} | ||||
| 	}) | ||||
| 	ApplyConfig(Config{DefaultSampler: fooSampler}) | ||||
| 	defer setupDefaultSamplerConfig() | ||||
| 	tp, _ := NewProvider(WithConfig(Config{DefaultSampler: fooSampler})) | ||||
|  | ||||
| 	type testCase struct { | ||||
| 		name          string | ||||
| 		newName       string | ||||
| @@ -106,7 +100,7 @@ func TestSetName(t *testing.T) { | ||||
| 			sampledAfter:  true, | ||||
| 		}, | ||||
| 	} { | ||||
| 		span := startNamedSpan(tt.name) | ||||
| 		span := startNamedSpan(tp, "SetName", tt.name) | ||||
| 		if !samplerIsCalled { | ||||
| 			t.Errorf("%d: the sampler was not even called during span creation", idx) | ||||
| 		} | ||||
| @@ -127,7 +121,8 @@ func TestSetName(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestRecordingIsOff(t *testing.T) { | ||||
| 	_, span := apitrace.GlobalTracer().Start(context.Background(), "StartSpan") | ||||
| 	tp, _ := NewProvider() | ||||
| 	_, span := tp.GetTracer("Recording off").Start(context.Background(), "StartSpan") | ||||
| 	defer span.End() | ||||
| 	if span.IsRecording() == true { | ||||
| 		t.Error("new span is recording events") | ||||
| @@ -137,17 +132,20 @@ func TestRecordingIsOff(t *testing.T) { | ||||
| // TODO: [rghetia] enable sampling test when Sampling is working. | ||||
|  | ||||
| func TestStartSpanWithChildOf(t *testing.T) { | ||||
| 	tp, _ := NewProvider() | ||||
| 	tr := tp.GetTracer("SpanWith ChildOf") | ||||
|  | ||||
| 	sc1 := core.SpanContext{ | ||||
| 		TraceID:    tid, | ||||
| 		SpanID:     sid, | ||||
| 		TraceFlags: 0x0, | ||||
| 	} | ||||
| 	_, s1 := apitrace.GlobalTracer().Start(context.Background(), "span1-unsampled-parent1", apitrace.ChildOf(sc1)) | ||||
| 	_, s1 := tr.Start(context.Background(), "span1-unsampled-parent1", apitrace.ChildOf(sc1)) | ||||
| 	if err := checkChild(sc1, s1); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	_, s2 := apitrace.GlobalTracer().Start(context.Background(), "span2-unsampled-parent1", apitrace.ChildOf(sc1)) | ||||
| 	_, s2 := tr.Start(context.Background(), "span2-unsampled-parent1", apitrace.ChildOf(sc1)) | ||||
| 	if err := checkChild(sc1, s2); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| @@ -158,35 +156,38 @@ func TestStartSpanWithChildOf(t *testing.T) { | ||||
| 		TraceFlags: 0x1, | ||||
| 		//Tracestate:   testTracestate, | ||||
| 	} | ||||
| 	_, s3 := apitrace.GlobalTracer().Start(context.Background(), "span3-sampled-parent2", apitrace.ChildOf(sc2)) | ||||
| 	_, s3 := tr.Start(context.Background(), "span3-sampled-parent2", apitrace.ChildOf(sc2)) | ||||
| 	if err := checkChild(sc2, s3); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	ctx, s4 := apitrace.GlobalTracer().Start(context.Background(), "span4-sampled-parent2", apitrace.ChildOf(sc2)) | ||||
| 	ctx, s4 := tr.Start(context.Background(), "span4-sampled-parent2", apitrace.ChildOf(sc2)) | ||||
| 	if err := checkChild(sc2, s4); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	s4Sc := s4.SpanContext() | ||||
| 	_, s5 := apitrace.GlobalTracer().Start(ctx, "span5-implicit-childof-span4") | ||||
| 	_, s5 := tr.Start(ctx, "span5-implicit-childof-span4") | ||||
| 	if err := checkChild(s4Sc, s5); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestStartSpanWithFollowsFrom(t *testing.T) { | ||||
| 	tp, _ := NewProvider() | ||||
| 	tr := tp.GetTracer("SpanWith FollowsFrom") | ||||
|  | ||||
| 	sc1 := core.SpanContext{ | ||||
| 		TraceID:    tid, | ||||
| 		SpanID:     sid, | ||||
| 		TraceFlags: 0x0, | ||||
| 	} | ||||
| 	_, s1 := apitrace.GlobalTracer().Start(context.Background(), "span1-unsampled-parent1", apitrace.FollowsFrom(sc1)) | ||||
| 	_, s1 := tr.Start(context.Background(), "span1-unsampled-parent1", apitrace.FollowsFrom(sc1)) | ||||
| 	if err := checkChild(sc1, s1); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	_, s2 := apitrace.GlobalTracer().Start(context.Background(), "span2-unsampled-parent1", apitrace.FollowsFrom(sc1)) | ||||
| 	_, s2 := tr.Start(context.Background(), "span2-unsampled-parent1", apitrace.FollowsFrom(sc1)) | ||||
| 	if err := checkChild(sc1, s2); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| @@ -197,18 +198,18 @@ func TestStartSpanWithFollowsFrom(t *testing.T) { | ||||
| 		TraceFlags: 0x1, | ||||
| 		//Tracestate:   testTracestate, | ||||
| 	} | ||||
| 	_, s3 := apitrace.GlobalTracer().Start(context.Background(), "span3-sampled-parent2", apitrace.FollowsFrom(sc2)) | ||||
| 	_, s3 := tr.Start(context.Background(), "span3-sampled-parent2", apitrace.FollowsFrom(sc2)) | ||||
| 	if err := checkChild(sc2, s3); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	ctx, s4 := apitrace.GlobalTracer().Start(context.Background(), "span4-sampled-parent2", apitrace.FollowsFrom(sc2)) | ||||
| 	ctx, s4 := tr.Start(context.Background(), "span4-sampled-parent2", apitrace.FollowsFrom(sc2)) | ||||
| 	if err := checkChild(sc2, s4); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	s4Sc := s4.SpanContext() | ||||
| 	_, s5 := apitrace.GlobalTracer().Start(ctx, "span5-implicit-childof-span4") | ||||
| 	_, s5 := tr.Start(ctx, "span5-implicit-childof-span4") | ||||
| 	if err := checkChild(s4Sc, s5); err != nil { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
| @@ -217,9 +218,11 @@ func TestStartSpanWithFollowsFrom(t *testing.T) { | ||||
| // TODO: [rghetia] Equivalent of SpanKind Test. | ||||
|  | ||||
| func TestSetSpanAttributes(t *testing.T) { | ||||
| 	span := startSpan() | ||||
| 	te := &testExporter{} | ||||
| 	tp, _ := NewProvider(WithSyncer(te)) | ||||
| 	span := startSpan(tp, "SpanAttribute") | ||||
| 	span.SetAttribute(key.New("key1").String("value1")) | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -230,7 +233,7 @@ func TestSetSpanAttributes(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID: sid, | ||||
| 		Name:         "span0", | ||||
| 		Name:         "SpanAttribute/span0", | ||||
| 		Attributes: []core.KeyValue{{ | ||||
| 			Key:   core.Key("key1"), | ||||
| 			Value: core.Value{Type: core.STRING, String: "value1"}, | ||||
| @@ -243,15 +246,16 @@ func TestSetSpanAttributes(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestSetSpanAttributesOverLimit(t *testing.T) { | ||||
| 	te := &testExporter{} | ||||
| 	cfg := Config{MaxAttributesPerSpan: 2} | ||||
| 	ApplyConfig(cfg) | ||||
| 	tp, _ := NewProvider(WithConfig(cfg), WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan() | ||||
| 	span := startSpan(tp, "SpanAttributesOverLimit") | ||||
| 	span.SetAttribute(key.New("key1").String("value1")) | ||||
| 	span.SetAttribute(key.New("key2").String("value2")) | ||||
| 	span.SetAttribute(key.New("key1").String("value3")) // Replace key1. | ||||
| 	span.SetAttribute(key.New("key4").String("value4")) // Remove key2 and add key4 | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -262,7 +266,7 @@ func TestSetSpanAttributesOverLimit(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID: sid, | ||||
| 		Name:         "span0", | ||||
| 		Name:         "SpanAttributesOverLimit/span0", | ||||
| 		Attributes: []core.KeyValue{ | ||||
| 			{ | ||||
| 				Key:   core.Key("key1"), | ||||
| @@ -282,7 +286,10 @@ func TestSetSpanAttributesOverLimit(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestEvents(t *testing.T) { | ||||
| 	span := startSpan() | ||||
| 	te := &testExporter{} | ||||
| 	tp, _ := NewProvider(WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan(tp, "Events") | ||||
| 	k1v1 := key.New("key1").String("value1") | ||||
| 	k2v2 := key.New("key2").String("value2") | ||||
| 	k3v3 := key.New("key3").String("value3") | ||||
| @@ -292,7 +299,7 @@ func TestEvents(t *testing.T) { | ||||
| 		key.New("key2").String("value2"), | ||||
| 		key.New("key3").String("value3"), | ||||
| 	) | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -309,7 +316,7 @@ func TestEvents(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID:    sid, | ||||
| 		Name:            "span0", | ||||
| 		Name:            "Events/span0", | ||||
| 		HasRemoteParent: true, | ||||
| 		MessageEvents: []export.Event{ | ||||
| 			{Message: "foo", Attributes: []core.KeyValue{k1v1}}, | ||||
| @@ -322,9 +329,11 @@ func TestEvents(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestEventsOverLimit(t *testing.T) { | ||||
| 	te := &testExporter{} | ||||
| 	cfg := Config{MaxEventsPerSpan: 2} | ||||
| 	ApplyConfig(cfg) | ||||
| 	span := startSpan() | ||||
| 	tp, _ := NewProvider(WithConfig(cfg), WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan(tp, "EventsOverLimit") | ||||
| 	k1v1 := key.New("key1").String("value1") | ||||
| 	k2v2 := key.New("key2").String("value2") | ||||
| 	k3v3 := key.New("key3").String("value3") | ||||
| @@ -339,7 +348,7 @@ func TestEventsOverLimit(t *testing.T) { | ||||
| 		key.New("key2").String("value2"), | ||||
| 		key.New("key3").String("value3"), | ||||
| 	) | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -356,7 +365,7 @@ func TestEventsOverLimit(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID: sid, | ||||
| 		Name:         "span0", | ||||
| 		Name:         "EventsOverLimit/span0", | ||||
| 		MessageEvents: []export.Event{ | ||||
| 			{Message: "foo", Attributes: []core.KeyValue{k1v1}}, | ||||
| 			{Message: "bar", Attributes: []core.KeyValue{k2v2, k3v3}}, | ||||
| @@ -370,7 +379,10 @@ func TestEventsOverLimit(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestAddLinks(t *testing.T) { | ||||
| 	span := startSpan() | ||||
| 	te := &testExporter{} | ||||
| 	tp, _ := NewProvider(WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan(tp, "AddLinks") | ||||
| 	k1v1 := key.New("key1").String("value1") | ||||
| 	k2v2 := key.New("key2").String("value2") | ||||
|  | ||||
| @@ -382,7 +394,7 @@ func TestAddLinks(t *testing.T) { | ||||
| 	span.AddLink(link1) | ||||
| 	span.AddLink(link2) | ||||
|  | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -393,7 +405,7 @@ func TestAddLinks(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID:    sid, | ||||
| 		Name:            "span0", | ||||
| 		Name:            "AddLinks/span0", | ||||
| 		HasRemoteParent: true, | ||||
| 		Links: []apitrace.Link{ | ||||
| 			{SpanContext: sc1, Attributes: []core.KeyValue{k1v1}}, | ||||
| @@ -406,7 +418,10 @@ func TestAddLinks(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestLinks(t *testing.T) { | ||||
| 	span := startSpan() | ||||
| 	te := &testExporter{} | ||||
| 	tp, _ := NewProvider(WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan(tp, "Links") | ||||
| 	k1v1 := key.New("key1").String("value1") | ||||
| 	k2v2 := key.New("key2").String("value2") | ||||
| 	k3v3 := key.New("key3").String("value3") | ||||
| @@ -419,7 +434,7 @@ func TestLinks(t *testing.T) { | ||||
| 		key.New("key2").String("value2"), | ||||
| 		key.New("key3").String("value3"), | ||||
| 	) | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -430,7 +445,7 @@ func TestLinks(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID:    sid, | ||||
| 		Name:            "span0", | ||||
| 		Name:            "Links/span0", | ||||
| 		HasRemoteParent: true, | ||||
| 		Links: []apitrace.Link{ | ||||
| 			{SpanContext: sc1, Attributes: []core.KeyValue{k1v1}}, | ||||
| @@ -443,13 +458,15 @@ func TestLinks(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestLinksOverLimit(t *testing.T) { | ||||
| 	te := &testExporter{} | ||||
| 	cfg := Config{MaxLinksPerSpan: 2} | ||||
| 	ApplyConfig(cfg) | ||||
| 	tp, _ := NewProvider(WithConfig(cfg), WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan(tp, "LinksOverLimit") | ||||
| 	sc1 := core.SpanContext{TraceID: core.TraceID{High: 0x1, Low: 0x1}, SpanID: 0x3} | ||||
| 	sc2 := core.SpanContext{TraceID: core.TraceID{High: 0x1, Low: 0x2}, SpanID: 0x3} | ||||
| 	sc3 := core.SpanContext{TraceID: core.TraceID{High: 0x1, Low: 0x3}, SpanID: 0x3} | ||||
|  | ||||
| 	span := startSpan() | ||||
| 	k2v2 := key.New("key2").String("value2") | ||||
| 	k3v3 := key.New("key3").String("value3") | ||||
|  | ||||
| @@ -457,7 +474,7 @@ func TestLinksOverLimit(t *testing.T) { | ||||
| 	span.Link(sc2, key.New("key2").String("value2")) | ||||
| 	span.Link(sc3, key.New("key3").String("value3")) | ||||
|  | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -468,7 +485,7 @@ func TestLinksOverLimit(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID: sid, | ||||
| 		Name:         "span0", | ||||
| 		Name:         "LinksOverLimit/span0", | ||||
| 		Links: []apitrace.Link{ | ||||
| 			{SpanContext: sc2, Attributes: []core.KeyValue{k2v2}}, | ||||
| 			{SpanContext: sc3, Attributes: []core.KeyValue{k3v3}}, | ||||
| @@ -482,15 +499,18 @@ func TestLinksOverLimit(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestSetSpanName(t *testing.T) { | ||||
| 	want := "SpanName-1" | ||||
| 	_, span := apitrace.GlobalTracer().Start(context.Background(), want, | ||||
| 	te := &testExporter{} | ||||
| 	tp, _ := NewProvider(WithSyncer(te)) | ||||
|  | ||||
| 	want := "SetSpanName/SpanName-1" | ||||
| 	_, span := tp.GetTracer("SetSpanName").Start(context.Background(), "SpanName-1", | ||||
| 		apitrace.ChildOf(core.SpanContext{ | ||||
| 			TraceID:    tid, | ||||
| 			SpanID:     sid, | ||||
| 			TraceFlags: 1, | ||||
| 		}), | ||||
| 	) | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -501,9 +521,12 @@ func TestSetSpanName(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestSetSpanStatus(t *testing.T) { | ||||
| 	span := startSpan() | ||||
| 	te := &testExporter{} | ||||
| 	tp, _ := NewProvider(WithSyncer(te)) | ||||
|  | ||||
| 	span := startSpan(tp, "SpanStatus") | ||||
| 	span.SetStatus(codes.Canceled) | ||||
| 	got, err := endSpan(span) | ||||
| 	got, err := endSpan(te, span) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -514,7 +537,7 @@ func TestSetSpanStatus(t *testing.T) { | ||||
| 			TraceFlags: 0x1, | ||||
| 		}, | ||||
| 		ParentSpanID:    sid, | ||||
| 		Name:            "span0", | ||||
| 		Name:            "SpanStatus/span0", | ||||
| 		Status:          codes.Canceled, | ||||
| 		HasRemoteParent: true, | ||||
| 	} | ||||
| @@ -556,16 +579,16 @@ func checkChild(p core.SpanContext, apiSpan apitrace.Span) error { | ||||
|  | ||||
| // startSpan starts a span with a name "span0". See startNamedSpan for | ||||
| // details. | ||||
| func startSpan() apitrace.Span { | ||||
| 	return startNamedSpan("span0") | ||||
| func startSpan(tp *Provider, trName string) apitrace.Span { | ||||
| 	return startNamedSpan(tp, trName, "span0") | ||||
| } | ||||
|  | ||||
| // startNamed Span is a test utility func that starts a span with a | ||||
| // passed name and with ChildOf option.  remote span context contains | ||||
| // TraceFlags with sampled bit set. This allows the span to be | ||||
| // automatically sampled. | ||||
| func startNamedSpan(name string) apitrace.Span { | ||||
| 	_, span := apitrace.GlobalTracer().Start( | ||||
| func startNamedSpan(tp *Provider, trName, name string) apitrace.Span { | ||||
| 	_, span := tp.GetTracer(trName).Start( | ||||
| 		context.Background(), | ||||
| 		name, | ||||
| 		apitrace.ChildOf(remoteSpanContext()), | ||||
| @@ -583,7 +606,7 @@ func startNamedSpan(name string) apitrace.Span { | ||||
| // | ||||
| // It also does some basic tests on the span. | ||||
| // It also clears spanID in the export.SpanData to make the comparison easier. | ||||
| func endSpan(span apitrace.Span) (*export.SpanData, error) { | ||||
| func endSpan(te *testExporter, span apitrace.Span) (*export.SpanData, error) { | ||||
|  | ||||
| 	if !span.IsRecording() { | ||||
| 		return nil, fmt.Errorf("IsRecording: got false, want true") | ||||
| @@ -591,11 +614,7 @@ func endSpan(span apitrace.Span) (*export.SpanData, error) { | ||||
| 	if !span.SpanContext().IsSampled() { | ||||
| 		return nil, fmt.Errorf("IsSampled: got false, want true") | ||||
| 	} | ||||
| 	var te testExporter | ||||
| 	p := NewSimpleSpanProcessor(&te) | ||||
| 	RegisterSpanProcessor(p) | ||||
| 	span.End() | ||||
| 	UnregisterSpanProcessor(p) | ||||
| 	if len(te.spans) != 1 { | ||||
| 		return nil, fmt.Errorf("got exported spans %#v, want one span", te.spans) | ||||
| 	} | ||||
| @@ -630,11 +649,9 @@ func (f fakeExporter) ExportSpan(ctx context.Context, s *export.SpanData) { | ||||
|  | ||||
| func TestEndSpanTwice(t *testing.T) { | ||||
| 	spans := make(fakeExporter) | ||||
| 	p := NewSimpleSpanProcessor(&spans) | ||||
| 	RegisterSpanProcessor(p) | ||||
| 	defer UnregisterSpanProcessor(p) | ||||
| 	tp, _ := NewProvider(WithSyncer(spans)) | ||||
|  | ||||
| 	span := startSpan() | ||||
| 	span := startSpan(tp, "EndSpanTwice") | ||||
| 	span.End() | ||||
| 	span.End() | ||||
| 	if len(spans) != 1 { | ||||
| @@ -644,64 +661,61 @@ func TestEndSpanTwice(t *testing.T) { | ||||
|  | ||||
| func TestStartSpanAfterEnd(t *testing.T) { | ||||
| 	spans := make(fakeExporter) | ||||
| 	p := NewSimpleSpanProcessor(&spans) | ||||
| 	RegisterSpanProcessor(p) | ||||
| 	defer UnregisterSpanProcessor(p) | ||||
| 	tp, _ := NewProvider(WithConfig(Config{DefaultSampler: AlwaysSample()}), WithSyncer(spans)) | ||||
|  | ||||
| 	ctx, span0 := apitrace.GlobalTracer().Start(context.Background(), "parent", apitrace.ChildOf(remoteSpanContext())) | ||||
| 	ctx1, span1 := apitrace.GlobalTracer().Start(ctx, "span-1") | ||||
| 	tr := tp.GetTracer("SpanAfterEnd") | ||||
| 	ctx, span0 := tr.Start(context.Background(), "parent", apitrace.ChildOf(remoteSpanContext())) | ||||
| 	ctx1, span1 := tr.Start(ctx, "span-1") | ||||
| 	span1.End() | ||||
| 	// Start a new span with the context containing span-1 | ||||
| 	// even though span-1 is ended, we still add this as a new child of span-1 | ||||
| 	_, span2 := apitrace.GlobalTracer().Start(ctx1, "span-2") | ||||
| 	_, span2 := tr.Start(ctx1, "span-2") | ||||
| 	span2.End() | ||||
| 	span0.End() | ||||
| 	if got, want := len(spans), 3; got != want { | ||||
| 		t.Fatalf("len(%#v) = %d; want %d", spans, got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-1"].SpanContext.TraceID, spans["parent"].SpanContext.TraceID; got != want { | ||||
| 	if got, want := spans["SpanAfterEnd/span-1"].SpanContext.TraceID, spans["SpanAfterEnd/parent"].SpanContext.TraceID; got != want { | ||||
| 		t.Errorf("span-1.TraceID=%q; want %q", got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-2"].SpanContext.TraceID, spans["parent"].SpanContext.TraceID; got != want { | ||||
| 	if got, want := spans["SpanAfterEnd/span-2"].SpanContext.TraceID, spans["SpanAfterEnd/parent"].SpanContext.TraceID; got != want { | ||||
| 		t.Errorf("span-2.TraceID=%q; want %q", got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-1"].ParentSpanID, spans["parent"].SpanContext.SpanID; got != want { | ||||
| 	if got, want := spans["SpanAfterEnd/span-1"].ParentSpanID, spans["SpanAfterEnd/parent"].SpanContext.SpanID; got != want { | ||||
| 		t.Errorf("span-1.ParentSpanID=%q; want %q (parent.SpanID)", got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-2"].ParentSpanID, spans["span-1"].SpanContext.SpanID; got != want { | ||||
| 	if got, want := spans["SpanAfterEnd/span-2"].ParentSpanID, spans["SpanAfterEnd/span-1"].SpanContext.SpanID; got != want { | ||||
| 		t.Errorf("span-2.ParentSpanID=%q; want %q (span1.SpanID)", got, want) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestChildSpanCount(t *testing.T) { | ||||
| 	ApplyConfig(Config{DefaultSampler: AlwaysSample()}) | ||||
| 	spans := make(fakeExporter) | ||||
| 	p := NewSimpleSpanProcessor(&spans) | ||||
| 	RegisterSpanProcessor(p) | ||||
| 	defer UnregisterSpanProcessor(p) | ||||
| 	tp, _ := NewProvider(WithConfig(Config{DefaultSampler: AlwaysSample()}), WithSyncer(spans)) | ||||
|  | ||||
| 	ctx, span0 := apitrace.GlobalTracer().Start(context.Background(), "parent") | ||||
| 	ctx1, span1 := apitrace.GlobalTracer().Start(ctx, "span-1") | ||||
| 	_, span2 := apitrace.GlobalTracer().Start(ctx1, "span-2") | ||||
| 	tr := tp.GetTracer("ChidSpanCount") | ||||
| 	ctx, span0 := tr.Start(context.Background(), "parent") | ||||
| 	ctx1, span1 := tr.Start(ctx, "span-1") | ||||
| 	_, span2 := tr.Start(ctx1, "span-2") | ||||
| 	span2.End() | ||||
| 	span1.End() | ||||
|  | ||||
| 	_, span3 := apitrace.GlobalTracer().Start(ctx, "span-3") | ||||
| 	_, span3 := tr.Start(ctx, "span-3") | ||||
| 	span3.End() | ||||
| 	span0.End() | ||||
| 	if got, want := len(spans), 4; got != want { | ||||
| 		t.Fatalf("len(%#v) = %d; want %d", spans, got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-3"].ChildSpanCount, 0; got != want { | ||||
| 	if got, want := spans["ChidSpanCount/span-3"].ChildSpanCount, 0; got != want { | ||||
| 		t.Errorf("span-3.ChildSpanCount=%q; want %q", got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-2"].ChildSpanCount, 0; got != want { | ||||
| 	if got, want := spans["ChidSpanCount/span-2"].ChildSpanCount, 0; got != want { | ||||
| 		t.Errorf("span-2.ChildSpanCount=%q; want %q", got, want) | ||||
| 	} | ||||
| 	if got, want := spans["span-1"].ChildSpanCount, 1; got != want { | ||||
| 	if got, want := spans["ChidSpanCount/span-1"].ChildSpanCount, 1; got != want { | ||||
| 		t.Errorf("span-1.ChildSpanCount=%q; want %q", got, want) | ||||
| 	} | ||||
| 	if got, want := spans["parent"].ChildSpanCount, 2; got != want { | ||||
| 	if got, want := spans["ChidSpanCount/parent"].ChildSpanCount, 2; got != want { | ||||
| 		t.Errorf("parent.ChildSpanCount=%q; want %q", got, want) | ||||
| 	} | ||||
| } | ||||
| @@ -713,19 +727,21 @@ func TestNilSpanEnd(t *testing.T) { | ||||
|  | ||||
| func TestExecutionTracerTaskEnd(t *testing.T) { | ||||
| 	var n uint64 | ||||
| 	ApplyConfig(Config{DefaultSampler: NeverSample()}) | ||||
| 	tp, _ := NewProvider(WithConfig(Config{DefaultSampler: NeverSample()})) | ||||
| 	tr := tp.GetTracer("Execution Tracer Task End") | ||||
|  | ||||
| 	executionTracerTaskEnd := func() { | ||||
| 		atomic.AddUint64(&n, 1) | ||||
| 	} | ||||
|  | ||||
| 	var spans []*span | ||||
| 	_, apiSpan := apitrace.GlobalTracer().Start(context.Background(), "foo") | ||||
| 	_, apiSpan := tr.Start(context.Background(), "foo") | ||||
| 	s := apiSpan.(*span) | ||||
|  | ||||
| 	s.executionTracerTaskEnd = executionTracerTaskEnd | ||||
| 	spans = append(spans, s) // never sample | ||||
|  | ||||
| 	_, apiSpan = apitrace.GlobalTracer().Start( | ||||
| 	_, apiSpan = tr.Start( | ||||
| 		context.Background(), | ||||
| 		"foo", | ||||
| 		apitrace.ChildOf( | ||||
| @@ -740,8 +756,8 @@ func TestExecutionTracerTaskEnd(t *testing.T) { | ||||
| 	s.executionTracerTaskEnd = executionTracerTaskEnd | ||||
| 	spans = append(spans, s) // parent not sampled | ||||
|  | ||||
| 	ApplyConfig(Config{DefaultSampler: AlwaysSample()}) | ||||
| 	_, apiSpan = apitrace.GlobalTracer().Start(context.Background(), "foo") | ||||
| 	//tp.ApplyConfig(Config{DefaultSampler: AlwaysSample()}) | ||||
| 	_, apiSpan = tr.Start(context.Background(), "foo") | ||||
| 	s = apiSpan.(*span) | ||||
| 	s.executionTracerTaskEnd = executionTracerTaskEnd | ||||
| 	spans = append(spans, s) // always sample | ||||
| @@ -755,18 +771,17 @@ func TestExecutionTracerTaskEnd(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestCustomStartEndTime(t *testing.T) { | ||||
| 	var te testExporter | ||||
| 	tp, _ := NewProvider(WithSyncer(&te), WithConfig(Config{DefaultSampler: AlwaysSample()})) | ||||
|  | ||||
| 	startTime := time.Date(2019, time.August, 27, 14, 42, 0, 0, time.UTC) | ||||
| 	endTime := startTime.Add(time.Second * 20) | ||||
| 	_, span := apitrace.Start( | ||||
| 	_, span := tp.GetTracer("Custom Start and End time").Start( | ||||
| 		context.Background(), | ||||
| 		"testspan", | ||||
| 		apitrace.WithStartTime(startTime), | ||||
| 	) | ||||
| 	var te testExporter | ||||
| 	p := NewSimpleSpanProcessor(&te) | ||||
| 	RegisterSpanProcessor(p) | ||||
| 	span.End(apitrace.WithEndTime(endTime)) | ||||
| 	UnregisterSpanProcessor(p) | ||||
|  | ||||
| 	if len(te.spans) != 1 { | ||||
| 		t.Fatalf("got exported spans %#v, want one span", te.spans) | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import ( | ||||
| ) | ||||
|  | ||||
| type tracer struct { | ||||
| 	provider  *Provider | ||||
| 	name      string | ||||
| 	component string | ||||
| 	resources []core.KeyValue | ||||
| @@ -57,17 +58,18 @@ func (tr *tracer) Start(ctx context.Context, name string, o ...apitrace.SpanOpti | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	span := startSpanInternal(name, parent, remoteParent, opts) | ||||
| 	spanName := tr.spanNameWithPrefix(name) | ||||
| 	span := startSpanInternal(tr, spanName, parent, remoteParent, opts) | ||||
| 	span.tracer = tr | ||||
|  | ||||
| 	if span.IsRecording() { | ||||
| 		sps, _ := spanProcessors.Load().(spanProcessorMap) | ||||
| 		sps, _ := tr.provider.spanProcessors.Load().(spanProcessorMap) | ||||
| 		for sp := range sps { | ||||
| 			sp.OnStart(span.data) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ctx, end := startExecutionTracerTask(ctx, name) | ||||
| 	ctx, end := startExecutionTracerTask(ctx, spanName) | ||||
| 	span.executionTracerTaskEnd = end | ||||
| 	return apitrace.SetCurrentSpan(ctx, span), span | ||||
| } | ||||
| @@ -99,3 +101,10 @@ func (tr *tracer) WithComponent(component string) apitrace.Tracer { | ||||
| 	tr.component = component | ||||
| 	return tr | ||||
| } | ||||
|  | ||||
| func (tr *tracer) spanNameWithPrefix(name string) string { | ||||
| 	if tr.name != "" { | ||||
| 		return tr.name + "/" + name | ||||
| 	} | ||||
| 	return name | ||||
| } | ||||
|   | ||||
							
								
								
									
										31
									
								
								sdk/trace/util_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								sdk/trace/util_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // Copyright 2019, OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package trace_test | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	sdktrace "go.opentelemetry.io/sdk/trace" | ||||
| ) | ||||
|  | ||||
| var testConfig = sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()} | ||||
|  | ||||
| func basicProvider(t *testing.T) *sdktrace.Provider { | ||||
| 	tp, err := sdktrace.NewProvider(sdktrace.WithConfig(testConfig)) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("failed to create provider, err: %v\n", err) | ||||
| 	} | ||||
| 	return tp | ||||
| } | ||||
		Reference in New Issue
	
	Block a user