Skip to content

Commit

Permalink
Add propagator interface and W3C propagator (#85)
Browse files Browse the repository at this point in the history
* add propagation api.

* add http propagator interface and w3c propagator implementation.

* remove Extract api from trace.

* remove Extract interface for tracer.

* fix copyright.

* fix variable names and comments.

* move inject/extract out of trace.

* replace INVALID_SPAN_CONTEXT with EmptySpanContext function.

* fix tag.Map.

* make carrier as interface instead of http.Request.

* rename structs and update doc comments..

* add doc.go

* update doc.

* add noop propagator.

* add new propagation api with Supplier interface.
- added Default Tracer which simply propagates SpanContext.
- added CopyOfRemote option to simply create remote span.

* remove old propagator.

* rename propagator to TextFormatPropagator.

* rename default tracer/span as pass_through tracer/span.

* add test for pass through tracer.

* add missing interface to pass through tracer.

* return SpanContext instead of contex.Context from Extract interface.
- also remove PassThroughTracer

* fix review comments.

* add more test cases for traceContext extraction.

* remove tidy temporarily from circle-ci target to avoid build failure.

* allow header ending in dash '-'.

* add inject test for non-zero value other than 01 for traceoption

* add AddLink and Link interface to MockSpan

* fix running go mod tidy on every build.
  • Loading branch information
rghetia authored Sep 23, 2019
1 parent b13362e commit 83935b2
Show file tree
Hide file tree
Showing 20 changed files with 749 additions and 109 deletions.
16 changes: 16 additions & 0 deletions api/propagation/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package propagation contains interface definition for Binary and TextFormat propagators.
package propagation // import "go.opentelemetry.io/api/propagation"
40 changes: 40 additions & 0 deletions api/propagation/noop_propagator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package propagation

import (
"context"

"go.opentelemetry.io/api/core"
)

// NoopTextFormatPropagator implements TextFormatPropagator that does nothing.
type NoopTextFormatPropagator struct{}

var _ TextFormatPropagator = NoopTextFormatPropagator{}

// Inject does nothing.
func (np NoopTextFormatPropagator) Inject(ctx context.Context, supplier Supplier) {
}

// Extract does nothing and returns an empty SpanContext
func (np NoopTextFormatPropagator) Extract(ctx context.Context, supplier Supplier) core.SpanContext {
return core.EmptySpanContext()
}

// GetAllKeys returns empty list of strings.
func (np NoopTextFormatPropagator) GetAllKeys() []string {
return []string{}
}
52 changes: 52 additions & 0 deletions api/propagation/propagator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package propagation

import (
"context"

"go.opentelemetry.io/api/core"
)

// TextFormatPropagator is an interface that specifies methods to inject and extract SpanContext
// into/from a carrier using Supplier interface.
// For example, HTTP Trace Context propagator would encode SpanContext into W3C Trace
// Context Header and set the header into HttpRequest.
type TextFormatPropagator interface {
// Inject method retrieves current SpanContext from the ctx, encodes it into propagator
// specific format and then injects the encoded SpanContext using supplier into a carrier
// associated with the supplier.
Inject(ctx context.Context, supplier Supplier)

// Extract method retrieves encoded SpanContext using supplier from the associated carrier.
// It decodes the SpanContext and returns it. If no SpanContext was retrieved OR
// if the retrieved SpanContext is invalid then an empty SpanContext is returned.
Extract(ctx context.Context, supplier Supplier) core.SpanContext

// GetAllKeys returns all the keys that this propagator injects/extracts into/from a
// carrier. The use cases for this are
// * allow pre-allocation of fields, especially in systems like gRPC Metadata
// * allow a single-pass over an iterator (ex OpenTracing has no getter in TextMap)
GetAllKeys() []string
}

// Supplier is an interface that specifies methods to retrieve and store
// value for a key to an associated carrier.
// Get method retrieves the value for a given key.
// Set method stores the value for a given key.
type Supplier interface {
Get(key string) string
Set(key string, value string)
}
22 changes: 0 additions & 22 deletions api/trace/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ type Tracer interface {

// WithResources attaches resource attributes to the Tracer.
WithResources(res ...core.KeyValue) Tracer

// Note: see https://github.com/opentracing/opentracing-go/issues/127
Inject(context.Context, Span, Injector)
}

type FinishOptions struct {
Expand Down Expand Up @@ -102,13 +99,6 @@ type Span interface {
ModifyAttributes(...tag.Mutator)
}

type Injector interface {
// Inject serializes 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 added to the request (carrier) as W3C Trace context header.
Inject(core.SpanContext, tag.Map)
}

// SpanOption apply changes to SpanOptions.
type SpanOption func(*SpanOptions)

Expand Down Expand Up @@ -157,18 +147,6 @@ func Start(ctx context.Context, name string, opts ...SpanOption) (context.Contex
return GlobalTracer().Start(ctx, name, opts...)
}

// Inject is convenient function to inject current span context using injector.
// Injector is expected to serialize span context and inject it in to a carrier.
// An example of a carrier is http request.
func Inject(ctx context.Context, injector Injector) {
span := CurrentSpan(ctx)
if span == nil {
return
}

span.Tracer().Inject(ctx, span, injector)
}

// WithStartTime sets the start time of the span to provided time t, when it is started.
// In absensce of this option, wall clock time is used as start time.
// This option is typically used when starting of the span is delayed.
Expand Down
4 changes: 0 additions & 4 deletions api/trace/noop_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,3 @@ func (NoopTracer) Start(ctx context.Context, name string, opts ...SpanOption) (c
span := NoopSpan{}
return SetCurrentSpan(ctx, span), span
}

// Inject does nothing.
func (NoopTracer) Inject(ctx context.Context, span Span, injector Injector) {
}
1 change: 0 additions & 1 deletion example/basic/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
Expand Down
7 changes: 3 additions & 4 deletions example/http/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package main
import (
"context"
"fmt"
"go.opentelemetry.io/plugin/httptrace"
"io/ioutil"
"net/http"

Expand All @@ -25,7 +26,6 @@ import (
"go.opentelemetry.io/api/key"
"go.opentelemetry.io/api/tag"
"go.opentelemetry.io/api/trace"
"go.opentelemetry.io/plugin/httptrace"
)

var (
Expand All @@ -50,9 +50,8 @@ func main() {
func(ctx context.Context) error {
req, _ := http.NewRequest("GET", "http://localhost:7777/hello", nil)

ctx, req, inj := httptrace.W3C(ctx, req)

trace.Inject(ctx, inj)
ctx, req = httptrace.W3C(ctx, req)
httptrace.Inject(ctx, req)

res, err := client.Do(req)
if err != nil {
Expand Down
2 changes: 0 additions & 2 deletions example/http/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac h1:+2b6iGRJe3hvV/yVXrd41yVEjxuFHxasJqDhkIjS4gk=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
Expand Down
2 changes: 1 addition & 1 deletion example/http/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var (

func main() {
helloHandler := func(w http.ResponseWriter, req *http.Request) {
attrs, tags, spanCtx := httptrace.Extract(req)
attrs, tags, spanCtx := httptrace.Extract(req.Context(), req)

req = req.WithContext(tag.WithMap(req.Context(), tag.NewMap(tag.MapUpdate{
MultiKV: tags,
Expand Down
5 changes: 0 additions & 5 deletions experimental/streaming/sdk/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

"go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/key"
"go.opentelemetry.io/api/tag"
"go.opentelemetry.io/api/trace"
apitrace "go.opentelemetry.io/api/trace"
"go.opentelemetry.io/experimental/streaming/exporter/observer"
Expand Down Expand Up @@ -125,7 +124,3 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...apitrace.SpanOp
}
return trace.SetCurrentSpan(ctx, span), span
}

func (t *tracer) Inject(ctx context.Context, span apitrace.Span, injector apitrace.Injector) {
injector.Inject(span.SpanContext(), tag.FromContext(ctx))
}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ require (
github.com/golangci/golangci-lint v1.17.1
github.com/google/go-cmp v0.3.0
github.com/hashicorp/golang-lru v0.5.3
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135
google.golang.org/api v0.9.0
google.golang.org/grpc v1.22.1
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac h1:+2b6iGRJe3hvV/yVXrd41yVEjxuFHxasJqDhkIjS4gk=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.7.6 h1:U+1DqNen04MdEPgFiIwdOUiqZ8qPa37xgogX/sd3+54=
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
Expand Down
96 changes: 96 additions & 0 deletions internal/trace/mock_span.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package trace

import (
"context"

"google.golang.org/grpc/codes"

"go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/tag"
apitrace "go.opentelemetry.io/api/trace"
)

// MockSpan is a mock span used in association with MockTracer for testing purpose only.
type MockSpan struct {
sc core.SpanContext
tracer apitrace.Tracer
}

var _ apitrace.Span = (*MockSpan)(nil)

// SpanContext returns associated core.SpanContext. If the receiver is nil it returns
// an empty core.SpanContext
func (ms *MockSpan) SpanContext() core.SpanContext {
if ms == nil {
core.EmptySpanContext()
}
return ms.sc
}

// IsRecordingEvents always returns false for MockSpan.
func (ms *MockSpan) IsRecordingEvents() bool {
return false
}

// SetStatus does nothing.
func (ms *MockSpan) SetStatus(status codes.Code) {
}

// SetError does nothing.
func (ms *MockSpan) SetError(v bool) {
}

// SetAttribute does nothing.
func (ms *MockSpan) SetAttribute(attribute core.KeyValue) {
}

// SetAttributes does nothing.
func (ms *MockSpan) SetAttributes(attributes ...core.KeyValue) {
}

// ModifyAttribute does nothing.
func (ms *MockSpan) ModifyAttribute(mutator tag.Mutator) {
}

// ModifyAttributes does nothing.
func (ms *MockSpan) ModifyAttributes(mutators ...tag.Mutator) {
}

// Finish does nothing.
func (ms *MockSpan) Finish(options ...apitrace.FinishOption) {
}

// SetName does nothing.
func (ms *MockSpan) SetName(name string) {
}

// Tracer returns MockTracer implementation of Tracer.
func (ms *MockSpan) Tracer() apitrace.Tracer {
return ms.tracer
}

// AddEvent does nothing.
func (ms *MockSpan) AddEvent(ctx context.Context, msg string, attrs ...core.KeyValue) {
}

// AddLink does nothing.
func (ms *MockSpan) AddLink(link apitrace.Link) {
}

// Link does nothing.
func (ms *MockSpan) Link(sc core.SpanContext, attrs ...core.KeyValue) {
}
Loading

0 comments on commit 83935b2

Please sign in to comment.