-
Notifications
You must be signed in to change notification settings - Fork 593
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add autoprop package to provide configuration of propagators with use…
…ful defaults and envar support (#2258) * Add autoprop module * Add example tests * Add unit tests for registry.go * Add unit test for NewTextMapPropagator * Add NewTextMapPropagator unit tests * Fix RegisterTextMapPropagator func name * Fix lint * Go import lint fix * Add dependabot entry * Add change to the changelog * Add autoprop to versions * Add setenv test func to support Go 1.16 * Fix spelling error in comment * Rename registry index field to names * Remove interface assertion * Fix lint * Update RegisterTextMapPropagator docs * Remove compile time assertion and test of impl * Upgrade to Go 1.17 as min supported version * Use T.Setenv instead of own setenv func * Panic on duplicate prop register * Check errs in registry_test
- Loading branch information
Showing
11 changed files
with
589 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package autoprop provides an OpenTelemetry TextMapPropagator creation | ||
// function. The OpenTelemetry specification states that the default | ||
// TextMapPropagator needs to be a no-operation implementation. The | ||
// opentelemetry-go project adheres to this requirement. However, for systems | ||
// that perform propagation this default is not ideal. This package provides a | ||
// TextMapPropagator with useful defaults (a combined TraceContext and Baggage | ||
// TextMapPropagator), and supports environment overrides using the | ||
// OTEL_PROPAGATORS environment variable. | ||
package autoprop // import "go.opentelemetry.io/contrib/propagators/autoprop" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package autoprop_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"sort" | ||
|
||
"go.opentelemetry.io/contrib/propagators/autoprop" | ||
"go.opentelemetry.io/contrib/propagators/b3" | ||
"go.opentelemetry.io/otel" | ||
"go.opentelemetry.io/otel/propagation" | ||
) | ||
|
||
func ExampleNewTextMapPropagator() { | ||
// NewTextMapPropagator returns a TraceContext and Baggage propagator by | ||
// default. The response of this function can be directly registered with | ||
// the go.opentelemetry.io/otel package. | ||
otel.SetTextMapPropagator(autoprop.NewTextMapPropagator()) | ||
|
||
fields := otel.GetTextMapPropagator().Fields() | ||
sort.Strings(fields) | ||
fmt.Println(fields) | ||
// Output: [baggage traceparent tracestate] | ||
} | ||
|
||
func ExampleNewTextMapPropagator_arguments() { | ||
// NewTextMapPropagator behaves the same as the | ||
// NewCompositeTextMapPropagator function in the | ||
// go.opentelemetry.io/otel/propagation package when TextMapPropagator are | ||
// passed as arguments. | ||
fields := autoprop.NewTextMapPropagator( | ||
propagation.TraceContext{}, | ||
propagation.Baggage{}, | ||
b3.New(), | ||
).Fields() | ||
sort.Strings(fields) | ||
fmt.Println(fields) | ||
// Output: [baggage traceparent tracestate x-b3-flags x-b3-sampled x-b3-spanid x-b3-traceid] | ||
} | ||
|
||
func ExampleNewTextMapPropagator_environment() { | ||
// Propagators set for the OTEL_PROPAGATORS environment variable take | ||
// precedence and will override any arguments passed to | ||
// NewTextMapPropagator. | ||
_ = os.Setenv("OTEL_PROPAGATORS", "b3,baggage") | ||
|
||
// Returns only a B3 and Baggage TextMapPropagator (i.e. does not include | ||
// TraceContext). | ||
fields := autoprop.NewTextMapPropagator(propagation.TraceContext{}).Fields() | ||
sort.Strings(fields) | ||
fmt.Println(fields) | ||
// Output: [baggage x-b3-flags x-b3-sampled x-b3-spanid x-b3-traceid] | ||
} | ||
|
||
type myTextMapPropagator struct{ propagation.TextMapPropagator } | ||
|
||
func (myTextMapPropagator) Fields() []string { | ||
return []string{"my-header-val"} | ||
} | ||
|
||
func ExampleRegisterTextMapPropagator() { | ||
// To use your own or a 3rd-party exporter via the OTEL_PROPAGATORS | ||
// environment variable, it needs to be registered prior to calling | ||
// NewTextMapPropagator. | ||
autoprop.RegisterTextMapPropagator("custom-prop", myTextMapPropagator{}) | ||
|
||
_ = os.Setenv("OTEL_PROPAGATORS", "custom-prop") | ||
fmt.Println(autoprop.NewTextMapPropagator().Fields()) | ||
// Output: [my-header-val] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module go.opentelemetry.io/contrib/propagators/autoprop | ||
|
||
go 1.17 | ||
|
||
require ( | ||
github.com/stretchr/testify v1.7.1 | ||
go.opentelemetry.io/contrib/propagators/aws v1.7.0 | ||
go.opentelemetry.io/contrib/propagators/b3 v1.7.0 | ||
go.opentelemetry.io/contrib/propagators/jaeger v1.7.0 | ||
go.opentelemetry.io/contrib/propagators/ot v1.7.0 | ||
go.opentelemetry.io/otel v1.7.0 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/go-logr/logr v1.2.3 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
go.opentelemetry.io/otel/sdk v1.7.0 // indirect | ||
go.opentelemetry.io/otel/trace v1.7.0 // indirect | ||
go.uber.org/atomic v1.7.0 // indirect | ||
go.uber.org/multierr v1.8.0 // indirect | ||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 // indirect | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= | ||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= | ||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= | ||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= | ||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= | ||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= | ||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
go.opentelemetry.io/contrib/propagators/aws v1.7.0 h1:hzLtX+K4YhsrBabA35uBYxCENb5rS/9Z9X8MToTlA3k= | ||
go.opentelemetry.io/contrib/propagators/aws v1.7.0/go.mod h1:h/ql5T6e1XLRFplWNNdzLHp8eb0dkBu+xYOCYxerh0Q= | ||
go.opentelemetry.io/contrib/propagators/b3 v1.7.0 h1:oRAenUhj+GFttfIp3gj7HYVzBhPOHgq/dWPDSmLCXSY= | ||
go.opentelemetry.io/contrib/propagators/b3 v1.7.0/go.mod h1:gXx7AhL4xXCF42gpm9dQvdohoDa2qeyEx4eIIxqK+h4= | ||
go.opentelemetry.io/contrib/propagators/jaeger v1.7.0 h1:x2mXKtONfOJFfNFSx4QXFx1fms6bKIPVvWvgdiaPdRI= | ||
go.opentelemetry.io/contrib/propagators/jaeger v1.7.0/go.mod h1:kt2lNImfxV6dETRsDCENd6jU6G0mPRS+P0qlNuvtkTE= | ||
go.opentelemetry.io/contrib/propagators/ot v1.7.0 h1:KPPToDRxyY/HI3qD4RqwWRbaQ65RIpF8uKWDqWkFHDA= | ||
go.opentelemetry.io/contrib/propagators/ot v1.7.0/go.mod h1:5qxBZR730yb71uXc3bazxt2Si8o8LQK3iJTnSLca/BU= | ||
go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= | ||
go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= | ||
go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= | ||
go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= | ||
go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= | ||
go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= | ||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= | ||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= | ||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= | ||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= | ||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= | ||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package autoprop // import "go.opentelemetry.io/contrib/propagators/autoprop" | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"go.opentelemetry.io/otel" | ||
"go.opentelemetry.io/otel/propagation" | ||
) | ||
|
||
// otelPropagatorsEnvKey is the environment variable name identifying | ||
// propagators to use. | ||
const otelPropagatorsEnvKey = "OTEL_PROPAGATORS" | ||
|
||
// NewTextMapPropagator returns a new TextMapPropagator composited by props or | ||
// one defined by the OTEL_PROPAGATORS environment variable. The | ||
// TextMapPropagator defined by OTEL_PROPAGATORS, if set, will take precedence | ||
// to the once composited by props. | ||
// | ||
// The propagators supported with the OTEL_PROPAGATORS environment variable by | ||
// default are: tracecontext, baggage, b3, b3multi, jaeger, xray, ottrace, and | ||
// none. Each of these values, and their combination, are supported in | ||
// conformance with the OpenTelemetry specification. See | ||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration | ||
// for more information. | ||
// | ||
// The supported environment variable propagators can be extended to include | ||
// custom 3rd-party TextMapPropagator. See the RegisterTextMapPropagator | ||
// function for more information. | ||
// | ||
// If OTEL_PROPAGATORS is not defined and props is no provided, the returned | ||
// TextMapPropagator will be a composite of the TraceContext and Baggage | ||
// propagators. | ||
func NewTextMapPropagator(props ...propagation.TextMapPropagator) propagation.TextMapPropagator { | ||
// Environment variable defined propagator has precedence over arguments. | ||
envProp, err := parseEnv() | ||
if err != nil { | ||
// Communicate to the user their supplied value will not be used. | ||
otel.Handle(err) | ||
} | ||
if envProp != nil { | ||
return envProp | ||
} | ||
|
||
switch len(props) { | ||
case 0: | ||
// Default to TraceContext and Baggage. | ||
return propagation.NewCompositeTextMapPropagator( | ||
propagation.TraceContext{}, propagation.Baggage{}, | ||
) | ||
case 1: | ||
// Do not add overhead with a composite propagator wrapping a single | ||
// propagator, return it directly. | ||
return props[0] | ||
default: | ||
return propagation.NewCompositeTextMapPropagator(props...) | ||
} | ||
} | ||
|
||
// errUnknownPropagator is returned when an unknown propagator name is used in | ||
// the OTEL_PROPAGATORS environment variable. | ||
var errUnknownPropagator = errors.New("unknown propagator") | ||
|
||
// parseEnv returns the composite TextMapPropagators defined by the | ||
// OTEL_PROPAGATORS environment variable. A nil TextMapPropagator is returned | ||
// if no propagator is defined for the environment variable. A no-op | ||
// TextMapPropagator will be returned if "none" is defined anywhere in the | ||
// environment variable. | ||
func parseEnv() (propagation.TextMapPropagator, error) { | ||
propStrs, defined := os.LookupEnv(otelPropagatorsEnvKey) | ||
if !defined { | ||
return nil, nil | ||
} | ||
|
||
const sep = "," | ||
|
||
var ( | ||
props []propagation.TextMapPropagator | ||
unknown []string | ||
) | ||
|
||
for _, pStr := range strings.Split(propStrs, sep) { | ||
if pStr == none { | ||
// If "none" is passed in combination with any other propagator, | ||
// the result still needs to be a no-op propagator. Therefore, | ||
// short-circuit here. | ||
return propagation.NewCompositeTextMapPropagator(), nil | ||
} | ||
|
||
p, ok := envRegistry.load(pStr) | ||
if !ok { | ||
unknown = append(unknown, pStr) | ||
continue | ||
} | ||
props = append(props, p) | ||
} | ||
|
||
var err error | ||
if len(unknown) > 0 { | ||
joined := strings.Join(unknown, sep) | ||
err = fmt.Errorf("%w: %s", errUnknownPropagator, joined) | ||
} | ||
|
||
switch len(props) { | ||
case 0: | ||
return nil, err | ||
case 1: | ||
// Do not return a composite of a single propagator. | ||
return props[0], err | ||
default: | ||
return propagation.NewCompositeTextMapPropagator(props...), err | ||
} | ||
} |
Oops, something went wrong.