propagator.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright The OpenTelemetry Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package global
  15. import (
  16. "context"
  17. "sync"
  18. "go.opentelemetry.io/otel/propagation"
  19. )
  20. // textMapPropagator is a default TextMapPropagator that delegates calls to a
  21. // registered delegate if one is set, otherwise it defaults to delegating the
  22. // calls to a the default no-op propagation.TextMapPropagator.
  23. type textMapPropagator struct {
  24. mtx sync.Mutex
  25. once sync.Once
  26. delegate propagation.TextMapPropagator
  27. noop propagation.TextMapPropagator
  28. }
  29. // Compile-time guarantee that textMapPropagator implements the
  30. // propagation.TextMapPropagator interface.
  31. var _ propagation.TextMapPropagator = (*textMapPropagator)(nil)
  32. func newTextMapPropagator() *textMapPropagator {
  33. return &textMapPropagator{
  34. noop: propagation.NewCompositeTextMapPropagator(),
  35. }
  36. }
  37. // SetDelegate sets a delegate propagation.TextMapPropagator that all calls are
  38. // forwarded to. Delegation can only be performed once, all subsequent calls
  39. // perform no delegation.
  40. func (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {
  41. if delegate == nil {
  42. return
  43. }
  44. p.mtx.Lock()
  45. p.once.Do(func() { p.delegate = delegate })
  46. p.mtx.Unlock()
  47. }
  48. // effectiveDelegate returns the current delegate of p if one is set,
  49. // otherwise the default noop TextMapPropagator is returned. This method
  50. // can be called concurrently.
  51. func (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {
  52. p.mtx.Lock()
  53. defer p.mtx.Unlock()
  54. if p.delegate != nil {
  55. return p.delegate
  56. }
  57. return p.noop
  58. }
  59. // Inject set cross-cutting concerns from the Context into the carrier.
  60. func (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
  61. p.effectiveDelegate().Inject(ctx, carrier)
  62. }
  63. // Extract reads cross-cutting concerns from the carrier into a Context.
  64. func (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
  65. return p.effectiveDelegate().Extract(ctx, carrier)
  66. }
  67. // Fields returns the keys whose values are set with Inject.
  68. func (p *textMapPropagator) Fields() []string {
  69. return p.effectiveDelegate().Fields()
  70. }