Skip to content

Commit

Permalink
sdk/trace: removing ApplyConfig and Config
Browse files Browse the repository at this point in the history
This patch removes `ApplyConfig` method and `Config` struct from
`go.opentelemetry.io/otel/sdk/trace` package.  To ensure valid config
for TracerProvider, it adds `ensureValidTracerProviderConfig` private
function.
Jaeger and Zipkin have been used the `Config` directly across package
boundaries. Since `Config` is removed, they can't use it. This change,
thus, replcae `WithSDK` with `WithSDKOptions`.

Resolves open-telemetry#1636.
  • Loading branch information
ijsong committed Mar 18, 2021
1 parent 0fe65e6 commit d52d8db
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 136 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Jaeger exporter populates Jaeger's Span Process from Resource. (#1673)
- `"go.opentelemetry.io/otel/sdk/resource".NewWithAttributes` will now drop any invalid attributes passed. (#1703)
- `"go.opentelemetry.io/otel/sdk/resource".StringDetector` will now error if the produced attribute is invalid. (#1703)
- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1693)
- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1693)

### Removed

Expand All @@ -40,6 +42,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Removed `WithConfig` from tracer provider to avoid overriding configuration. (#1633)
- Removed `serviceName` parameter from Zipkin exporter and uses resource instead. (#1549)
- Removed `jaeger.WithProcess`. (#1673)
- Removed `ApplyConfig` method and `Config` struct from tracer provider. (#1693)

### Fixed

Expand Down
10 changes: 5 additions & 5 deletions example/jaeger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ func initTracer() func() {
// Create and install Jaeger export pipeline.
flush, err := jaeger.InstallNewPipeline(
jaeger.WithCollectorEndpoint("http://localhost:14268/api/traces"),
jaeger.WithSDK(&sdktrace.Config{
DefaultSampler: sdktrace.AlwaysSample(),
Resource: resource.NewWithAttributes(
jaeger.WithSDKOptions(
sdktrace.WithDefaultSampler(sdktrace.AlwaysSample()),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.ServiceNameKey.String("trace-demo"),
attribute.String("exporter", "jaeger"),
attribute.Float64("float", 312.23),
),
}),
)),
),
)
if err != nil {
log.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion example/zipkin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func initTracer(url string) func() {
exporter, err := zipkin.NewRawExporter(
url,
zipkin.WithLogger(logger),
zipkin.WithSDK(&sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
zipkin.WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
)
if err != nil {
log.Fatal(err)
Expand Down
19 changes: 6 additions & 13 deletions exporters/trace/jaeger/jaeger.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ type options struct {
// BatchMaxCount defines the maximum number of spans sent in one batch
BatchMaxCount int

Config *sdktrace.Config
// TracerProviderOptions defines the options for tracer provider of sdk.
TracerProviderOptions []sdktrace.TracerProviderOption

Disabled bool
}
Expand All @@ -71,10 +72,10 @@ func WithBatchMaxCount(batchMaxCount int) Option {
}
}

// WithSDK sets the SDK config for the exporter pipeline.
func WithSDK(config *sdktrace.Config) Option {
// WithSDKOptions configures options for tracer provider of sdk.
func WithSDKOptions(opts ...sdktrace.TracerProviderOption) Option {
return func(o *options) {
o.Config = config
o.TracerProviderOptions = opts
}
}

Expand Down Expand Up @@ -157,15 +158,7 @@ func NewExportPipeline(endpointOption EndpointOption, opts ...Option) (trace.Tra
return nil, nil, err
}

pOpts := []sdktrace.TracerProviderOption{sdktrace.WithSyncer(exporter)}
if exporter.o.Config != nil {
pOpts = append(pOpts,
sdktrace.WithDefaultSampler(exporter.o.Config.DefaultSampler),
sdktrace.WithIDGenerator(exporter.o.Config.IDGenerator),
sdktrace.WithSpanLimits(exporter.o.Config.SpanLimits),
sdktrace.WithResource(exporter.o.Config.Resource),
)
}
pOpts := append(exporter.o.TracerProviderOptions, sdktrace.WithSyncer(exporter))
tp := sdktrace.NewTracerProvider(pOpts...)
return tp, exporter.Flush, nil
}
Expand Down
77 changes: 64 additions & 13 deletions exporters/trace/jaeger/jaeger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package jaeger
import (
"context"
"encoding/binary"
"fmt"
"os"
"sort"
"strings"
Expand Down Expand Up @@ -114,9 +115,7 @@ func TestNewExportPipeline(t *testing.T) {
name: "always on",
endpoint: WithCollectorEndpoint(collectorEndpoint),
options: []Option{
WithSDK(&sdktrace.Config{
DefaultSampler: sdktrace.AlwaysSample(),
}),
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
},
expectedProviderType: &sdktrace.TracerProvider{},
testSpanSampling: true,
Expand All @@ -126,9 +125,7 @@ func TestNewExportPipeline(t *testing.T) {
name: "never",
endpoint: WithCollectorEndpoint(collectorEndpoint),
options: []Option{
WithSDK(&sdktrace.Config{
DefaultSampler: sdktrace.NeverSample(),
}),
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.NeverSample())),
},
expectedProviderType: &sdktrace.TracerProvider{},
testSpanSampling: true,
Expand Down Expand Up @@ -281,11 +278,11 @@ func TestNewRawExporterShouldFailIfCollectorUnset(t *testing.T) {
}

type testCollectorEnpoint struct {
spansUploaded []*gen.Span
batchesUploaded []*gen.Batch
}

func (c *testCollectorEnpoint) upload(batch *gen.Batch) error {
c.spansUploaded = append(c.spansUploaded, batch.Spans...)
c.batchesUploaded = append(c.batchesUploaded, batch)
return nil
}

Expand All @@ -297,6 +294,12 @@ func withTestCollectorEndpoint() func() (batchUploader, error) {
}
}

func withTestCollectorEndpointInjected(ce *testCollectorEnpoint) func() (batchUploader, error) {
return func() (batchUploader, error) {
return ce, nil
}
}

func TestExporter_ExportSpan(t *testing.T) {
const (
serviceName = "test-service"
Expand All @@ -306,12 +309,12 @@ func TestExporter_ExportSpan(t *testing.T) {
// Create Jaeger Exporter
exp, err := NewRawExporter(
withTestCollectorEndpoint(),
WithSDK(&sdktrace.Config{
Resource: resource.NewWithAttributes(
WithSDKOptions(
sdktrace.WithResource(resource.NewWithAttributes(
semconv.ServiceNameKey.String(serviceName),
attribute.String(tagKey, tagVal),
),
}),
)),
),
)

assert.NoError(t, err)
Expand All @@ -328,7 +331,8 @@ func TestExporter_ExportSpan(t *testing.T) {

exp.Flush()
tc := exp.uploader.(*testCollectorEnpoint)
assert.True(t, len(tc.spansUploaded) == 1)
assert.True(t, len(tc.batchesUploaded) == 1)
assert.True(t, len(tc.batchesUploaded[0].GetSpans()) == 1)
}

func Test_spanSnapshotToThrift(t *testing.T) {
Expand Down Expand Up @@ -886,3 +890,50 @@ func TestProcess(t *testing.T) {
})
}
}

func TestNewExporterPipelineWithOptions(t *testing.T) {
envStore, err := ottest.SetEnvVariables(map[string]string{
envDisabled: "false",
})
require.NoError(t, err)
defer func() {
require.NoError(t, envStore.Restore())
}()

const (
serviceName = "test-service"
eventCountLimit = 10
)

testCollector := &testCollectorEnpoint{}
tp, spanFlush, err := NewExportPipeline(
withTestCollectorEndpointInjected(testCollector),
WithSDKOptions(
sdktrace.WithResource(resource.NewWithAttributes(
semconv.ServiceNameKey.String(serviceName),
)),
sdktrace.WithSpanLimits(sdktrace.SpanLimits{
EventCountLimit: eventCountLimit,
}),
),
)
assert.NoError(t, err)

otel.SetTracerProvider(tp)
_, span := otel.Tracer("test-tracer").Start(context.Background(), "test-span")
for i := 0; i < eventCountLimit*2; i++ {
span.AddEvent(fmt.Sprintf("event-%d", i))
}
span.End()
spanFlush()

assert.True(t, span.SpanContext().IsValid())

batchesUploaded := testCollector.batchesUploaded
assert.True(t, len(batchesUploaded) == 1)
uploadedBatch := batchesUploaded[0]
assert.Equal(t, serviceName, uploadedBatch.GetProcess().GetServiceName())
assert.True(t, len(uploadedBatch.GetSpans()) == 1)
uploadedSpan := uploadedBatch.GetSpans()[0]
assert.Equal(t, eventCountLimit, len(uploadedSpan.GetLogs()))
}
16 changes: 7 additions & 9 deletions exporters/trace/zipkin/zipkin.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var (
type options struct {
client *http.Client
logger *log.Logger
config *sdktrace.Config
tpOpts []sdktrace.TracerProviderOption
}

// Option defines a function that configures the exporter.
Expand All @@ -73,10 +73,10 @@ func WithClient(client *http.Client) Option {
}
}

// WithSDK sets the SDK config for the exporter pipeline.
func WithSDK(config *sdktrace.Config) Option {
return func(o *options) {
o.config = config
// WithSDKOptions configures options passed to the created TracerProvider.
func WithSDKOptions(tpOpts ...sdktrace.TracerProviderOption) Option {
return func(opts *options) {
opts.tpOpts = tpOpts
}
}

Expand Down Expand Up @@ -116,10 +116,8 @@ func NewExportPipeline(collectorURL string, opts ...Option) (*sdktrace.TracerPro
return nil, err
}

tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
if exporter.o.config != nil {
tp.ApplyConfig(*exporter.o.config)
}
tpOpts := append(exporter.o.tpOpts, sdktrace.WithBatcher(exporter))
tp := sdktrace.NewTracerProvider(tpOpts...)

return tp, err
}
Expand Down
43 changes: 37 additions & 6 deletions exporters/trace/zipkin/zipkin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,15 @@ func TestNewExportPipeline(t *testing.T) {
{
name: "always on",
options: []Option{
WithSDK(&sdktrace.Config{
DefaultSampler: sdktrace.AlwaysSample(),
}),
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
},
testSpanSampling: true,
spanShouldBeSampled: true,
},
{
name: "never",
options: []Option{
WithSDK(&sdktrace.Config{
DefaultSampler: sdktrace.NeverSample(),
}),
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.NeverSample())),
},
testSpanSampling: true,
spanShouldBeSampled: false,
Expand Down Expand Up @@ -389,3 +385,38 @@ func TestErrorOnExportShutdownExporter(t *testing.T) {
assert.NoError(t, exp.Shutdown(context.Background()))
assert.NoError(t, exp.ExportSpans(context.Background(), nil))
}

func TestNewExportPipelineWithOptions(t *testing.T) {
const eventCountLimit = 10

collector := startMockZipkinCollector(t)
defer collector.Close()

tp, err := NewExportPipeline(collector.url,
WithSDKOptions(
sdktrace.WithResource(resource.NewWithAttributes(
semconv.ServiceNameKey.String("zipkin-test"),
)),
sdktrace.WithSpanLimits(sdktrace.SpanLimits{
EventCountLimit: eventCountLimit,
}),
),
)
require.NoError(t, err)

otel.SetTracerProvider(tp)
_, span := otel.Tracer("zipkin-tracer").Start(context.Background(), "test-span")
for i := 0; i < eventCountLimit*2; i++ {
span.AddEvent(fmt.Sprintf("event-%d", i))
}
span.End()

require.NoError(t, tp.Shutdown(context.Background()))

checkFunc := func() bool {
return collector.ModelsLen() == 1
}
require.Eventually(t, checkFunc, time.Second, 10*time.Millisecond)
model := collector.StealModels()[0]
require.Equal(t, len(model.Annotations), eventCountLimit)
}
37 changes: 18 additions & 19 deletions sdk/trace/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,6 @@

package trace // import "go.opentelemetry.io/otel/sdk/trace"

import (
"go.opentelemetry.io/otel/sdk/resource"
)

// Config represents the global tracing configuration.
type Config struct {
// DefaultSampler is the default sampler used when creating new spans.
DefaultSampler Sampler

// IDGenerator is for internal use only.
IDGenerator IDGenerator

// SpanLimits used to limit the number of attributes, events and links to a span.
SpanLimits SpanLimits

// Resource contains attributes representing an entity that produces telemetry.
Resource *resource.Resource
}

// SpanLimits represents the limits of a span.
type SpanLimits struct {
// AttributeCountLimit is the maximum allowed span attribute count.
Expand All @@ -51,6 +32,24 @@ type SpanLimits struct {
AttributePerLinkCountLimit int
}

func (sl *SpanLimits) ensureDefault() {
if sl.EventCountLimit <= 0 {
sl.EventCountLimit = DefaultEventCountLimit
}
if sl.AttributeCountLimit <= 0 {
sl.AttributeCountLimit = DefaultAttributeCountLimit
}
if sl.LinkCountLimit <= 0 {
sl.LinkCountLimit = DefaultLinkCountLimit
}
if sl.AttributePerEventCountLimit <= 0 {
sl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit
}
if sl.AttributePerLinkCountLimit <= 0 {
sl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit
}
}

const (
// DefaultAttributeCountLimit is the default maximum allowed span attribute count.
DefaultAttributeCountLimit = 128
Expand Down
Loading

0 comments on commit d52d8db

Please sign in to comment.