Skip to content

Commit 54d715f

Browse files
committed
sdk/trace: removing ApplyConfig and Config
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, removes `WithSDK` functions from them, instead, introduces new functions, for instance, `WithResource`, `WithDefaultSampler`, and `WithSpanLimits`. Resolves #1636.
1 parent 62cbf0f commit 54d715f

File tree

12 files changed

+278
-126
lines changed

12 files changed

+278
-126
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2727
- `trace.NewSpanContext()` can be used in conjunction with the `trace.SpanContextConfig` struct to initialize a new `SpanContext` where all values are known.
2828
- Renamed the `LabelSet` method of `"go.opentelemetry.io/otel/sdk/resource".Resource` to `Set`. (#1692)
2929
- Jaeger exporter populates Jaeger's Span Process from Resource. (#1673)
30+
- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1693)
31+
- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1693)
32+
- Update zipkin export pipeline in `go.opentelemetry.io/otel/exporters/trace/zipkin` package to add resources specified by `WithResource` its tags. (#1693)
3033

3134
### Removed
3235

@@ -36,6 +39,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
3639
- Removed setting status to `Error` while recording an error as a span event in `RecordError`. (#1663)
3740
- Removed `WithConfig` from tracer provider to avoid overriding configuration. (#1633)
3841
- Removed `jaeger.WithProcess`. (#1673)
42+
- Removed `ApplyConfig` method and `Config` struct from tracer provider. (#1693)
3943

4044
### Fixed
4145

example/jaeger/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func initTracer() func() {
4242
attribute.Float64("float", 312.23),
4343
),
4444
}),
45+
jaeger.WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
4546
)
4647
if err != nil {
4748
log.Fatal(err)

example/zipkin/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func initTracer(url string) func() {
4242
url,
4343
"zipkin-test",
4444
zipkin.WithLogger(logger),
45-
zipkin.WithSDK(&sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
45+
zipkin.WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
4646
)
4747
if err != nil {
4848
log.Fatal(err)

exporters/trace/jaeger/jaeger.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ type options struct {
5252
// BatchMaxCount defines the maximum number of spans sent in one batch
5353
BatchMaxCount int
5454

55-
Config *sdktrace.Config
55+
// TracerProviderOptions defines the options for tracer provider of sdk.
56+
TracerProviderOptions []sdktrace.TracerProviderOption
5657

5758
Disabled bool
5859
}
@@ -71,10 +72,10 @@ func WithBatchMaxCount(batchMaxCount int) Option {
7172
}
7273
}
7374

74-
// WithSDK sets the SDK config for the exporter pipeline.
75-
func WithSDK(config *sdktrace.Config) Option {
75+
// WithSDKOptions configures options for tracer provider of sdk.
76+
func WithSDKOptions(opts ...sdktrace.TracerProviderOption) Option {
7677
return func(o *options) {
77-
o.Config = config
78+
o.TracerProviderOptions = opts
7879
}
7980
}
8081

@@ -157,15 +158,7 @@ func NewExportPipeline(endpointOption EndpointOption, opts ...Option) (trace.Tra
157158
return nil, nil, err
158159
}
159160

160-
pOpts := []sdktrace.TracerProviderOption{sdktrace.WithSyncer(exporter)}
161-
if exporter.o.Config != nil {
162-
pOpts = append(pOpts,
163-
sdktrace.WithDefaultSampler(exporter.o.Config.DefaultSampler),
164-
sdktrace.WithIDGenerator(exporter.o.Config.IDGenerator),
165-
sdktrace.WithSpanLimits(exporter.o.Config.SpanLimits),
166-
sdktrace.WithResource(exporter.o.Config.Resource),
167-
)
168-
}
161+
pOpts := append(exporter.o.TracerProviderOptions, sdktrace.WithSyncer(exporter))
169162
tp := sdktrace.NewTracerProvider(pOpts...)
170163
return tp, exporter.Flush, nil
171164
}

exporters/trace/jaeger/jaeger_test.go

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package jaeger
1717
import (
1818
"context"
1919
"encoding/binary"
20+
"fmt"
2021
"os"
2122
"sort"
2223
"strings"
@@ -114,9 +115,7 @@ func TestNewExportPipeline(t *testing.T) {
114115
name: "always on",
115116
endpoint: WithCollectorEndpoint(collectorEndpoint),
116117
options: []Option{
117-
WithSDK(&sdktrace.Config{
118-
DefaultSampler: sdktrace.AlwaysSample(),
119-
}),
118+
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
120119
},
121120
expectedProviderType: &sdktrace.TracerProvider{},
122121
testSpanSampling: true,
@@ -126,9 +125,7 @@ func TestNewExportPipeline(t *testing.T) {
126125
name: "never",
127126
endpoint: WithCollectorEndpoint(collectorEndpoint),
128127
options: []Option{
129-
WithSDK(&sdktrace.Config{
130-
DefaultSampler: sdktrace.NeverSample(),
131-
}),
128+
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.NeverSample())),
132129
},
133130
expectedProviderType: &sdktrace.TracerProvider{},
134131
testSpanSampling: true,
@@ -886,3 +883,81 @@ func TestProcess(t *testing.T) {
886883
})
887884
}
888885
}
886+
887+
type testCollectorEnpointWithSpans struct {
888+
spansUploaded *[]*gen.Span
889+
}
890+
891+
var _ batchUploader = (*testCollectorEnpointWithSpans)(nil)
892+
893+
func (c *testCollectorEnpointWithSpans) upload(batch *gen.Batch) error {
894+
*c.spansUploaded = append(*c.spansUploaded, batch.Spans...)
895+
return nil
896+
}
897+
898+
func withTestCollectorEnpointWithSpans(spansUploaded *[]*gen.Span) func() (batchUploader, error) {
899+
return func() (batchUploader, error) {
900+
return &testCollectorEnpointWithSpans{
901+
spansUploaded: spansUploaded,
902+
}, nil
903+
}
904+
}
905+
906+
func TestNewExporterPipelineWithOptions(t *testing.T) {
907+
envStore, err := ottest.SetEnvVariables(map[string]string{
908+
envDisabled: "false",
909+
})
910+
require.NoError(t, err)
911+
defer func() {
912+
require.NoError(t, envStore.Restore())
913+
}()
914+
915+
const (
916+
serviceName = "test-service"
917+
tagKey = "key"
918+
tagVal = "val"
919+
eventCountLimit = 10
920+
)
921+
922+
var uploadedSpans []*gen.Span
923+
tp, spanFlush, err := NewExportPipeline(
924+
withTestCollectorEnpointWithSpans(&uploadedSpans),
925+
WithSDKOptions(
926+
sdktrace.WithResource(resource.NewWithAttributes(
927+
semconv.ServiceNameKey.String(serviceName),
928+
attribute.String(tagKey, tagVal),
929+
)),
930+
sdktrace.WithSpanLimits(sdktrace.SpanLimits{
931+
EventCountLimit: eventCountLimit,
932+
}),
933+
),
934+
)
935+
assert.NoError(t, err)
936+
937+
otel.SetTracerProvider(tp)
938+
_, span := otel.Tracer("test-tracer").Start(context.Background(), "test-span")
939+
for i := 0; i < eventCountLimit*2; i++ {
940+
span.AddEvent(fmt.Sprintf("event-%d", i))
941+
}
942+
span.End()
943+
spanFlush()
944+
945+
assert.True(t, span.SpanContext().IsValid())
946+
947+
assert.True(t, len(uploadedSpans) == 1)
948+
uploadedSpan := uploadedSpans[0]
949+
assert.Equal(t, len(uploadedSpan.GetLogs()), eventCountLimit)
950+
assert.Condition(t, func() bool {
951+
tagFound := false
952+
serviceNameFound := false
953+
for _, tag := range uploadedSpan.GetTags() {
954+
if tag.GetKey() == tagKey && tag.GetVStr() == tagVal {
955+
tagFound = true
956+
}
957+
if tag.GetKey() == string(semconv.ServiceNameKey) && tag.GetVStr() == serviceName {
958+
serviceNameFound = true
959+
}
960+
}
961+
return tagFound && serviceNameFound
962+
})
963+
}

exporters/trace/zipkin/model.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ var extraZipkinTags = []string{
146146
}
147147

148148
func toZipkinTags(data *export.SpanSnapshot) map[string]string {
149-
m := make(map[string]string, len(data.Attributes)+len(extraZipkinTags))
149+
m := make(map[string]string, len(data.Attributes)+len(data.Resource.Attributes())+len(extraZipkinTags))
150+
for _, kv := range data.Resource.Attributes() {
151+
m[(string)(kv.Key)] = kv.Value.Emit()
152+
}
150153
for _, kv := range data.Attributes {
151154
m[(string)(kv.Key)] = kv.Value.Emit()
152155
}

exporters/trace/zipkin/zipkin.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ var (
5454
type options struct {
5555
client *http.Client
5656
logger *log.Logger
57-
config *sdktrace.Config
57+
tpOpts []sdktrace.TracerProviderOption
5858
}
5959

6060
// Option defines a function that configures the exporter.
@@ -74,10 +74,10 @@ func WithClient(client *http.Client) Option {
7474
}
7575
}
7676

77-
// WithSDK sets the SDK config for the exporter pipeline.
78-
func WithSDK(config *sdktrace.Config) Option {
79-
return func(o *options) {
80-
o.config = config
77+
// WithSDKOptions configures options for tracer provider of sdk.
78+
func WithSDKOptions(tpOpts ...sdktrace.TracerProviderOption) Option {
79+
return func(opts *options) {
80+
opts.tpOpts = tpOpts
8181
}
8282
}
8383

@@ -118,10 +118,8 @@ func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktr
118118
return nil, err
119119
}
120120

121-
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
122-
if exporter.o.config != nil {
123-
tp.ApplyConfig(*exporter.o.config)
124-
}
121+
tpOpts := append(exporter.o.tpOpts, sdktrace.WithBatcher(exporter))
122+
tp := sdktrace.NewTracerProvider(tpOpts...)
125123

126124
return tp, err
127125
}

exporters/trace/zipkin/zipkin_test.go

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ import (
3131
"github.com/stretchr/testify/require"
3232

3333
"go.opentelemetry.io/otel"
34+
"go.opentelemetry.io/otel/attribute"
3435
"go.opentelemetry.io/otel/codes"
3536
export "go.opentelemetry.io/otel/sdk/export/trace"
37+
"go.opentelemetry.io/otel/sdk/resource"
3638
sdktrace "go.opentelemetry.io/otel/sdk/trace"
39+
"go.opentelemetry.io/otel/semconv"
3740
"go.opentelemetry.io/otel/trace"
3841
)
3942

@@ -63,19 +66,15 @@ func TestNewExportPipeline(t *testing.T) {
6366
{
6467
name: "always on",
6568
options: []Option{
66-
WithSDK(&sdktrace.Config{
67-
DefaultSampler: sdktrace.AlwaysSample(),
68-
}),
69+
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.AlwaysSample())),
6970
},
7071
testSpanSampling: true,
7172
spanShouldBeSampled: true,
7273
},
7374
{
7475
name: "never",
7576
options: []Option{
76-
WithSDK(&sdktrace.Config{
77-
DefaultSampler: sdktrace.NeverSample(),
78-
}),
77+
WithSDKOptions(sdktrace.WithDefaultSampler(sdktrace.NeverSample())),
7978
},
8079
testSpanSampling: true,
8180
spanShouldBeSampled: false,
@@ -388,3 +387,47 @@ func TestErrorOnExportShutdownExporter(t *testing.T) {
388387
assert.NoError(t, exp.Shutdown(context.Background()))
389388
assert.NoError(t, exp.ExportSpans(context.Background(), nil))
390389
}
390+
391+
func TestNewExportPipelineWithOptions(t *testing.T) {
392+
const (
393+
tagKey = "key"
394+
tagVal = "val"
395+
eventCountLimit = 10
396+
)
397+
398+
collector := startMockZipkinCollector(t)
399+
defer collector.Close()
400+
401+
tp, err := NewExportPipeline(collector.url, serviceName,
402+
WithSDKOptions(
403+
sdktrace.WithResource(resource.NewWithAttributes(
404+
semconv.ServiceNameKey.String(serviceName),
405+
attribute.String(tagKey, tagVal),
406+
)),
407+
sdktrace.WithSpanLimits(sdktrace.SpanLimits{
408+
EventCountLimit: eventCountLimit,
409+
}),
410+
),
411+
)
412+
require.NoError(t, err)
413+
414+
otel.SetTracerProvider(tp)
415+
_, span := otel.Tracer("zipkin-tracer").Start(context.TODO(), "test-span")
416+
for i := 0; i < eventCountLimit*2; i++ {
417+
span.AddEvent(fmt.Sprintf("event-%d", i))
418+
}
419+
span.End()
420+
421+
err = tp.ForceFlush(context.TODO())
422+
require.NoError(t, err)
423+
424+
checkFunc := func() bool {
425+
return collector.ModelsLen() == 1
426+
}
427+
// It should wait for more than a default batch timeout of BatchSpanProcessor since Zipkin uses default options.
428+
require.Eventually(t, checkFunc, 10*time.Second, 10*time.Millisecond)
429+
model := collector.StealModels()[0]
430+
require.Equal(t, len(model.Annotations), eventCountLimit)
431+
require.Contains(t, model.Tags, tagKey)
432+
require.Contains(t, model.Tags, string(semconv.ServiceNameKey))
433+
}

sdk/trace/config.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,6 @@
1414

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

17-
import (
18-
"go.opentelemetry.io/otel/sdk/resource"
19-
)
20-
21-
// Config represents the global tracing configuration.
22-
type Config struct {
23-
// DefaultSampler is the default sampler used when creating new spans.
24-
DefaultSampler Sampler
25-
26-
// IDGenerator is for internal use only.
27-
IDGenerator IDGenerator
28-
29-
// SpanLimits used to limit the number of attributes, events and links to a span.
30-
SpanLimits SpanLimits
31-
32-
// Resource contains attributes representing an entity that produces telemetry.
33-
Resource *resource.Resource
34-
}
35-
3617
// SpanLimits represents the limits of a span.
3718
type SpanLimits struct {
3819
// AttributeCountLimit is the maximum allowed span attribute count.

0 commit comments

Comments
 (0)