@@ -634,7 +634,7 @@ func (s fakeSpan) SpanContext() trace.SpanContext {
634
634
// Inject is a part of the implementation of the OpenTracing Tracer
635
635
// interface.
636
636
//
637
- // Currently only the HTTPHeaders format is supported.
637
+ // Currently only the HTTPHeaders and TextMap formats are supported.
638
638
func (t * BridgeTracer ) Inject (sm ot.SpanContext , format interface {}, carrier interface {}) error {
639
639
bridgeSC , ok := sm .(* bridgeSpanContext )
640
640
if ! ok {
@@ -643,38 +643,75 @@ func (t *BridgeTracer) Inject(sm ot.SpanContext, format interface{}, carrier int
643
643
if ! bridgeSC .otelSpanContext .IsValid () {
644
644
return ot .ErrInvalidSpanContext
645
645
}
646
- if builtinFormat , ok := format .(ot.BuiltinFormat ); ! ok || builtinFormat != ot .HTTPHeaders {
646
+
647
+ builtinFormat , ok := format .(ot.BuiltinFormat )
648
+ if ! ok {
647
649
return ot .ErrUnsupportedFormat
648
650
}
649
- hhcarrier , ok := carrier .(ot.HTTPHeadersCarrier )
650
- if ! ok {
651
- return ot .ErrInvalidCarrier
651
+
652
+ var textCarrier propagation.TextMapCarrier
653
+
654
+ switch builtinFormat {
655
+ case ot .HTTPHeaders :
656
+ hhcarrier , ok := carrier .(ot.HTTPHeadersCarrier )
657
+ if ! ok {
658
+ return ot .ErrInvalidCarrier
659
+ }
660
+
661
+ textCarrier = propagation .HeaderCarrier (hhcarrier )
662
+ case ot .TextMap :
663
+ if textCarrier , ok = carrier .(propagation.TextMapCarrier ); ! ok {
664
+ var err error
665
+ if textCarrier , err = newTextMapWrapperForInject (carrier ); err != nil {
666
+ return err
667
+ }
668
+ }
669
+ default :
670
+ return ot .ErrUnsupportedFormat
652
671
}
653
- header := http . Header ( hhcarrier )
672
+
654
673
fs := fakeSpan {
655
674
Span : noopSpan ,
656
675
sc : bridgeSC .otelSpanContext ,
657
676
}
658
677
ctx := trace .ContextWithSpan (context .Background (), fs )
659
678
ctx = baggage .ContextWithBaggage (ctx , bridgeSC .bag )
660
- t .getPropagator ().Inject (ctx , propagation . HeaderCarrier ( header ) )
679
+ t .getPropagator ().Inject (ctx , textCarrier )
661
680
return nil
662
681
}
663
682
664
683
// Extract is a part of the implementation of the OpenTracing Tracer
665
684
// interface.
666
685
//
667
- // Currently only the HTTPHeaders format is supported.
686
+ // Currently only the HTTPHeaders and TextMap formats are supported.
668
687
func (t * BridgeTracer ) Extract (format interface {}, carrier interface {}) (ot.SpanContext , error ) {
669
- if builtinFormat , ok := format .(ot.BuiltinFormat ); ! ok || builtinFormat != ot .HTTPHeaders {
688
+ builtinFormat , ok := format .(ot.BuiltinFormat )
689
+ if ! ok {
670
690
return nil , ot .ErrUnsupportedFormat
671
691
}
672
- hhcarrier , ok := carrier .(ot.HTTPHeadersCarrier )
673
- if ! ok {
674
- return nil , ot .ErrInvalidCarrier
692
+
693
+ var textCarrier propagation.TextMapCarrier
694
+
695
+ switch builtinFormat {
696
+ case ot .HTTPHeaders :
697
+ hhcarrier , ok := carrier .(ot.HTTPHeadersCarrier )
698
+ if ! ok {
699
+ return nil , ot .ErrInvalidCarrier
700
+ }
701
+
702
+ textCarrier = propagation .HeaderCarrier (hhcarrier )
703
+ case ot .TextMap :
704
+ if textCarrier , ok = carrier .(propagation.TextMapCarrier ); ! ok {
705
+ var err error
706
+ if textCarrier , err = newTextMapWrapperForExtract (carrier ); err != nil {
707
+ return nil , err
708
+ }
709
+ }
710
+ default :
711
+ return nil , ot .ErrUnsupportedFormat
675
712
}
676
- header := http . Header ( hhcarrier )
677
- ctx := t .getPropagator ().Extract (context .Background (), propagation . HeaderCarrier ( header ) )
713
+
714
+ ctx := t .getPropagator ().Extract (context .Background (), textCarrier )
678
715
bag := baggage .FromContext (ctx )
679
716
bridgeSC := & bridgeSpanContext {
680
717
bag : bag ,
@@ -692,3 +729,105 @@ func (t *BridgeTracer) getPropagator() propagation.TextMapPropagator {
692
729
}
693
730
return otel .GetTextMapPropagator ()
694
731
}
732
+
733
+ // textMapWrapper Provides operating.TextMapWriter and operating.TextMapReader to
734
+ // propagation.TextMapCarrier compatibility.
735
+ // Usually, Inject method will only use the write-related interface.
736
+ // Extract method will only use the reade-related interface.
737
+ // To avoid panic,
738
+ // when the carrier implements only one of the interfaces,
739
+ // it provides a default implementation of the other interface (textMapWriter and textMapReader).
740
+ type textMapWrapper struct {
741
+ ot.TextMapWriter
742
+ ot.TextMapReader
743
+ readerMap map [string ]string
744
+ }
745
+
746
+ func (t * textMapWrapper ) Get (key string ) string {
747
+ if t .readerMap == nil {
748
+ t .loadMap ()
749
+ }
750
+
751
+ return t .readerMap [key ]
752
+ }
753
+
754
+ func (t * textMapWrapper ) Set (key string , value string ) {
755
+ t .TextMapWriter .Set (key , value )
756
+ }
757
+
758
+ func (t * textMapWrapper ) Keys () []string {
759
+ if t .readerMap == nil {
760
+ t .loadMap ()
761
+ }
762
+
763
+ str := make ([]string , 0 , len (t .readerMap ))
764
+ for key := range t .readerMap {
765
+ str = append (str , key )
766
+ }
767
+
768
+ return str
769
+ }
770
+
771
+ func (t * textMapWrapper ) loadMap () {
772
+ t .readerMap = make (map [string ]string )
773
+
774
+ _ = t .ForeachKey (func (key , val string ) error {
775
+ t .readerMap [key ] = val
776
+
777
+ return nil
778
+ })
779
+ }
780
+
781
+ func newTextMapWrapperForExtract (carrier interface {}) (* textMapWrapper , error ) {
782
+ t := & textMapWrapper {}
783
+
784
+ reader , ok := carrier .(ot.TextMapReader )
785
+ if ! ok {
786
+ return nil , ot .ErrInvalidCarrier
787
+ }
788
+
789
+ t .TextMapReader = reader
790
+
791
+ writer , ok := carrier .(ot.TextMapWriter )
792
+ if ok {
793
+ t .TextMapWriter = writer
794
+ } else {
795
+ t .TextMapWriter = & textMapWriter {}
796
+ }
797
+
798
+ return t , nil
799
+ }
800
+
801
+ func newTextMapWrapperForInject (carrier interface {}) (* textMapWrapper , error ) {
802
+ t := & textMapWrapper {}
803
+
804
+ writer , ok := carrier .(ot.TextMapWriter )
805
+ if ! ok {
806
+ return nil , ot .ErrInvalidCarrier
807
+ }
808
+
809
+ t .TextMapWriter = writer
810
+
811
+ reader , ok := carrier .(ot.TextMapReader )
812
+ if ok {
813
+ t .TextMapReader = reader
814
+ } else {
815
+ t .TextMapReader = & textMapReader {}
816
+ }
817
+
818
+ return t , nil
819
+ }
820
+
821
+ type textMapWriter struct {
822
+ }
823
+
824
+ func (t * textMapWriter ) Set (key string , value string ) {
825
+ // maybe print a warning log.
826
+ }
827
+
828
+ type textMapReader struct {
829
+ }
830
+
831
+ func (t * textMapReader ) ForeachKey (handler func (key , val string ) error ) error {
832
+ return nil // maybe print a warning log.
833
+ }
0 commit comments