|
- package lightstep
-
- import (
- "encoding/base64"
- "io"
- "io/ioutil"
-
- "github.com/gogo/protobuf/proto"
- lightstep "github.com/lightstep/lightstep-tracer-common/golang/gogo/lightsteppb"
- "github.com/opentracing/opentracing-go"
- )
-
- // BinaryCarrier is used as the format parameter in inject/extract for lighstep binary propagation.
- const BinaryCarrier = opentracing.Binary
-
- // BinaryPropagator propagates context in binary format
- var BinaryPropagator binaryPropagator
-
- type binaryPropagator struct{}
-
- func (binaryPropagator) Inject(
- spanContext opentracing.SpanContext,
- opaqueCarrier interface{},
- ) error {
- sc, ok := spanContext.(SpanContext)
- if !ok {
- return opentracing.ErrInvalidSpanContext
- }
- data, err := proto.Marshal(&lightstep.BinaryCarrier{
- BasicCtx: &lightstep.BasicTracerCarrier{
- TraceId: sc.TraceID,
- SpanId: sc.SpanID,
- Sampled: true,
- BaggageItems: sc.Baggage,
- },
- })
- if err != nil {
- return err
- }
-
- switch carrier := opaqueCarrier.(type) {
- case io.Writer:
- buf := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
- base64.StdEncoding.Encode(buf, data)
- _, err = carrier.Write(buf)
- return err
- case *string:
- *carrier = base64.StdEncoding.EncodeToString(data)
- case *[]byte:
- *carrier = make([]byte, base64.StdEncoding.EncodedLen(len(data)))
- base64.StdEncoding.Encode(*carrier, data)
- default:
- return opentracing.ErrInvalidCarrier
- }
- return nil
- }
-
- func (binaryPropagator) Extract(
- opaqueCarrier interface{},
- ) (opentracing.SpanContext, error) {
- var data []byte
- var err error
-
- // Decode from string, *string, *[]byte, or []byte
- switch carrier := opaqueCarrier.(type) {
- case io.Reader:
- buf, err := ioutil.ReadAll(carrier)
- if err != nil {
- return nil, err
- }
- data, err = decodeBase64Bytes(buf)
- case *string:
- if carrier != nil {
- data, err = base64.StdEncoding.DecodeString(*carrier)
- }
- case string:
- data, err = base64.StdEncoding.DecodeString(carrier)
- case *[]byte:
- if carrier != nil {
- data, err = decodeBase64Bytes(*carrier)
- }
- case []byte:
- data, err = decodeBase64Bytes(carrier)
- default:
- return nil, opentracing.ErrInvalidCarrier
- }
- if err != nil {
- return nil, err
- }
- pb := &lightstep.BinaryCarrier{}
- if err := proto.Unmarshal(data, pb); err != nil {
- return nil, err
- }
- if pb.BasicCtx == nil {
- return nil, opentracing.ErrInvalidCarrier
- }
-
- return SpanContext{
- TraceID: pb.BasicCtx.TraceId,
- SpanID: pb.BasicCtx.SpanId,
- Baggage: pb.BasicCtx.BaggageItems,
- }, nil
- }
-
- func decodeBase64Bytes(in []byte) ([]byte, error) {
- data := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
- n, err := base64.StdEncoding.Decode(data, in)
- if err != nil {
- return nil, err
- }
- return data[:n], nil
- }
|