traefik/vendor/github.com/ExpediaDotCom/haystack-client-go/span.go
2019-05-09 00:14:04 +02:00

164 lines
4.5 KiB
Go

/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"encoding/json"
"time"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/log"
)
/*_Span implements opentracing.Span*/
type _Span struct {
tracer *Tracer
context *SpanContext
operationName string
// startTime is the timestamp indicating when the span began, with microseconds precision.
startTime time.Time
// duration returns duration of the span with microseconds precision.
duration time.Duration
tags []opentracing.Tag
logs []opentracing.LogRecord
}
// SetOperationName sets or changes the operation name.
func (span *_Span) SetOperationName(operationName string) opentracing.Span {
span.operationName = operationName
return span
}
// SetTag implements SetTag() of opentracing.Span
func (span *_Span) SetTag(key string, value interface{}) opentracing.Span {
span.tags = append(span.tags,
opentracing.Tag{
Key: key,
Value: value,
})
return span
}
// LogFields implements opentracing.Span API
func (span *_Span) LogFields(fields ...log.Field) {
log := opentracing.LogRecord{
Fields: fields,
Timestamp: time.Now(),
}
span.logs = append(span.logs, log)
}
// LogKV implements opentracing.Span API
func (span *_Span) LogKV(alternatingKeyValues ...interface{}) {
fields, err := log.InterleavedKVToFields(alternatingKeyValues...)
if err != nil {
span.LogFields(log.Error(err), log.String("function", "LogKV"))
return
}
span.LogFields(fields...)
}
// LogEvent implements opentracing.Span API
func (span *_Span) LogEvent(event string) {
span.Log(opentracing.LogData{Event: event})
}
// LogEventWithPayload implements opentracing.Span API
func (span *_Span) LogEventWithPayload(event string, payload interface{}) {
span.Log(opentracing.LogData{Event: event, Payload: payload})
}
// Log implements opentracing.Span API
func (span *_Span) Log(ld opentracing.LogData) {
span.logs = append(span.logs, ld.ToLogRecord())
}
// SetBaggageItem implements SetBaggageItem() of opentracing.SpanContext
func (span *_Span) SetBaggageItem(key, value string) opentracing.Span {
span.context = span.context.WithBaggageItem(key, value)
span.LogFields(log.String("event", "baggage"), log.String("payload", key), log.String("payload", value))
return span
}
// BaggageItem implements BaggageItem() of opentracing.SpanContext
func (span *_Span) BaggageItem(key string) string {
return span.context.Baggage[key]
}
// Finish implements opentracing.Span API
func (span *_Span) Finish() {
span.FinishWithOptions(opentracing.FinishOptions{})
}
// FinishWithOptions implements opentracing.Span API
func (span *_Span) FinishWithOptions(options opentracing.FinishOptions) {
if options.FinishTime.IsZero() {
options.FinishTime = span.tracer.timeNow()
}
span.duration = options.FinishTime.Sub(span.startTime)
if options.LogRecords != nil {
span.logs = append(span.logs, options.LogRecords...)
}
for _, ld := range options.BulkLogData {
span.logs = append(span.logs, ld.ToLogRecord())
}
span.tracer.DispatchSpan(span)
}
// Context implements opentracing.Span API
func (span *_Span) Context() opentracing.SpanContext {
return span.context
}
/*Tracer returns the tracer*/
func (span *_Span) Tracer() opentracing.Tracer {
return span.tracer
}
/*OperationName allows retrieving current operation name*/
func (span *_Span) OperationName() string {
return span.operationName
}
/*ServiceName returns the name of the service*/
func (span *_Span) ServiceName() string {
return span.tracer.serviceName
}
func (span *_Span) String() string {
data, err := json.Marshal(map[string]interface{}{
"traceId": span.context.TraceID,
"spanId": span.context.SpanID,
"parentSpanId": span.context.ParentID,
"operationName": span.OperationName(),
"serviceName": span.ServiceName(),
"tags": span.Tags(),
"logs": span.logs,
})
if err != nil {
panic(err)
}
return string(data)
}
func (span *_Span) Tags() []opentracing.Tag {
return span.tags
}