tracer.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // Copyright 2022 The OpenZipkin 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 zipkintracer
  15. import (
  16. "fmt"
  17. "net"
  18. "strings"
  19. "time"
  20. opentracing "github.com/opentracing/opentracing-go"
  21. "github.com/opentracing/opentracing-go/ext"
  22. "github.com/openzipkin/zipkin-go"
  23. "github.com/openzipkin/zipkin-go/model"
  24. )
  25. type tracerImpl struct {
  26. zipkinTracer *zipkin.Tracer
  27. textPropagator *textMapPropagator
  28. accessorPropagator *accessorPropagator
  29. opts *TracerOptions
  30. }
  31. // Wrap receives a zipkin tracer and returns an opentracing
  32. // tracer
  33. func Wrap(tr *zipkin.Tracer, opts ...TracerOption) opentracing.Tracer {
  34. t := &tracerImpl{
  35. zipkinTracer: tr,
  36. opts: &TracerOptions{},
  37. }
  38. t.textPropagator = &textMapPropagator{t}
  39. t.accessorPropagator = &accessorPropagator{t}
  40. for _, o := range opts {
  41. o(t.opts)
  42. }
  43. return t
  44. }
  45. func (t *tracerImpl) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
  46. var startSpanOptions opentracing.StartSpanOptions
  47. for _, opt := range opts {
  48. opt.Apply(&startSpanOptions)
  49. }
  50. zopts := make([]zipkin.SpanOption, 0)
  51. // Parent
  52. if len(startSpanOptions.References) > 0 {
  53. parent, ok := (startSpanOptions.References[0].ReferencedContext).(SpanContext)
  54. if ok {
  55. zopts = append(zopts, zipkin.Parent(model.SpanContext(parent)))
  56. }
  57. }
  58. startTime := time.Now()
  59. // Time
  60. if !startSpanOptions.StartTime.IsZero() {
  61. zopts = append(zopts, zipkin.StartTime(startSpanOptions.StartTime))
  62. startTime = startSpanOptions.StartTime
  63. }
  64. zopts = append(zopts, parseTagsAsZipkinOptions(startSpanOptions.Tags)...)
  65. newSpan := t.zipkinTracer.StartSpan(operationName, zopts...)
  66. sp := &spanImpl{
  67. zipkinSpan: newSpan,
  68. tracer: t,
  69. startTime: startTime,
  70. }
  71. if t.opts.observer != nil {
  72. observer, _ := t.opts.observer.OnStartSpan(sp, operationName, startSpanOptions)
  73. sp.observer = observer
  74. }
  75. return sp
  76. }
  77. func parseTagsAsZipkinOptions(t map[string]interface{}) []zipkin.SpanOption {
  78. zopts := make([]zipkin.SpanOption, 0)
  79. tags := map[string]string{}
  80. remoteEndpoint := &model.Endpoint{}
  81. var kind string
  82. if val, ok := t[string(ext.SpanKind)]; ok {
  83. switch kindVal := val.(type) {
  84. case ext.SpanKindEnum:
  85. kind = string(kindVal)
  86. case string:
  87. kind = kindVal
  88. default:
  89. kind = fmt.Sprintf("%v", kindVal)
  90. }
  91. mKind := model.Kind(strings.ToUpper(kind))
  92. if mKind == model.Client ||
  93. mKind == model.Server ||
  94. mKind == model.Producer ||
  95. mKind == model.Consumer {
  96. zopts = append(zopts, zipkin.Kind(mKind))
  97. } else {
  98. tags["span.kind"] = kind
  99. }
  100. }
  101. if val, ok := t[string(ext.PeerService)]; ok {
  102. serviceName, _ := val.(string)
  103. remoteEndpoint.ServiceName = serviceName
  104. }
  105. if val, ok := t[string(ext.PeerHostIPv4)]; ok {
  106. ipv4, _ := val.(string)
  107. remoteEndpoint.IPv4 = net.ParseIP(ipv4)
  108. }
  109. if val, ok := t[string(ext.PeerHostIPv6)]; ok {
  110. ipv6, _ := val.(string)
  111. remoteEndpoint.IPv6 = net.ParseIP(ipv6)
  112. }
  113. if val, ok := t[string(ext.PeerPort)]; ok {
  114. port, _ := val.(uint16)
  115. remoteEndpoint.Port = port
  116. }
  117. for key, val := range t {
  118. if key == string(ext.SpanKind) ||
  119. key == string(ext.PeerService) ||
  120. key == string(ext.PeerHostIPv4) ||
  121. key == string(ext.PeerHostIPv6) ||
  122. key == string(ext.PeerPort) {
  123. continue
  124. }
  125. tags[key] = fmt.Sprint(val)
  126. }
  127. if len(tags) > 0 {
  128. zopts = append(zopts, zipkin.Tags(tags))
  129. }
  130. if !remoteEndpoint.Empty() {
  131. zopts = append(zopts, zipkin.RemoteEndpoint(remoteEndpoint))
  132. }
  133. return zopts
  134. }
  135. type delegatorType struct{}
  136. // Delegator is the format to use for DelegatingCarrier.
  137. var Delegator delegatorType
  138. func (t *tracerImpl) Inject(sc opentracing.SpanContext, format interface{}, carrier interface{}) error {
  139. switch format {
  140. case opentracing.TextMap, opentracing.HTTPHeaders:
  141. return t.textPropagator.Inject(sc, carrier)
  142. case opentracing.Binary:
  143. // try with textMapPropagator
  144. return t.textPropagator.Inject(sc, carrier)
  145. }
  146. if _, ok := format.(delegatorType); ok {
  147. return t.accessorPropagator.Inject(sc, carrier)
  148. }
  149. return opentracing.ErrUnsupportedFormat
  150. }
  151. func (t *tracerImpl) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
  152. switch format {
  153. case opentracing.TextMap, opentracing.HTTPHeaders:
  154. return t.textPropagator.Extract(carrier)
  155. case opentracing.Binary:
  156. // try with textMapPropagator
  157. return t.textPropagator.Extract(carrier)
  158. }
  159. if _, ok := format.(delegatorType); ok {
  160. return t.accessorPropagator.Extract(carrier)
  161. }
  162. return nil, opentracing.ErrUnsupportedFormat
  163. }