1
0
Fork 0

Update tracing dependencies

This commit is contained in:
Ludovic Fernandez 2019-04-05 11:58:06 +02:00 committed by Traefiker Bot
parent 4919b638f9
commit ed12366d52
98 changed files with 3371 additions and 2808 deletions

View file

@ -28,6 +28,7 @@ import (
throttler "github.com/uber/jaeger-client-go/internal/throttler/remote"
"github.com/uber/jaeger-client-go/rpcmetrics"
"github.com/uber/jaeger-client-go/transport"
"github.com/uber/jaeger-lib/metrics"
)
const defaultSamplingProbability = 0.001
@ -192,7 +193,7 @@ func (c Configuration) NewTracer(options ...Option) (opentracing.Tracer, io.Clos
if c.RPCMetrics {
Observer(
rpcmetrics.NewObserver(
opts.metrics.Namespace("jaeger-rpc", map[string]string{"component": "jaeger"}),
opts.metrics.Namespace(metrics.NSOptions{Name: "jaeger-rpc", Tags: map[string]string{"component": "jaeger"}}),
rpcmetrics.DefaultNameNormalizer,
),
)(&opts) // adds to c.observers
@ -230,6 +231,7 @@ func (c Configuration) NewTracer(options ...Option) (opentracing.Tracer, io.Clos
jaeger.TracerOptions.Logger(opts.logger),
jaeger.TracerOptions.CustomHeaderKeys(c.Headers),
jaeger.TracerOptions.Gen128Bit(opts.gen128Bit),
jaeger.TracerOptions.PoolSpans(opts.poolSpans),
jaeger.TracerOptions.ZipkinSharedRPCSpan(opts.zipkinSharedRPCSpan),
jaeger.TracerOptions.MaxTagValueLength(opts.maxTagValueLength),
}

View file

@ -22,7 +22,7 @@ import (
"strings"
"time"
opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/uber/jaeger-client-go"
@ -159,46 +159,35 @@ func reporterConfigFromEnv() (*ReporterConfig, error) {
}
}
host := jaeger.DefaultUDPSpanServerHost
ep := os.Getenv(envEndpoint)
if e := os.Getenv(envAgentHost); e != "" {
if ep != "" {
return nil, errors.Errorf("cannot set env vars %s and %s together", envAgentHost, envEndpoint)
}
host = e
}
port := jaeger.DefaultUDPSpanServerPort
if e := os.Getenv(envAgentPort); e != "" {
if ep != "" {
return nil, errors.Errorf("cannot set env vars %s and %s together", envAgentPort, envEndpoint)
}
if value, err := strconv.ParseInt(e, 10, 0); err == nil {
port = int(value)
} else {
return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envAgentPort, e)
}
}
// the side effect of this is that we are building the default value, even if none of the env vars
// were not explicitly passed
rc.LocalAgentHostPort = fmt.Sprintf("%s:%d", host, port)
if ep != "" {
u, err := url.ParseRequestURI(ep)
if e := os.Getenv(envEndpoint); e != "" {
u, err := url.ParseRequestURI(e)
if err != nil {
return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envEndpoint, ep)
return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envEndpoint, e)
}
rc.CollectorEndpoint = u.String()
user := os.Getenv(envUser)
pswd := os.Getenv(envPassword)
if user != "" && pswd == "" || user == "" && pswd != "" {
return nil, errors.Errorf("you must set %s and %s env vars together", envUser, envPassword)
}
rc.User = user
rc.Password = pswd
} else {
host := jaeger.DefaultUDPSpanServerHost
if e := os.Getenv(envAgentHost); e != "" {
host = e
}
rc.CollectorEndpoint = fmt.Sprintf("%s", u)
}
user := os.Getenv(envUser)
pswd := os.Getenv(envPassword)
if user != "" && pswd == "" || user == "" && pswd != "" {
return nil, errors.Errorf("you must set %s and %s env vars together", envUser, envPassword)
port := jaeger.DefaultUDPSpanServerPort
if e := os.Getenv(envAgentPort); e != "" {
if value, err := strconv.ParseInt(e, 10, 0); err == nil {
port = int(value)
} else {
return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envAgentPort, e)
}
}
rc.LocalAgentHostPort = fmt.Sprintf("%s:%d", host, port)
}
rc.User = user
rc.Password = pswd
return rc, nil
}

View file

@ -33,6 +33,7 @@ type Options struct {
contribObservers []jaeger.ContribObserver
observers []jaeger.Observer
gen128Bit bool
poolSpans bool
zipkinSharedRPCSpan bool
maxTagValueLength int
tags []opentracing.Tag
@ -78,7 +79,7 @@ func Observer(observer jaeger.Observer) Option {
}
}
// ContribObserver can be registered with the Tracer to recieve notifications
// ContribObserver can be registered with the Tracer to receive notifications
// about new spans.
func ContribObserver(observer jaeger.ContribObserver) Option {
return func(c *Options) {
@ -93,6 +94,13 @@ func Gen128Bit(gen128Bit bool) Option {
}
}
// PoolSpans specifies whether to pool spans
func PoolSpans(poolSpans bool) Option {
return func(c *Options) {
c.poolSpans = poolSpans
}
}
// ZipkinSharedRPCSpan creates an option that enables sharing span ID between client
// and server spans a la zipkin. If false, client and server spans will be assigned
// different IDs.

View file

@ -16,7 +16,7 @@ package jaeger
const (
// JaegerClientVersion is the version of the client library reported as Span tag.
JaegerClientVersion = "Go-2.15.0"
JaegerClientVersion = "Go-2.16.0"
// JaegerClientVersionTagKey is the name of the tag used to report client version.
JaegerClientVersionTagKey = "jaeger.version"

View file

@ -198,7 +198,7 @@ func (c SpanContext) WithBaggageItem(key, value string) SpanContext {
// extract method, but now it returns a dummy context with only debugID filled in.
//
// See JaegerDebugHeader in constants.go
// See textMapPropagator#Extract
// See TextMapPropagator#Extract
func (c *SpanContext) isDebugIDContainerOnly() bool {
return !c.traceID.IsValid() && c.debugID != ""
}

View file

@ -38,7 +38,8 @@ type HeadersConfig struct {
TraceBaggageHeaderPrefix string `yaml:"traceBaggageHeaderPrefix"`
}
func (c *HeadersConfig) applyDefaults() *HeadersConfig {
// ApplyDefaults sets missing configuration keys to default values
func (c *HeadersConfig) ApplyDefaults() *HeadersConfig {
if c.JaegerBaggageHeader == "" {
c.JaegerBaggageHeader = JaegerBaggageHeader
}

View file

@ -21,83 +21,83 @@ import (
// Metrics is a container of all stats emitted by Jaeger tracer.
type Metrics struct {
// Number of traces started by this tracer as sampled
TracesStartedSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=y"`
TracesStartedSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=y" help:"Number of traces started by this tracer as sampled"`
// Number of traces started by this tracer as not sampled
TracesStartedNotSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=n"`
TracesStartedNotSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=n" help:"Number of traces started by this tracer as not sampled"`
// Number of externally started sampled traces this tracer joined
TracesJoinedSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=y"`
TracesJoinedSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=y" help:"Number of externally started sampled traces this tracer joined"`
// Number of externally started not-sampled traces this tracer joined
TracesJoinedNotSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=n"`
TracesJoinedNotSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=n" help:"Number of externally started not-sampled traces this tracer joined"`
// Number of sampled spans started by this tracer
SpansStartedSampled metrics.Counter `metric:"started_spans" tags:"sampled=y"`
SpansStartedSampled metrics.Counter `metric:"started_spans" tags:"sampled=y" help:"Number of sampled spans started by this tracer"`
// Number of unsampled spans started by this tracer
SpansStartedNotSampled metrics.Counter `metric:"started_spans" tags:"sampled=n"`
SpansStartedNotSampled metrics.Counter `metric:"started_spans" tags:"sampled=n" help:"Number of unsampled spans started by this tracer"`
// Number of spans finished by this tracer
SpansFinished metrics.Counter `metric:"finished_spans"`
SpansFinished metrics.Counter `metric:"finished_spans" help:"Number of spans finished by this tracer"`
// Number of errors decoding tracing context
DecodingErrors metrics.Counter `metric:"span_context_decoding_errors"`
DecodingErrors metrics.Counter `metric:"span_context_decoding_errors" help:"Number of errors decoding tracing context"`
// Number of spans successfully reported
ReporterSuccess metrics.Counter `metric:"reporter_spans" tags:"result=ok"`
ReporterSuccess metrics.Counter `metric:"reporter_spans" tags:"result=ok" help:"Number of spans successfully reported"`
// Number of spans not reported due to a Sender failure
ReporterFailure metrics.Counter `metric:"reporter_spans" tags:"result=err"`
ReporterFailure metrics.Counter `metric:"reporter_spans" tags:"result=err" help:"Number of spans not reported due to a Sender failure"`
// Number of spans dropped due to internal queue overflow
ReporterDropped metrics.Counter `metric:"reporter_spans" tags:"result=dropped"`
ReporterDropped metrics.Counter `metric:"reporter_spans" tags:"result=dropped" help:"Number of spans dropped due to internal queue overflow"`
// Current number of spans in the reporter queue
ReporterQueueLength metrics.Gauge `metric:"reporter_queue_length"`
ReporterQueueLength metrics.Gauge `metric:"reporter_queue_length" help:"Current number of spans in the reporter queue"`
// Number of times the Sampler succeeded to retrieve sampling strategy
SamplerRetrieved metrics.Counter `metric:"sampler_queries" tags:"result=ok"`
SamplerRetrieved metrics.Counter `metric:"sampler_queries" tags:"result=ok" help:"Number of times the Sampler succeeded to retrieve sampling strategy"`
// Number of times the Sampler failed to retrieve sampling strategy
SamplerQueryFailure metrics.Counter `metric:"sampler_queries" tags:"result=err"`
SamplerQueryFailure metrics.Counter `metric:"sampler_queries" tags:"result=err" help:"Number of times the Sampler failed to retrieve sampling strategy"`
// Number of times the Sampler succeeded to retrieve and update sampling strategy
SamplerUpdated metrics.Counter `metric:"sampler_updates" tags:"result=ok"`
SamplerUpdated metrics.Counter `metric:"sampler_updates" tags:"result=ok" help:"Number of times the Sampler succeeded to retrieve and update sampling strategy"`
// Number of times the Sampler failed to update sampling strategy
SamplerUpdateFailure metrics.Counter `metric:"sampler_updates" tags:"result=err"`
SamplerUpdateFailure metrics.Counter `metric:"sampler_updates" tags:"result=err" help:"Number of times the Sampler failed to update sampling strategy"`
// Number of times baggage was successfully written or updated on spans.
BaggageUpdateSuccess metrics.Counter `metric:"baggage_updates" tags:"result=ok"`
BaggageUpdateSuccess metrics.Counter `metric:"baggage_updates" tags:"result=ok" help:"Number of times baggage was successfully written or updated on spans"`
// Number of times baggage failed to write or update on spans.
BaggageUpdateFailure metrics.Counter `metric:"baggage_updates" tags:"result=err"`
BaggageUpdateFailure metrics.Counter `metric:"baggage_updates" tags:"result=err" help:"Number of times baggage failed to write or update on spans"`
// Number of times baggage was truncated as per baggage restrictions.
BaggageTruncate metrics.Counter `metric:"baggage_truncations"`
BaggageTruncate metrics.Counter `metric:"baggage_truncations" help:"Number of times baggage was truncated as per baggage restrictions"`
// Number of times baggage restrictions were successfully updated.
BaggageRestrictionsUpdateSuccess metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=ok"`
BaggageRestrictionsUpdateSuccess metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=ok" help:"Number of times baggage restrictions were successfully updated"`
// Number of times baggage restrictions failed to update.
BaggageRestrictionsUpdateFailure metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=err"`
BaggageRestrictionsUpdateFailure metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=err" help:"Number of times baggage restrictions failed to update"`
// Number of times debug spans were throttled.
ThrottledDebugSpans metrics.Counter `metric:"throttled_debug_spans"`
ThrottledDebugSpans metrics.Counter `metric:"throttled_debug_spans" help:"Number of times debug spans were throttled"`
// Number of times throttler successfully updated.
ThrottlerUpdateSuccess metrics.Counter `metric:"throttler_updates" tags:"result=ok"`
ThrottlerUpdateSuccess metrics.Counter `metric:"throttler_updates" tags:"result=ok" help:"Number of times throttler successfully updated"`
// Number of times throttler failed to update.
ThrottlerUpdateFailure metrics.Counter `metric:"throttler_updates" tags:"result=err"`
ThrottlerUpdateFailure metrics.Counter `metric:"throttler_updates" tags:"result=err" help:"Number of times throttler failed to update"`
}
// NewMetrics creates a new Metrics struct and initializes it.
func NewMetrics(factory metrics.Factory, globalTags map[string]string) *Metrics {
m := &Metrics{}
// TODO the namespace "jaeger" should be configurable (e.g. in all-in-one "jaeger-client" would make more sense)
metrics.Init(m, factory.Namespace("jaeger", nil), globalTags)
// TODO the namespace "jaeger" should be configurable
metrics.MustInit(m, factory.Namespace(metrics.NSOptions{Name: "jaeger"}).Namespace(metrics.NSOptions{Name: "tracer"}), globalTags)
return m
}

View file

@ -51,15 +51,17 @@ type Extractor interface {
Extract(carrier interface{}) (SpanContext, error)
}
type textMapPropagator struct {
// TextMapPropagator is a combined Injector and Extractor for TextMap format
type TextMapPropagator struct {
headerKeys *HeadersConfig
metrics Metrics
encodeValue func(string) string
decodeValue func(string) string
}
func newTextMapPropagator(headerKeys *HeadersConfig, metrics Metrics) *textMapPropagator {
return &textMapPropagator{
// NewTextMapPropagator creates a combined Injector and Extractor for TextMap format
func NewTextMapPropagator(headerKeys *HeadersConfig, metrics Metrics) *TextMapPropagator {
return &TextMapPropagator{
headerKeys: headerKeys,
metrics: metrics,
encodeValue: func(val string) string {
@ -71,8 +73,9 @@ func newTextMapPropagator(headerKeys *HeadersConfig, metrics Metrics) *textMapPr
}
}
func newHTTPHeaderPropagator(headerKeys *HeadersConfig, metrics Metrics) *textMapPropagator {
return &textMapPropagator{
// NewHTTPHeaderPropagator creates a combined Injector and Extractor for HTTPHeaders format
func NewHTTPHeaderPropagator(headerKeys *HeadersConfig, metrics Metrics) *TextMapPropagator {
return &TextMapPropagator{
headerKeys: headerKeys,
metrics: metrics,
encodeValue: func(val string) string {
@ -88,19 +91,22 @@ func newHTTPHeaderPropagator(headerKeys *HeadersConfig, metrics Metrics) *textMa
}
}
type binaryPropagator struct {
// BinaryPropagator is a combined Injector and Extractor for Binary format
type BinaryPropagator struct {
tracer *Tracer
buffers sync.Pool
}
func newBinaryPropagator(tracer *Tracer) *binaryPropagator {
return &binaryPropagator{
// NewBinaryPropagator creates a combined Injector and Extractor for Binary format
func NewBinaryPropagator(tracer *Tracer) *BinaryPropagator {
return &BinaryPropagator{
tracer: tracer,
buffers: sync.Pool{New: func() interface{} { return &bytes.Buffer{} }},
}
}
func (p *textMapPropagator) Inject(
// Inject implements Injector of TextMapPropagator
func (p *TextMapPropagator) Inject(
sc SpanContext,
abstractCarrier interface{},
) error {
@ -121,7 +127,8 @@ func (p *textMapPropagator) Inject(
return nil
}
func (p *textMapPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) {
// Extract implements Extractor of TextMapPropagator
func (p *TextMapPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) {
textMapReader, ok := abstractCarrier.(opentracing.TextMapReader)
if !ok {
return emptyContext, opentracing.ErrInvalidCarrier
@ -166,7 +173,8 @@ func (p *textMapPropagator) Extract(abstractCarrier interface{}) (SpanContext, e
return ctx, nil
}
func (p *binaryPropagator) Inject(
// Inject implements Injector of BinaryPropagator
func (p *BinaryPropagator) Inject(
sc SpanContext,
abstractCarrier interface{},
) error {
@ -207,7 +215,8 @@ func (p *binaryPropagator) Inject(
return nil
}
func (p *binaryPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) {
// Extract implements Extractor of BinaryPropagator
func (p *BinaryPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) {
carrier, ok := abstractCarrier.(io.Reader)
if !ok {
return emptyContext, opentracing.ErrInvalidCarrier
@ -269,7 +278,7 @@ func (p *binaryPropagator) Extract(abstractCarrier interface{}) (SpanContext, er
// is converted to map[string]string { "key1" : "value1",
// "key2" : "value2",
// "key3" : "value3" }
func (p *textMapPropagator) parseCommaSeparatedMap(value string) map[string]string {
func (p *TextMapPropagator) parseCommaSeparatedMap(value string) map[string]string {
baggage := make(map[string]string)
value, err := url.QueryUnescape(value)
if err != nil {
@ -289,12 +298,12 @@ func (p *textMapPropagator) parseCommaSeparatedMap(value string) map[string]stri
// Converts a baggage item key into an http header format,
// by prepending TraceBaggageHeaderPrefix and encoding the key string
func (p *textMapPropagator) addBaggageKeyPrefix(key string) string {
func (p *TextMapPropagator) addBaggageKeyPrefix(key string) string {
// TODO encodeBaggageKeyAsHeader add caching and escaping
return fmt.Sprintf("%v%v", p.headerKeys.TraceBaggageHeaderPrefix, key)
}
func (p *textMapPropagator) removeBaggageKeyPrefix(key string) string {
func (p *TextMapPropagator) removeBaggageKeyPrefix(key string) string {
// TODO decodeBaggageHeaderKey add caching and escaping
return key[len(p.headerKeys.TraceBaggageHeaderPrefix):]
}

View file

@ -34,7 +34,7 @@ type Metrics struct {
// RequestCountFailures is a counter of the number of times any failure has been observed.
RequestCountFailures metrics.Counter `metric:"requests" tags:"error=true"`
// RequestLatencySuccess is a latency histogram of succesful requests.
// RequestLatencySuccess is a latency histogram of successful requests.
RequestLatencySuccess metrics.Timer `metric:"request_latency" tags:"error=false"`
// RequestLatencyFailures is a latency histogram of failed requests.

View file

@ -18,6 +18,8 @@ const CLIENT_SEND = "cs"
const CLIENT_RECV = "cr"
const SERVER_SEND = "ss"
const SERVER_RECV = "sr"
const MESSAGE_SEND = "ms"
const MESSAGE_RECV = "mr"
const WIRE_SEND = "ws"
const WIRE_RECV = "wr"
const CLIENT_SEND_FRAGMENT = "csf"
@ -27,6 +29,7 @@ const SERVER_RECV_FRAGMENT = "srf"
const LOCAL_COMPONENT = "lc"
const CLIENT_ADDR = "ca"
const SERVER_ADDR = "sa"
const MESSAGE_ADDR = "ma"
func init() {
}

View file

@ -103,10 +103,12 @@ func (p *AnnotationType) UnmarshalText(text []byte) error {
// - ServiceName: Service name in lowercase, such as "memcache" or "zipkin-web"
//
// Conventionally, when the service name isn't known, service_name = "unknown".
// - Ipv6: IPv6 host address packed into 16 bytes. Ex Inet6Address.getBytes()
type Endpoint struct {
Ipv4 int32 `thrift:"ipv4,1" json:"ipv4"`
Port int16 `thrift:"port,2" json:"port"`
ServiceName string `thrift:"service_name,3" json:"service_name"`
Ipv6 []byte `thrift:"ipv6,4" json:"ipv6,omitempty"`
}
func NewEndpoint() *Endpoint {
@ -124,6 +126,16 @@ func (p *Endpoint) GetPort() int16 {
func (p *Endpoint) GetServiceName() string {
return p.ServiceName
}
var Endpoint_Ipv6_DEFAULT []byte
func (p *Endpoint) GetIpv6() []byte {
return p.Ipv6
}
func (p *Endpoint) IsSetIpv6() bool {
return p.Ipv6 != nil
}
func (p *Endpoint) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
@ -150,6 +162,10 @@ func (p *Endpoint) Read(iprot thrift.TProtocol) error {
if err := p.readField3(iprot); err != nil {
return err
}
case 4:
if err := p.readField4(iprot); err != nil {
return err
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
@ -192,6 +208,15 @@ func (p *Endpoint) readField3(iprot thrift.TProtocol) error {
return nil
}
func (p *Endpoint) readField4(iprot thrift.TProtocol) error {
if v, err := iprot.ReadBinary(); err != nil {
return thrift.PrependError("error reading field 4: ", err)
} else {
p.Ipv6 = v
}
return nil
}
func (p *Endpoint) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("Endpoint"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
@ -205,6 +230,9 @@ func (p *Endpoint) Write(oprot thrift.TProtocol) error {
if err := p.writeField3(oprot); err != nil {
return err
}
if err := p.writeField4(oprot); err != nil {
return err
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err)
}
@ -253,6 +281,21 @@ func (p *Endpoint) writeField3(oprot thrift.TProtocol) (err error) {
return err
}
func (p *Endpoint) writeField4(oprot thrift.TProtocol) (err error) {
if p.IsSetIpv6() {
if err := oprot.WriteFieldBegin("ipv6", thrift.STRING, 4); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:ipv6: ", p), err)
}
if err := oprot.WriteBinary(p.Ipv6); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.ipv6 (4) field write error: ", p), err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 4:ipv6: ", p), err)
}
}
return err
}
func (p *Endpoint) String() string {
if p == nil {
return "<nil>"
@ -707,6 +750,8 @@ func (p *BinaryAnnotation) String() string {
// this field non-atomically is implementation-specific.
//
// This field is i64 vs i32 to support spans longer than 35 minutes.
// - TraceIDHigh: Optional unique 8-byte additional identifier for a trace. If non zero, this
// means the trace uses 128 bit traceIds instead of 64 bit.
type Span struct {
TraceID int64 `thrift:"trace_id,1" json:"trace_id"`
// unused field # 2
@ -719,6 +764,7 @@ type Span struct {
Debug bool `thrift:"debug,9" json:"debug,omitempty"`
Timestamp *int64 `thrift:"timestamp,10" json:"timestamp,omitempty"`
Duration *int64 `thrift:"duration,11" json:"duration,omitempty"`
TraceIDHigh *int64 `thrift:"trace_id_high,12" json:"trace_id_high,omitempty"`
}
func NewSpan() *Span {
@ -777,6 +823,15 @@ func (p *Span) GetDuration() int64 {
}
return *p.Duration
}
var Span_TraceIDHigh_DEFAULT int64
func (p *Span) GetTraceIDHigh() int64 {
if !p.IsSetTraceIDHigh() {
return Span_TraceIDHigh_DEFAULT
}
return *p.TraceIDHigh
}
func (p *Span) IsSetParentID() bool {
return p.ParentID != nil
}
@ -793,6 +848,10 @@ func (p *Span) IsSetDuration() bool {
return p.Duration != nil
}
func (p *Span) IsSetTraceIDHigh() bool {
return p.TraceIDHigh != nil
}
func (p *Span) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
@ -843,6 +902,10 @@ func (p *Span) Read(iprot thrift.TProtocol) error {
if err := p.readField11(iprot); err != nil {
return err
}
case 12:
if err := p.readField12(iprot); err != nil {
return err
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
@ -961,6 +1024,15 @@ func (p *Span) readField11(iprot thrift.TProtocol) error {
return nil
}
func (p *Span) readField12(iprot thrift.TProtocol) error {
if v, err := iprot.ReadI64(); err != nil {
return thrift.PrependError("error reading field 12: ", err)
} else {
p.TraceIDHigh = &v
}
return nil
}
func (p *Span) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("Span"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
@ -992,6 +1064,9 @@ func (p *Span) Write(oprot thrift.TProtocol) error {
if err := p.writeField11(oprot); err != nil {
return err
}
if err := p.writeField12(oprot); err != nil {
return err
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err)
}
@ -1142,6 +1217,21 @@ func (p *Span) writeField11(oprot thrift.TProtocol) (err error) {
return err
}
func (p *Span) writeField12(oprot thrift.TProtocol) (err error) {
if p.IsSetTraceIDHigh() {
if err := oprot.WriteFieldBegin("trace_id_high", thrift.I64, 12); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 12:trace_id_high: ", p), err)
}
if err := oprot.WriteI64(int64(*p.TraceIDHigh)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.trace_id_high (12) field write error: ", p), err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 12:trace_id_high: ", p), err)
}
}
return err
}
func (p *Span) String() string {
if p == nil {
return "<nil>"

View file

@ -17,6 +17,7 @@ package jaeger
import (
"fmt"
"io"
"math/rand"
"os"
"reflect"
"strconv"
@ -96,13 +97,13 @@ func NewTracer(
}
// register default injectors/extractors unless they are already provided via options
textPropagator := newTextMapPropagator(getDefaultHeadersConfig(), t.metrics)
textPropagator := NewTextMapPropagator(getDefaultHeadersConfig(), t.metrics)
t.addCodec(opentracing.TextMap, textPropagator, textPropagator)
httpHeaderPropagator := newHTTPHeaderPropagator(getDefaultHeadersConfig(), t.metrics)
httpHeaderPropagator := NewHTTPHeaderPropagator(getDefaultHeadersConfig(), t.metrics)
t.addCodec(opentracing.HTTPHeaders, httpHeaderPropagator, httpHeaderPropagator)
binaryPropagator := newBinaryPropagator(t)
binaryPropagator := NewBinaryPropagator(t)
t.addCodec(opentracing.Binary, binaryPropagator, binaryPropagator)
// TODO remove after TChannel supports OpenTracing
@ -122,9 +123,18 @@ func NewTracer(
}
if t.randomNumber == nil {
rng := utils.NewRand(time.Now().UnixNano())
seedGenerator := utils.NewRand(time.Now().UnixNano())
pool := sync.Pool{
New: func() interface{} {
return rand.NewSource(seedGenerator.Int63())
},
}
t.randomNumber = func() uint64 {
return uint64(rng.Int63())
generator := pool.Get().(rand.Source)
number := uint64(generator.Int63())
pool.Put(generator)
return number
}
}
if t.timeNow == nil {
@ -309,7 +319,11 @@ func (t *Tracer) Extract(
carrier interface{},
) (opentracing.SpanContext, error) {
if extractor, ok := t.extractors[format]; ok {
return extractor.Extract(carrier)
spanCtx, err := extractor.Extract(carrier)
if err != nil {
return nil, err // ensure returned spanCtx is nil
}
return spanCtx, nil
}
return nil, opentracing.ErrUnsupportedFormat
}

View file

@ -51,10 +51,10 @@ func (tracerOptions) CustomHeaderKeys(headerKeys *HeadersConfig) TracerOption {
if headerKeys == nil {
return
}
textPropagator := newTextMapPropagator(headerKeys.applyDefaults(), tracer.metrics)
textPropagator := NewTextMapPropagator(headerKeys.ApplyDefaults(), tracer.metrics)
tracer.addCodec(opentracing.TextMap, textPropagator, textPropagator)
httpHeaderPropagator := newHTTPHeaderPropagator(headerKeys.applyDefaults(), tracer.metrics)
httpHeaderPropagator := NewHTTPHeaderPropagator(headerKeys.ApplyDefaults(), tracer.metrics)
tracer.addCodec(opentracing.HTTPHeaders, httpHeaderPropagator, httpHeaderPropagator)
}
}

View file

@ -12,5 +12,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package zipkin comprises Zipkin functionality for Zipkin compatiblity.
// Package zipkin comprises Zipkin functionality for Zipkin compatibility.
package zipkin

View file

@ -23,13 +23,30 @@ import (
"github.com/uber/jaeger-client-go"
)
// Option is a function that sets an option on Propagator
type Option func(propagator *Propagator)
// BaggagePrefix is a function that sets baggage prefix on Propagator
func BaggagePrefix(prefix string) Option {
return func(propagator *Propagator) {
propagator.baggagePrefix = prefix
}
}
// Propagator is an Injector and Extractor
type Propagator struct{}
type Propagator struct {
baggagePrefix string
}
// NewZipkinB3HTTPHeaderPropagator creates a Propagator for extracting and injecting
// Zipkin HTTP B3 headers into SpanContexts.
func NewZipkinB3HTTPHeaderPropagator() Propagator {
return Propagator{}
// Zipkin HTTP B3 headers into SpanContexts. Baggage is by default enabled and uses prefix
// 'baggage-'.
func NewZipkinB3HTTPHeaderPropagator(opts ...Option) Propagator {
p := Propagator{baggagePrefix: "baggage-"}
for _, opt := range opts {
opt(&p)
}
return p
}
// Inject conforms to the Injector interface for decoding Zipkin HTTP B3 headers
@ -42,8 +59,7 @@ func (p Propagator) Inject(
return opentracing.ErrInvalidCarrier
}
// TODO this needs to change to support 128bit IDs
textMapWriter.Set("x-b3-traceid", strconv.FormatUint(sc.TraceID().Low, 16))
textMapWriter.Set("x-b3-traceid", sc.TraceID().String())
if sc.ParentID() != 0 {
textMapWriter.Set("x-b3-parentspanid", strconv.FormatUint(uint64(sc.ParentID()), 16))
}
@ -53,6 +69,10 @@ func (p Propagator) Inject(
} else {
textMapWriter.Set("x-b3-sampled", "0")
}
sc.ForeachBaggageItem(func(k, v string) bool {
textMapWriter.Set(p.baggagePrefix+k, v)
return true
})
return nil
}
@ -62,21 +82,27 @@ func (p Propagator) Extract(abstractCarrier interface{}) (jaeger.SpanContext, er
if !ok {
return jaeger.SpanContext{}, opentracing.ErrInvalidCarrier
}
var traceID uint64
var traceID jaeger.TraceID
var spanID uint64
var parentID uint64
sampled := false
var baggage map[string]string
err := textMapReader.ForeachKey(func(rawKey, value string) error {
key := strings.ToLower(rawKey) // TODO not necessary for plain TextMap
var err error
if key == "x-b3-traceid" {
traceID, err = strconv.ParseUint(value, 16, 64)
traceID, err = jaeger.TraceIDFromString(value)
} else if key == "x-b3-parentspanid" {
parentID, err = strconv.ParseUint(value, 16, 64)
} else if key == "x-b3-spanid" {
spanID, err = strconv.ParseUint(value, 16, 64)
} else if key == "x-b3-sampled" && value == "1" {
} else if key == "x-b3-sampled" && (value == "1" || value == "true") {
sampled = true
} else if strings.HasPrefix(key, p.baggagePrefix) {
if baggage == nil {
baggage = make(map[string]string)
}
baggage[key[len(p.baggagePrefix):]] = value
}
return err
})
@ -84,12 +110,12 @@ func (p Propagator) Extract(abstractCarrier interface{}) (jaeger.SpanContext, er
if err != nil {
return jaeger.SpanContext{}, err
}
if traceID == 0 {
if !traceID.IsValid() {
return jaeger.SpanContext{}, opentracing.ErrSpanContextNotFound
}
return jaeger.NewSpanContext(
jaeger.TraceID{Low: traceID},
traceID,
jaeger.SpanID(spanID),
jaeger.SpanID(parentID),
sampled, nil), nil
sampled, baggage), nil
}

View file

@ -48,13 +48,19 @@ func BuildZipkinThrift(s *Span) *z.Span {
if parentID != 0 {
ptrParentID = &parentID
}
traceIDHigh := int64(span.context.traceID.High)
var ptrTraceIDHigh *int64
if traceIDHigh != 0 {
ptrTraceIDHigh = &traceIDHigh
}
timestamp := utils.TimeToMicrosecondsSinceEpochInt64(span.startTime)
duration := span.duration.Nanoseconds() / int64(time.Microsecond)
endpoint := &z.Endpoint{
ServiceName: span.tracer.serviceName,
Ipv4: int32(span.tracer.hostIPv4)}
thriftSpan := &z.Span{
TraceID: int64(span.context.traceID.Low), // TODO upgrade zipkin thrift and use TraceIdHigh
TraceID: int64(span.context.traceID.Low),
TraceIDHigh: ptrTraceIDHigh,
ID: int64(span.context.spanID),
ParentID: ptrParentID,
Name: span.operationName,