propagation.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package propagation // import "go.opentelemetry.io/otel/propagation"
  4. import (
  5. "context"
  6. "net/http"
  7. )
  8. // TextMapCarrier is the storage medium used by a TextMapPropagator.
  9. type TextMapCarrier interface {
  10. // DO NOT CHANGE: any modification will not be backwards compatible and
  11. // must never be done outside of a new major release.
  12. // Get returns the value associated with the passed key.
  13. Get(key string) string
  14. // DO NOT CHANGE: any modification will not be backwards compatible and
  15. // must never be done outside of a new major release.
  16. // Set stores the key-value pair.
  17. Set(key string, value string)
  18. // DO NOT CHANGE: any modification will not be backwards compatible and
  19. // must never be done outside of a new major release.
  20. // Keys lists the keys stored in this carrier.
  21. Keys() []string
  22. // DO NOT CHANGE: any modification will not be backwards compatible and
  23. // must never be done outside of a new major release.
  24. }
  25. // MapCarrier is a TextMapCarrier that uses a map held in memory as a storage
  26. // medium for propagated key-value pairs.
  27. type MapCarrier map[string]string
  28. // Compile time check that MapCarrier implements the TextMapCarrier.
  29. var _ TextMapCarrier = MapCarrier{}
  30. // Get returns the value associated with the passed key.
  31. func (c MapCarrier) Get(key string) string {
  32. return c[key]
  33. }
  34. // Set stores the key-value pair.
  35. func (c MapCarrier) Set(key, value string) {
  36. c[key] = value
  37. }
  38. // Keys lists the keys stored in this carrier.
  39. func (c MapCarrier) Keys() []string {
  40. keys := make([]string, 0, len(c))
  41. for k := range c {
  42. keys = append(keys, k)
  43. }
  44. return keys
  45. }
  46. // HeaderCarrier adapts http.Header to satisfy the TextMapCarrier interface.
  47. type HeaderCarrier http.Header
  48. // Get returns the value associated with the passed key.
  49. func (hc HeaderCarrier) Get(key string) string {
  50. return http.Header(hc).Get(key)
  51. }
  52. // Set stores the key-value pair.
  53. func (hc HeaderCarrier) Set(key string, value string) {
  54. http.Header(hc).Set(key, value)
  55. }
  56. // Keys lists the keys stored in this carrier.
  57. func (hc HeaderCarrier) Keys() []string {
  58. keys := make([]string, 0, len(hc))
  59. for k := range hc {
  60. keys = append(keys, k)
  61. }
  62. return keys
  63. }
  64. // TextMapPropagator propagates cross-cutting concerns as key-value text
  65. // pairs within a carrier that travels in-band across process boundaries.
  66. type TextMapPropagator interface {
  67. // DO NOT CHANGE: any modification will not be backwards compatible and
  68. // must never be done outside of a new major release.
  69. // Inject set cross-cutting concerns from the Context into the carrier.
  70. Inject(ctx context.Context, carrier TextMapCarrier)
  71. // DO NOT CHANGE: any modification will not be backwards compatible and
  72. // must never be done outside of a new major release.
  73. // Extract reads cross-cutting concerns from the carrier into a Context.
  74. Extract(ctx context.Context, carrier TextMapCarrier) context.Context
  75. // DO NOT CHANGE: any modification will not be backwards compatible and
  76. // must never be done outside of a new major release.
  77. // Fields returns the keys whose values are set with Inject.
  78. Fields() []string
  79. // DO NOT CHANGE: any modification will not be backwards compatible and
  80. // must never be done outside of a new major release.
  81. }
  82. type compositeTextMapPropagator []TextMapPropagator
  83. func (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {
  84. for _, i := range p {
  85. i.Inject(ctx, carrier)
  86. }
  87. }
  88. func (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
  89. for _, i := range p {
  90. ctx = i.Extract(ctx, carrier)
  91. }
  92. return ctx
  93. }
  94. func (p compositeTextMapPropagator) Fields() []string {
  95. unique := make(map[string]struct{})
  96. for _, i := range p {
  97. for _, k := range i.Fields() {
  98. unique[k] = struct{}{}
  99. }
  100. }
  101. fields := make([]string, 0, len(unique))
  102. for k := range unique {
  103. fields = append(fields, k)
  104. }
  105. return fields
  106. }
  107. // NewCompositeTextMapPropagator returns a unified TextMapPropagator from the
  108. // group of passed TextMapPropagator. This allows different cross-cutting
  109. // concerns to be propagates in a unified manner.
  110. //
  111. // The returned TextMapPropagator will inject and extract cross-cutting
  112. // concerns in the order the TextMapPropagators were provided. Additionally,
  113. // the Fields method will return a de-duplicated slice of the keys that are
  114. // set with the Inject method.
  115. func NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {
  116. return compositeTextMapPropagator(p)
  117. }