Skip to content

Commit

Permalink
Make InMemorySpanRecorder public; use sampling.priority to turn sampl…
Browse files Browse the repository at this point in the history
…ing on and off (#30)
  • Loading branch information
yurishkuro committed Jul 1, 2016
1 parent 1050f2f commit f061a1a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 48 deletions.
51 changes: 51 additions & 0 deletions recorder.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,60 @@
package basictracer

import "sync"

// A SpanRecorder handles all of the `RawSpan` data generated via an
// associated `Tracer` (see `NewStandardTracer`) instance. It also names
// the containing process and provides access to a straightforward tag map.
type SpanRecorder interface {
// Implementations must determine whether and where to store `span`.
RecordSpan(span RawSpan)
}

// InMemorySpanRecorder is a simple thread-safe implementation of
// SpanRecorder that stores all reported spans in memory, accessible
// via reporter.GetSpans(). It is primarily intended for testing purposes.
type InMemorySpanRecorder struct {
sync.RWMutex
spans []RawSpan
}

// NewInMemoryRecorder creates new InMemorySpanRecorder
func NewInMemoryRecorder() *InMemorySpanRecorder {
return new(InMemorySpanRecorder)
}

// RecordSpan implements the respective method of SpanRecorder.
func (r *InMemorySpanRecorder) RecordSpan(span RawSpan) {
r.Lock()
defer r.Unlock()
r.spans = append(r.spans, span)
}

// GetSpans returns a copy of the array of spans accumulated so far.
func (r *InMemorySpanRecorder) GetSpans() []RawSpan {
r.RLock()
defer r.RUnlock()
spans := make([]RawSpan, len(r.spans))
copy(spans, r.spans)
return spans
}

// GetSampledSpans returns a slice of spans accumulated so far which were sampled.
func (r *InMemorySpanRecorder) GetSampledSpans() []RawSpan {
r.RLock()
defer r.RUnlock()
spans := make([]RawSpan, 0, len(r.spans))
for _, span := range r.spans {
if span.Sampled {
spans = append(spans, span)
}
}
return spans
}

// Reset clears the internal array of spans.
func (r *InMemorySpanRecorder) Reset() {
r.Lock()
defer r.Unlock()
r.spans = nil
}
45 changes: 4 additions & 41 deletions recorder_test.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,12 @@
package basictracer

import (
"reflect"
"sync"
"sync/atomic"
"testing"
"time"
)

// InMemoryRecorder is a simple thread-safe implementation of
// SpanRecorder that stores all reported spans in memory, accessible
// via reporter.GetSpans()
type InMemoryRecorder struct {
spans []RawSpan
lock sync.Mutex
}

// NewInMemoryRecorder instantiates a new InMemoryRecorder for testing purposes.
func NewInMemoryRecorder() *InMemoryRecorder {
return &InMemoryRecorder{
spans: make([]RawSpan, 0),
}
}

// RecordSpan implements RecordSpan() of SpanRecorder.
//
// The recorded spans can be retrieved via recorder.Spans slice.
func (recorder *InMemoryRecorder) RecordSpan(span RawSpan) {
recorder.lock.Lock()
defer recorder.lock.Unlock()
recorder.spans = append(recorder.spans, span)
}

// GetSpans returns a snapshot of spans recorded so far.
func (recorder *InMemoryRecorder) GetSpans() []RawSpan {
recorder.lock.Lock()
defer recorder.lock.Unlock()
spans := make([]RawSpan, len(recorder.spans))
copy(spans, recorder.spans)
return spans
}
"github.com/stretchr/testify/assert"
)

func TestInMemoryRecorderSpans(t *testing.T) {
recorder := NewInMemoryRecorder()
Expand All @@ -51,12 +18,8 @@ func TestInMemoryRecorderSpans(t *testing.T) {
Duration: -1,
}
apiRecorder.RecordSpan(span)
if len(recorder.GetSpans()) != 1 {
t.Fatal("No spans recorded")
}
if !reflect.DeepEqual(recorder.GetSpans()[0], span) {
t.Fatal("Span not recorded")
}
assert.Equal(t, []RawSpan{span}, recorder.GetSpans())
assert.Equal(t, []RawSpan{}, recorder.GetSampledSpans())
}

type CountingRecorder int32
Expand Down
6 changes: 4 additions & 2 deletions span.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ func (s *spanImpl) SetTag(key string, value interface{}) opentracing.Span {
s.Lock()
defer s.Unlock()
if key == string(ext.SamplingPriority) {
s.raw.Sampled = true
return s
if v, ok := value.(uint16); ok {
s.raw.Sampled = v != 0
return s
}
}
if s.trim() {
return s
Expand Down
11 changes: 6 additions & 5 deletions tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ type Options struct {
// all options disabled. A Recorder needs to be set manually before using the
// returned object with a Tracer.
func DefaultOptions() Options {
var opts Options
opts.ShouldSample = func(traceID uint64) bool { return traceID%64 == 0 }
opts.NewSpanEventListener = func() func(SpanEvent) { return nil }
return opts
return Options{
ShouldSample: func(traceID uint64) bool { return traceID%64 == 0 },
}
}

// NewWithOptions creates a customized Tracer.
Expand Down Expand Up @@ -185,7 +184,9 @@ func (t *tracerImpl) startSpanInternal(
tags opentracing.Tags,
) opentracing.Span {
sp.tracer = t
sp.event = t.options.NewSpanEventListener()
if t.options.NewSpanEventListener != nil {
sp.event = t.options.NewSpanEventListener()
}
sp.raw.Operation = operationName
sp.raw.Start = startTime
sp.raw.Duration = -1
Expand Down

0 comments on commit f061a1a

Please sign in to comment.