Skip to content

Commit 029d7ad

Browse files
committed
Fix issue #1490, apply same logic as in the SDK
Signed-off-by: Bogdan Drutu <[email protected]>
1 parent 9d3416c commit 029d7ad

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
3838
- `SamplingResult.TraceState` is correctly propagated to a newly created
3939
span's `SpanContext`. (#1655)
4040
- Jaeger Exporter: Ensure mapping between OTEL and Jaeger span data complies with the specification. (#1626)
41+
<<<<<<< HEAD
42+
<<<<<<< HEAD
4143
- The `otel-collector` example now correctly flushes metric events prior to shutting down the exporter. (#1678)
4244
- Synchronization issues in global trace delegate implementation. (#1686)
43-
44-
### Fixed
4545
- Do not set span status message in `SpanStatusFromHTTPStatusCode` if it can be inferred from `http.status_code`. (#1681)
46+
- Reduced excess memory usage by global `TracerProvider`. (#1687)
4647

4748
## [0.18.0] - 2020-03-03
4849

internal/global/trace.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import (
4646
// configured.
4747
type tracerProvider struct {
4848
mtx sync.Mutex
49-
tracers []*tracer
49+
tracers map[il]*tracer
5050
delegate trace.TracerProvider
5151
}
5252

@@ -66,6 +66,11 @@ func (p *tracerProvider) setDelegate(provider trace.TracerProvider) {
6666
defer p.mtx.Unlock()
6767

6868
p.delegate = provider
69+
70+
if len(p.tracers) == 0 {
71+
return
72+
}
73+
6974
for _, t := range p.tracers {
7075
t.setDelegate(provider)
7176
}
@@ -82,11 +87,31 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
8287
return p.delegate.Tracer(name, opts...)
8388
}
8489

90+
// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.
91+
92+
key := il{
93+
name: name,
94+
version: trace.NewTracerConfig(opts...).InstrumentationVersion,
95+
}
96+
97+
if p.tracers == nil {
98+
p.tracers = make(map[il]*tracer)
99+
}
100+
101+
if val, ok := p.tracers[key]; ok {
102+
return val
103+
}
104+
85105
t := &tracer{name: name, opts: opts}
86-
p.tracers = append(p.tracers, t)
106+
p.tracers[key] = t
87107
return t
88108
}
89109

110+
type il struct {
111+
name string
112+
version string
113+
}
114+
90115
// tracer is a placeholder for a trace.Tracer.
91116
//
92117
// All Tracer functionality is forwarded to a delegate once configured.

internal/global/trace_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,21 @@ func TestTracerDelegatesConcurrentSafe(t *testing.T) {
195195

196196
assert.LessOrEqual(t, int32(10), atomic.LoadInt32(&called), "expected configured TraceProvider to be called")
197197
}
198+
199+
func TestTraceProviderDelegatesSameInstance(t *testing.T) {
200+
global.ResetForTest()
201+
202+
// Retrieve the placeholder TracerProvider.
203+
gtp := otel.GetTracerProvider()
204+
tracer := gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz"))
205+
assert.Same(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz")))
206+
assert.Same(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz")))
207+
208+
otel.SetTracerProvider(fnTracerProvider{
209+
tracer: func(name string, opts ...trace.TracerOption) trace.Tracer {
210+
return trace.NewNoopTracerProvider().Tracer("")
211+
},
212+
})
213+
214+
assert.NotSame(t, tracer, gtp.Tracer("abc", trace.WithInstrumentationVersion("xyz")))
215+
}

0 commit comments

Comments
 (0)