Skip to content

Commit

Permalink
update doc.
Browse files Browse the repository at this point in the history
  • Loading branch information
rghetia committed Aug 27, 2019
1 parent 35f8c48 commit a271d18
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 31 deletions.
21 changes: 13 additions & 8 deletions api/propagation/propagator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@ import (
"go.opentelemetry.io/api/tag"
)

// TextFormatPropagator is an interface that specifies methods to create CarrierInjector
// and CarrierExtractor objects. These methods bind given carrier to the created object.
// CarrierInjector object implements Inject method to inject
// SpanContext and tag.Map as a text format into carrier like HTTP request.
// Similarly, CarrierExtractor object implements Extract method to extract SpanContext
// encoded in text format from a carrier like HTTP request.
// TextFormatPropagator is an interface that specifies methods to create objects
// that encodes/decodes into/from text format representation of SpanContext and tag.Map.
//
// CarrierInjector method creates an Injector object and binds the carrier to the object.
// Injector object provides Inject method to inject SpanContext and tag.Map after serializing into
// a text format associated with the propagator.
//
// Similarly, CarrierExtractor method creates an Extractor object and binds the carrier to the
// object. Extractor object provides Extract method to extract text formatted de-serialized
// SpanContext and tag.Map
//
// Typically, a plugin for transport like HTTP uses this interface to allow user
// to configure appropriate text format propagators.
type TextFormatPropagator interface {
Expand All @@ -38,14 +43,14 @@ type TextFormatPropagator interface {
}

type Injector interface {
// Inject serializes span context and tag.Map and inserts them in to
// Inject encodes span context and tag.Map and inserts them in to
// carrier associated with the injector. For example in case of http request,
// span context could be added to the request (carrier) as W3C Trace context header.
Inject(core.SpanContext, tag.Map)
}

type Extractor interface {
// Extract de-serializes span context and tag.Map from a carrier associated with the
// Extract decodes span context and tag.Map from a carrier associated with the
// extractor. For example in case of http request, span context could be extracted
// from the W3C Trace context header.
Extract() (core.SpanContext, tag.Map)
Expand Down
52 changes: 29 additions & 23 deletions propagation/http_trace_context_propagator.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type httpTraceContextPropagator struct{}

var _ apipropagation.TextFormatPropagator = httpTraceContextPropagator{}

// CarrierExtractor implements CarrierExtractor method of TextFormatPropagator interface.
// CarrierExtractor implements TextFormatPropagator interface.
//
// It creates CarrierExtractor object and binds carrier to the object. The carrier
// is expected to be *http.Request. If the carrier type is not *http.Request
Expand All @@ -50,7 +50,7 @@ func (hp httpTraceContextPropagator) CarrierExtractor(carrier interface{}) apipr
return traceContextExtractor{}
}

// CarrierInjector implements CarrierInjector method of TextFormatPropagator interface.
// CarrierInjector implements TextFormatPropagator interface.
//
// It creates CarrierInjector object and binds carrier to the object. The carrier
// is expected to be of type *http.Request. If the carrier type is not *http.Request
Expand All @@ -63,14 +63,14 @@ func (hp httpTraceContextPropagator) CarrierInjector(carrier interface{}) apipro
return traceContextInjector{}
}

// HttpTraceContextPropagator creates a new propagator that propagates SpanContext
// HttpTraceContextPropagator creates a new text format propagator that propagates SpanContext
// in W3C TraceContext format.
//
// The propagator is then used to create CarrierInjector and CarrierExtractor associated with a
// specific request. Injectors and Extractors respectively provides method to
// inject and extract SpanContext into/from the http request. Inject method encodes
// SpanContext into W3C TraceContext Header and injects the header in the request.
// Extract method extracts the header and decodes SpanContext.
// SpanContext and tag.Map into W3C TraceContext Header and injects the header in the request.
// Extract method extracts the header and decodes SpanContext and tag.Map.
func HttpTraceContextPropagator() httpTraceContextPropagator {
return httpTraceContextPropagator{}
}
Expand All @@ -81,84 +81,90 @@ type traceContextExtractor struct {

var _ apipropagation.Extractor = traceContextExtractor{}

// Extract implements Extract method of propagation.Extractor interface. It extracts
// W3C TraceContext Header and decodes SpanContext from the Header.
// Extract implements Extractor interface.
//
// It extracts W3C TraceContext Header and then decodes SpanContext and tag.Map from the Header.
func (tce traceContextExtractor) Extract() (sc core.SpanContext, tm tag.Map) {
if tce.req == nil {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
h, ok := getRequestHeader(tce.req, traceparentHeader, false)
if !ok {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
sections := strings.Split(h, "-")
if len(sections) < 4 {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}

if len(sections[0]) != 2 {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
ver, err := hex.DecodeString(sections[0])
if err != nil {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
version := int(ver[0])
if version > maxVersion {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}

if version == 0 && len(sections) != 4 {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}

if len(sections[1]) != 32 {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}

result, err := strconv.ParseUint(sections[1][0:16], 16, 64)
if err != nil {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
sc.TraceID.High = result

result, err = strconv.ParseUint(sections[1][16:32], 16, 64)
if err != nil {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
sc.TraceID.Low = result

if len(sections[2]) != 16 {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
result, err = strconv.ParseUint(sections[2][0:], 16, 64)
if err != nil {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
sc.SpanID = result

opts, err := hex.DecodeString(sections[3])
if err != nil || len(opts) < 1 {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}
sc.TraceOptions = opts[0]

if !sc.IsValid() {
return core.EmptySpanContext(), tag.NewEmptyMap()
return noExtract()
}

// TODO: [rghetia] add tag.Map (distributed context) extraction
return sc, tag.NewEmptyMap()
}

func noExtract() (core.SpanContext, tag.Map) {
return core.EmptySpanContext(), tag.NewEmptyMap()
}

type traceContextInjector struct {
req *http.Request
}

var _ apipropagation.Injector = traceContextInjector{}

// Inject implements Inject method of propagation.Injector interface. It encodes
// SpanContext into W3C TraceContext Header and injects the header into
// Inject implements Injector interface.
//
// It encodes SpanContext and tag.Map into W3C TraceContext Header and injects the header into
// the associated request.
func (tci traceContextInjector) Inject(sc core.SpanContext, tm tag.Map) {
if tci.req == nil {
Expand Down

0 comments on commit a271d18

Please sign in to comment.