Skip to content

Commit fe0099f

Browse files
matej-grghetiajmacd
authoredMar 10, 2020
[tracing] add simplified export pipeline setup for Jaeger (#459)
* add simplified export pipeline setup for Jaeger * add With* options to configure SDK options. * add test for WithRegistration and WithSDK * rename Registeration with RegisterGlobal * rename WithRegistration to RegisterAsGlobal Co-authored-by: rahulpa <rahulpa@google.com> Co-authored-by: Joshua MacDonald <jmacd@users.noreply.github.com>
1 parent 8cddf30 commit fe0099f

File tree

3 files changed

+111
-25
lines changed

3 files changed

+111
-25
lines changed
 

‎example/jaeger/main.go

+5-13
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ import (
3030

3131
// initTracer creates a new trace provider instance and registers it as global trace provider.
3232
func initTracer() func() {
33-
// Create Jaeger Exporter
34-
exporter, err := jaeger.NewExporter(
33+
// Create and install Jaeger export pipeline
34+
_, flush, err := jaeger.NewExportPipeline(
3535
jaeger.WithCollectorEndpoint("http://localhost:14268/api/traces"),
3636
jaeger.WithProcess(jaeger.Process{
3737
ServiceName: "trace-demo",
@@ -40,23 +40,15 @@ func initTracer() func() {
4040
key.Float64("float", 312.23),
4141
},
4242
}),
43+
jaeger.RegisterAsGlobal(),
44+
jaeger.WithSDK(&sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
4345
)
4446
if err != nil {
4547
log.Fatal(err)
4648
}
4749

48-
// For demoing purposes, always sample. In a production application, you should
49-
// configure this to a trace.ProbabilitySampler set at the desired
50-
// probability.
51-
tp, err := sdktrace.NewProvider(
52-
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
53-
sdktrace.WithSyncer(exporter))
54-
if err != nil {
55-
log.Fatal(err)
56-
}
57-
global.SetTraceProvider(tp)
5850
return func() {
59-
exporter.Flush()
51+
flush()
6052
}
6153
}
6254

‎exporters/trace/jaeger/jaeger.go

+49-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import (
2323
"google.golang.org/grpc/codes"
2424

2525
"go.opentelemetry.io/otel/api/core"
26+
"go.opentelemetry.io/otel/api/global"
2627
gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger"
2728
export "go.opentelemetry.io/otel/sdk/export/trace"
29+
sdktrace "go.opentelemetry.io/otel/sdk/trace"
2830
)
2931

3032
const defaultServiceName = "OpenTelemetry"
@@ -43,6 +45,12 @@ type options struct {
4345

4446
//BufferMaxCount defines the total number of traces that can be buffered in memory
4547
BufferMaxCount int
48+
49+
Config *sdktrace.Config
50+
51+
// RegisterGlobal is set to true if the trace provider of the new pipeline should be
52+
// registered as Global Trace Provider
53+
RegisterGlobal bool
4654
}
4755

4856
// WithOnError sets the hook to be called when there is
@@ -68,9 +76,24 @@ func WithBufferMaxCount(bufferMaxCount int) func(o *options) {
6876
}
6977
}
7078

71-
// NewExporter returns a trace.Exporter implementation that exports
79+
// WithSDK sets the SDK config for the exporter pipeline.
80+
func WithSDK(config *sdktrace.Config) func(o *options) {
81+
return func(o *options) {
82+
o.Config = config
83+
}
84+
}
85+
86+
// RegisterAsGlobal enables the registration of the trace provider of the new pipeline
87+
// as Global Trace Provider.
88+
func RegisterAsGlobal() func(o *options) {
89+
return func(o *options) {
90+
o.RegisterGlobal = true
91+
}
92+
}
93+
94+
// NewRawExporter returns a trace.Exporter implementation that exports
7295
// the collected spans to Jaeger.
73-
func NewExporter(endpointOption EndpointOption, opts ...Option) (*Exporter, error) {
96+
func NewRawExporter(endpointOption EndpointOption, opts ...Option) (*Exporter, error) {
7497
uploader, err := endpointOption()
7598
if err != nil {
7699
return nil, err
@@ -105,6 +128,7 @@ func NewExporter(endpointOption EndpointOption, opts ...Option) (*Exporter, erro
105128
ServiceName: service,
106129
Tags: tags,
107130
},
131+
o: o,
108132
}
109133
bundler := bundler.NewBundler((*gen.Span)(nil), func(bundle interface{}) {
110134
if err := e.upload(bundle.([]*gen.Span)); err != nil {
@@ -123,6 +147,28 @@ func NewExporter(endpointOption EndpointOption, opts ...Option) (*Exporter, erro
123147
return e, nil
124148
}
125149

150+
// NewExportPipeline sets up a complete export pipeline
151+
// with the recommended setup for trace provider
152+
func NewExportPipeline(endpointOption EndpointOption, opts ...Option) (*sdktrace.Provider, func(), error) {
153+
exporter, err := NewRawExporter(endpointOption, opts...)
154+
if err != nil {
155+
return nil, nil, err
156+
}
157+
syncer := sdktrace.WithSyncer(exporter)
158+
tp, err := sdktrace.NewProvider(syncer)
159+
if err != nil {
160+
return nil, nil, err
161+
}
162+
if exporter.o.Config != nil {
163+
tp.ApplyConfig(*exporter.o.Config)
164+
}
165+
if exporter.o.RegisterGlobal {
166+
global.SetTraceProvider(tp)
167+
}
168+
169+
return tp, exporter.Flush, nil
170+
}
171+
126172
// Process contains the information exported to jaeger about the source
127173
// of the trace data.
128174
type Process struct {
@@ -138,6 +184,7 @@ type Exporter struct {
138184
process *gen.Process
139185
bundler *bundler.Bundler
140186
uploader batchUploader
187+
o options
141188
}
142189

143190
var _ export.SpanSyncer = (*Exporter)(nil)

‎exporters/trace/jaeger/jaeger_test.go

+57-10
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,62 @@ import (
3737
export "go.opentelemetry.io/otel/sdk/export/trace"
3838
)
3939

40-
func TestNewExporter(t *testing.T) {
40+
func TestNewExporterPipelineWithRegistration(t *testing.T) {
41+
tp, fn, err := NewExportPipeline(
42+
WithCollectorEndpoint("http://localhost:14268/api/traces"),
43+
RegisterAsGlobal(),
44+
)
45+
defer fn()
46+
assert.NoError(t, err)
47+
assert.Same(t, tp, global.TraceProvider())
48+
}
49+
50+
func TestNewExporterPipelineWithoutRegistration(t *testing.T) {
51+
tp, fn, err := NewExportPipeline(
52+
WithCollectorEndpoint("http://localhost:14268/api/traces"),
53+
)
54+
defer fn()
55+
assert.NoError(t, err)
56+
assert.NotEqual(t, tp, global.TraceProvider())
57+
}
58+
59+
func TestNewExporterPipelineWithSDK(t *testing.T) {
60+
tp, fn, err := NewExportPipeline(
61+
WithCollectorEndpoint("http://localhost:14268/api/traces"),
62+
WithSDK(&sdktrace.Config{
63+
DefaultSampler: sdktrace.AlwaysSample(),
64+
}),
65+
)
66+
defer fn()
67+
assert.NoError(t, err)
68+
_, span := tp.Tracer("jaeger test").Start(context.Background(), "always-on")
69+
spanCtx := span.SpanContext()
70+
assert.True(t, spanCtx.IsSampled())
71+
span.End()
72+
73+
tp2, fn, err := NewExportPipeline(
74+
WithCollectorEndpoint("http://localhost:14268/api/traces"),
75+
WithSDK(&sdktrace.Config{
76+
DefaultSampler: sdktrace.NeverSample(),
77+
}),
78+
)
79+
defer fn()
80+
assert.NoError(t, err)
81+
_, span2 := tp2.Tracer("jaeger test").Start(context.Background(), "never")
82+
span2Ctx := span2.SpanContext()
83+
assert.False(t, span2Ctx.IsSampled())
84+
span2.End()
85+
}
86+
87+
func TestNewRawExporter(t *testing.T) {
4188
const (
4289
collectorEndpoint = "http://localhost"
4390
serviceName = "test-service"
4491
tagKey = "key"
4592
tagVal = "val"
4693
)
4794
// Create Jaeger Exporter
48-
exp, err := NewExporter(
95+
exp, err := NewRawExporter(
4996
WithCollectorEndpoint(collectorEndpoint),
5097
WithProcess(Process{
5198
ServiceName: serviceName,
@@ -60,8 +107,8 @@ func TestNewExporter(t *testing.T) {
60107
assert.Len(t, exp.process.Tags, 1)
61108
}
62109

63-
func TestNewExporterShouldFailIfCollectorEndpointEmpty(t *testing.T) {
64-
_, err := NewExporter(
110+
func TestNewRawExporterShouldFailIfCollectorEndpointEmpty(t *testing.T) {
111+
_, err := NewRawExporter(
65112
WithCollectorEndpoint(""),
66113
)
67114

@@ -92,7 +139,7 @@ func TestExporter_ExportSpan(t *testing.T) {
92139
tagVal = "val"
93140
)
94141
// Create Jaeger Exporter
95-
exp, err := NewExporter(
142+
exp, err := NewRawExporter(
96143
withTestCollectorEndpoint(),
97144
WithProcess(Process{
98145
ServiceName: serviceName,
@@ -121,24 +168,24 @@ func TestExporter_ExportSpan(t *testing.T) {
121168
assert.True(t, len(tc.spansUploaded) == 1)
122169
}
123170

124-
func TestNewExporterWithAgentEndpoint(t *testing.T) {
171+
func TestNewRawExporterWithAgentEndpoint(t *testing.T) {
125172
const agentEndpoint = "localhost:6831"
126173
// Create Jaeger Exporter
127-
_, err := NewExporter(
174+
_, err := NewRawExporter(
128175
WithAgentEndpoint(agentEndpoint),
129176
)
130177
assert.NoError(t, err)
131178
}
132179

133-
func TestNewExporterWithAgentShouldFailIfEndpointInvalid(t *testing.T) {
180+
func TestNewRawExporterWithAgentShouldFailIfEndpointInvalid(t *testing.T) {
134181
//empty
135-
_, err := NewExporter(
182+
_, err := NewRawExporter(
136183
WithAgentEndpoint(""),
137184
)
138185
assert.Error(t, err)
139186

140187
//invalid endpoint addr
141-
_, err = NewExporter(
188+
_, err = NewRawExporter(
142189
WithAgentEndpoint("http://localhost"),
143190
)
144191
assert.Error(t, err)

0 commit comments

Comments
 (0)
Please sign in to comment.