<commit_before>package tracer

import (
	"sync"
	"time"

	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
)

type Span struct {
	sync.Mutex
	emitter       Emitter
	operationName string
	tracer        *Tracer
	fields        map[string]log.Field
	startedAt     time.Time
	baggage       map[string]string
	tags          map[string]interface{}
}

func (s *Span) clone() *Span {
	var fields map[string]log.Field
	if s.fields != nil {
		fields = make(map[string]log.Field, len(s.fields))
		for k, v := range s.fields {
			fields[k] = v
		}
	}

	var baggage map[string]string
	if s.baggage != nil {
		baggage = make(map[string]string, len(s.baggage))
		for k, v := range baggage {
			baggage[k] = v
		}
	}

	return &Span{
		emitter:       s.emitter,
		operationName: s.operationName,
		tracer:        s.tracer,
		fields:        fields,
		startedAt:     time.Now(),
		baggage:       baggage,
	}
}

// Sets the end timestamp and finalizes Span state.
//
// With the exception of calls to Context() (which are always allowed),
// Finish() must be the last call made to any span instance, and to do
// otherwise leads to undefined behavior.
func (s *Span) Finish() {
	s.FinishWithOptions(opentracing.FinishOptions{
		FinishTime: time.Now(),
	})
}

// FinishWithOptions is like Finish() but with explicit control over
// timestamps and log data.
func (s *Span) FinishWithOptions(opts opentracing.FinishOptions) {
	if opts.LogRecords != nil {
		for _, record := range opts.LogRecords {
			s.emitter.Emit(s, "", record.Fields...)
		}
	}

	s.emitter.Emit(s, s.operationName)
}

// Context() yields the SpanContext for this Span. Note that the return
// value of Context() is still valid after a call to Span.Finish(), as is
// a call to Span.Context() after a call to Span.Finish().
func (s *Span) Context() opentracing.SpanContext {
	return s
}

// Sets or changes the operation name.
func (s *Span) SetOperationName(operationName string) opentracing.Span {
	dupe := s.clone()
	dupe.operationName = operationName
	return dupe
}

// Adds a tag to the span.
//
// If there is a pre-existing tag set for `key`, it is overwritten.
//
// Tag values can be numeric types, strings, or bools. The behavior of
// other tag value types is undefined at the OpenTracing level. If a
// tracing system does not know how to handle a particular value type, it
// may ignore the tag, but shall not panic.
func (s *Span) SetTag(key string, value interface{}) opentracing.Span {
	s.Lock()
	defer s.Unlock()

	if s.tags == nil {<commit_msg>- finished records elapsed time<commit_after>package tracer

import (
	"sync"
	"time"

	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
)

type Span struct {
	sync.Mutex
	emitter       Emitter
	operationName string
	tracer        *Tracer
	fields        map[string]log.Field
	startedAt     time.Time
	baggage       map[string]string
	tags          map[string]interface{}
}

func (s *Span) clone() *Span {
	var fields map[string]log.Field
	if s.fields != nil {
		fields = make(map[string]log.Field, len(s.fields))
		for k, v := range s.fields {
			fields[k] = v
		}
	}

	var baggage map[string]string
	if s.baggage != nil {
		baggage = make(map[string]string, len(s.baggage))
		for k, v := range baggage {
			baggage[k] = v
		}
	}

	return &Span{
		emitter:       s.emitter,
		operationName: s.operationName,
		tracer:        s.tracer,
		fields:        fields,
		startedAt:     time.Now(),
		baggage:       baggage,
	}
}

// Sets the end timestamp and finalizes Span state.
//
// With the exception of calls to Context() (which are always allowed),
// Finish() must be the last call made to any span instance, and to do
// otherwise leads to undefined behavior.
func (s *Span) Finish() {
	s.FinishWithOptions(opentracing.FinishOptions{
		FinishTime: time.Now(),
	})
}

// FinishWithOptions is like Finish() but with explicit control over
// timestamps and log data.
func (s *Span) FinishWithOptions(opts opentracing.FinishOptions) {
	if opts.LogRecords != nil {
		for _, record := range opts.LogRecords {
			s.emitter.Emit(s, "", record.Fields...)
		}
	}

	elapsed := time.Now().Sub(s.startedAt) / time.Millisecond
	s.emitter.Emit(s, s.operationName, log.Int64("elapsed", int64(elapsed)))
}

// Context() yields the SpanContext for this Span. Note that the return
// value of Context() is still valid after a call to Span.Finish(), as is
// a call to Span.Context() after a call to Span.Finish().
func (s *Span) Context() opentracing.SpanContext {
	return s
}

// Sets or changes the operation name.
func (s *Span) SetOperationName(operationName string) opentracing.Span {
	dupe := s.clone()
	dupe.operationName = operationName
	return dupe
}

// Adds a tag to the span.
//
// If there is a pre-existing tag set for `key`, it is overwritten.
//
// Tag values can be numeric types, strings, or bools. The behavior of
// other tag value types is undefined at the OpenTracing level. If a
// tracing system does not know how to handle a particular value type, it
// may ignore the tag, but shall not panic.
func (s *Span) SetTag(key string, value interface{}) opentracing.Span {
	s.Lock()
	defer s.Unlock()

	if s.tags == nil {
{'fraction_non_alphanumeric': 0.11747740819073255, 'fraction_numerical': 0.0007690828686791001, 'mean_word_length': 3.263934426229508, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5850742', 'n_tokens_mistral': 1788, 'n_tokens_neox': 1720, 'n_words': 579}