jaeger

package module
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2016 License: MIT Imports: 23 Imported by: 0

README

GoDoc Build Status Coverage Status OpenTracing Compatible

Jaeger Bindings for Go OpenTracing API

This is a client side library that implements an OpenTracing Tracer, with Zipkin-compatible data model.

Initialization

import (
    "github.com/opentracing/opentracing-go"
    "github.com/uber/jaeger-client-go/config"
)

type AppConfig struct {
    ...
    Tracing config.Configuration
    ...
}

func main() {
    cfg := loadAppConfig() // e.g. from a yaml file

    tracer, closer, err := cfg.Tracing.New("your-service-name", nil)
    // check err
    defer closer.Close()

    opentracing.InitGlobalTracer(tracer)
    ...
}
Metrics & Monitoring

The tracer emits a number of different metrics, defined in metrics.go. The monitoring backend is expected to support tag-based metric names, e.g. instead of statsd-style string names like counters.my-service.jaeger.spans.started.sampled, the metrics are defined by a short name and a collection of key/value tags, for example: name:traces, state:started, sampled:true.

The monitoring backend is represented by the StatsReporter interface. An implementation of that interface should be passed to the New method during tracer initialization:

    stats := // create StatsReporter implementation
    tracer := config.Tracing.New("your-service-name", stats)

By default, a no-op NullStatsReporter is used.

Logging

The tracer can be configured with an optional logger, which will be used to log communication errors, or log spans if a logging reporter option is specified in the configuration. The logging API is abstracted by the Logger interface. A logger instance implementing this interface can be set on the Config object before calling the New method.

Instrumentation for Tracing

Since this tracer is fully compliant with OpenTracing API 1.0, all code instrumentation should only use the API itself, as described in the [opentracing-go] (https://github.com/opentracing/opentracing-go) documentation.

Features

Reporters

A "reporter" is a component receives the finished spans and reports them to somewhere. Under normal circumstances, the Tracer should use the default RemoteReporter, which sends the spans out of process via configurable "transport". For testing purposes, one can use an InMemoryReporter that accumulates spans in a buffer and allows to retrieve them for later verification. Also available are NullReporter, a no-op reporter that does nothing, a LoggingReporter which logs all finished spans using their String() method, and a CompositeReporter that can be used to combine more than one reporter into one, e.g. to attach a logging reporter to the main remote reporter.

Span Reporting Transports

The remote reporter uses "transports" to actually send the spans out of process. Currently two supported transports are Thrift over UDP and Thrift over TChannel. More transports will be added in the future.

The only data format currently used is Zipkin Thrift 1.x span format, which allows easy integration of the tracer with Zipkin backend.

Sampling

The tracer does not record all spans, but only those that have the sampling bit set in the flags. When a new trace is started and a new unique ID is generated, a sampling decision is made whether this trace should be sampled. The sampling decision is propagated to all downstream calls via the flags field of the trace context. The following samplers are available:

  1. RemotelyControlledSampler uses one of the other simpler samplers and periodically updates it by polling an external server. This allows dynamic control of the sampling strategies.
  2. ConstSampler always makes the same sampling decision for all trace IDs. it can be configured to either sample all traces, or to sample none.
  3. ProbabilisticSampler uses a fixed sampling rate as a probability for a given trace to be sampled. The actual decision is made by comparing the trace ID with a random number multiplied by the sampling rate.
  4. RateLimitingSampler can be used to allow only a certain fixed number of traces to be sampled per second.
Baggage Injection

The OpenTracing spec allows for baggage, which are key value pairs that are added to the span context and propagated throughout the trace. An external process can inject baggage by setting the special HTTP Header jaeger-baggage on a request

curl -H "jaeger-baggage: key1=value1, key2=value2" http://myhost.com

Baggage can also be programatically set inside your service by doing the following

span.SetBaggageItem("key", "value")
Debug Traces (Forced Sampling)
Programmatically

The OpenTracing API defines a sampling.priority standard tag that can be used to affect the sampling of a span and its children:

import (
    "github.com/opentracing/opentracing-go"
    "github.com/opentracing/opentracing-go/ext"
)
       
span := opentracing.SpanFromContext(ctx)
ext.SamplingPriority.Set(span, 1)    
Via HTTP Headers

Jaeger Tracer also understands a special HTTP Header jaeger-debug-id, which can be set in the incoming request, e.g.

curl -H "jaeger-debug-id: some-correlation-id" http://myhost.com

When Jaeger sees this header in the request that otherwise has no tracing context, it ensures that the new trace started for this request will be sampled in the "debug" mode (meaning it should survive all downsampling that might happen in the collection pipeline), and the root span will have a tag as if this statement was executed:

span.SetTag("jaeger-debug-id", "some-correlation-id")

This allows using Jaeger UI to find the trace by this tag.

License

The MIT License.

Documentation

Overview

Package jaeger implements an OpenTracing (http://opentracing.io) Tracer. It is currently using Zipkin-compatible data model and can be directly itegrated with Zipkin backend (http://zipkin.io).

For integration instructions please refer to the README:

https://github.com/uber/jaeger-client-go/blob/master/README.md

Index

Constants

View Source
const (
	// JaegerClientVersion is the version of the client library reported as Span tag.
	JaegerClientVersion = "Go-1.6"

	// JaegerClientVersionTagKey is the name of the tag used to report client version.
	JaegerClientVersionTagKey = "jaeger.version"

	// JaegerDebugHeader is the name of HTTP header or a TextMap carrier key which,
	// if found in the carrier, forces the trace to be sampled as "debug" trace.
	// The value of the header is recorded as the tag on the root span, so that the
	// trace can be found in the UI using this value as a correlation ID.
	JaegerDebugHeader = "jaeger-debug-id"

	// JaegerBaggageHeader is the name of the HTTP header that is used to submit baggage.
	// It differs from TraceBaggageHeaderPrefix in that it can be used only in cases where
	// a root span does not exist.
	JaegerBaggageHeader = "jaeger-baggage"

	// TracerHostnameTagKey used to report host name of the process.
	TracerHostnameTagKey = "jaeger.hostname"

	// SamplerTypeTagKey reports which sampler was used on the root span.
	SamplerTypeTagKey = "sampler.type"

	// SamplerParamTagKey reports the parameter of the sampler, like sampling probability.
	SamplerParamTagKey = "sampler.param"

	// TracerStateHeaderName is the http header name used to propagate tracing context.
	// This must be in lower-case to avoid mismatches when decoding incoming headers.
	TracerStateHeaderName = "uber-trace-id"

	// TraceBaggageHeaderPrefix is the prefix for http headers used to propagate baggage.
	// This must be in lower-case to avoid mismatches when decoding incoming headers.
	TraceBaggageHeaderPrefix = "uberctx-"

	// SamplerTypeConst is the type of sampler that always makes the same decision.
	SamplerTypeConst = "const"

	// SamplerTypeRemote is the type of sampler that polls Jaeger agent for sampling strategy.
	SamplerTypeRemote = "remote"

	// SamplerTypeProbabilistic is the type of sampler that samples traces
	// with a certain fixed probability.
	SamplerTypeProbabilistic = "probabilistic"

	// SamplerTypeRateLimiting is the type of sampler that samples
	// only up to a fixed number of traces per second.
	SamplerTypeRateLimiting = "ratelimiting"
)
View Source
const SpanContextFormat formatKey = iota

SpanContextFormat is a constant used as OpenTracing Format. Requires *SpanContext as carrier. This format is intended for interop with TChannel or other Zipkin-like tracers.

View Source
const ZipkinSpanFormat = "zipkin-span-format"

ZipkinSpanFormat is an OpenTracing carrier format constant

Variables

View Source
var NullLogger = &nullLogger{}

NullLogger is implementation of the Logger interface that delegates to default `log` package

View Source
var StdLogger = &stdLogger{}

StdLogger is implementation of the Logger interface that delegates to default `log` package

View Source
var TracerOptions tracerOptions

TracerOptions is a factory for all available TracerOption's

Functions

func NewTracer

func NewTracer(
	serviceName string,
	sampler Sampler,
	reporter Reporter,
	options ...TracerOption,
) (opentracing.Tracer, io.Closer)

NewTracer creates Tracer implementation that reports tracing to Jaeger. The returned io.Closer can be used in shutdown hooks to ensure that the internal queue of the Reporter is drained and all buffered spans are submitted to collectors.

Types

type ConstSampler

type ConstSampler struct {
	Decision bool
	// contains filtered or unexported fields
}

ConstSampler is a sampler that always makes the same decision.

func (*ConstSampler) Close

func (s *ConstSampler) Close()

Close implements Close() of Sampler.

func (*ConstSampler) Equal

func (s *ConstSampler) Equal(other Sampler) bool

Equal implements Equal() of Sampler.

func (*ConstSampler) IsSampled

func (s *ConstSampler) IsSampled(id uint64) bool

IsSampled implements IsSampled() of Sampler.

type ExtractableZipkinSpan

type ExtractableZipkinSpan interface {
	TraceID() uint64
	SpanID() uint64
	ParentID() uint64
	Flags() byte
}

ExtractableZipkinSpan is a type of Carrier used for integration with Zipkin-aware RPC frameworks (like TChannel). It does not support baggage, only trace IDs.

type Extractor

type Extractor interface {
	// Extract decodes a SpanContext instance from the given `carrier`,
	// or (nil, opentracing.ErrSpanContextNotFound) if no context could
	// be found in the `carrier`.
	Extract(carrier interface{}) (SpanContext, error)
}

Extractor is responsible for extracting SpanContext instances from a format-specific "carrier" object. Typically the extraction will take place on the server side of an RPC boundary, but message queues and other IPC mechanisms are also reasonable places to use an Extractor.

type InMemoryReporter

type InMemoryReporter struct {
	// contains filtered or unexported fields
}

InMemoryReporter is used for testing, and simply collects spans in memory.

func NewInMemoryReporter

func NewInMemoryReporter() *InMemoryReporter

NewInMemoryReporter creates a reporter that stores spans in memory. NOTE: the Tracer should be created with options.PoolSpans = false.

func (*InMemoryReporter) Close

func (r *InMemoryReporter) Close()

Close implements Close() method of Reporter by doing nothing.

func (*InMemoryReporter) GetSpans

func (r *InMemoryReporter) GetSpans() []opentracing.Span

GetSpans returns accumulated spans as a copy of the buffer.

func (*InMemoryReporter) Report

func (r *InMemoryReporter) Report(span *span)

Report implements Report() method of Reporter by storing the span in the buffer.

func (*InMemoryReporter) Reset

func (r *InMemoryReporter) Reset()

Reset clears all accumulated spans.

func (*InMemoryReporter) SpansSubmitted

func (r *InMemoryReporter) SpansSubmitted() int

SpansSubmitted returns the number of spans accumulated in the buffer.

type InMemoryStatsCollector

type InMemoryStatsCollector struct {
	sync.Mutex
	// contains filtered or unexported fields
}

InMemoryStatsCollector collects all stats in-memory and provides access to them via snapshots. Currently only the counters are implemented.

This is only meant for testing, not optimized for production use.

func NewInMemoryStatsCollector

func NewInMemoryStatsCollector() *InMemoryStatsCollector

NewInMemoryStatsCollector creates new in-memory stats reporter (aggregator)

func (*InMemoryStatsCollector) Clear added in v1.6.0

func (r *InMemoryStatsCollector) Clear()

Clear discards accumulated stats

func (*InMemoryStatsCollector) GetCounterValue added in v1.6.0

func (r *InMemoryStatsCollector) GetCounterValue(name string, tags ...string) int64

GetCounterValue retrieves the value of a counter with the given name and tags. Tags are read from an even number of key-values strings treates as alternating key, value pairs.

func (*InMemoryStatsCollector) GetCounterValues

func (r *InMemoryStatsCollector) GetCounterValues() map[string]int64

GetCounterValues returns a snapshot of currently accumulated counter values. The keys in the map are in the form "name|tag1=value1|...|tagN=valueN", where tag names are sorted alphabetically.

func (*InMemoryStatsCollector) IncCounter

func (r *InMemoryStatsCollector) IncCounter(name string, tags map[string]string, value int64)

IncCounter implements IncCounter of StatsReporter

func (*InMemoryStatsCollector) RecordTimer

func (r *InMemoryStatsCollector) RecordTimer(name string, tags map[string]string, d time.Duration)

RecordTimer is a no-op implementation of RecordTimer of StatsReporter

func (*InMemoryStatsCollector) UpdateGauge

func (r *InMemoryStatsCollector) UpdateGauge(name string, tags map[string]string, value int64)

UpdateGauge is a no-op implementation of UpdateGauge of StatsReporter

type InjectableZipkinSpan

type InjectableZipkinSpan interface {
	SetTraceID(traceID uint64)
	SetSpanID(spanID uint64)
	SetParentID(parentID uint64)
	SetFlags(flags byte)
}

InjectableZipkinSpan is a type of Carrier used for integration with Zipkin-aware RPC frameworks (like TChannel). It does not support baggage, only trace IDs.

type Injector

type Injector interface {
	// Inject takes `SpanContext` and injects it into `carrier`. The actual type
	// of `carrier` depends on the `format` passed to `Tracer.Inject()`.
	//
	// Implementations may return opentracing.ErrInvalidCarrier or any other
	// implementation-specific error if injection fails.
	Inject(ctx SpanContext, carrier interface{}) error
}

Injector is responsible for injecting SpanContext instances in a manner suitable for propagation via a format-specific "carrier" object. Typically the injection will take place across an RPC boundary, but message queues and other IPC mechanisms are also reasonable places to use an Injector.

type Logger

type Logger interface {
	// Error logs a message at error priority
	Error(msg string)

	// Infof logs a message at info priority
	Infof(msg string, args ...interface{})
}

Logger provides an abstract interface for logging from Reporters. Applications can provide their own implementation of this interface to adapt reporters logging to whatever logging library they prefer (stdlib log, logrus, go-logging, etc).

type MetricDescr added in v1.6.0

type MetricDescr struct {
	Name string
	Tags map[string]string
}

MetricDescr describes a metric with tags

func NewMetricDescr added in v1.6.0

func NewMetricDescr(name string, keyValues ...string) MetricDescr

NewMetricDescr creates a new metric descriptor from the name and an even number of keyValues strings treates as alternating key, value pairs.

func (MetricDescr) Key added in v1.6.0

func (m MetricDescr) Key() string

Key converts name+tags into a single string of the form "name|tag1=value1|...|tagN=valueN", where tag names are sorted alphabetically.

func (MetricDescr) WithTag added in v1.6.0

func (m MetricDescr) WithTag(key, value string) MetricDescr

WithTag returns a new metric descriptor with additional tag

type Metrics

type Metrics struct {
	// Number of traces started by this tracer as sampled
	TracesStartedSampled *counter `metric:"traces" tags:"state=started,sampled=y"`

	// Number of traces started by this tracer as not sampled
	TracesStartedNotSampled *counter `metric:"traces" tags:"state=started,sampled=n"`

	// Number of externally started sampled traces this tracer joined
	TracesJoinedSampled *counter `metric:"traces" tags:"state=joined,sampled=y"`

	// Number of externally started not-sampled traces this tracer joined
	TracesJoinedNotSampled *counter `metric:"traces" tags:"state=joined,sampled=n"`

	// Number of sampled spans started by this tracer
	SpansStarted *counter `metric:"spans" tags:"group=lifecycle,state=started"`

	// Number of sampled spans finished by this tracer
	SpansFinished *counter `metric:"spans" tags:"group=lifecycle,state=finished"`

	// Number of sampled spans started by this tracer
	SpansSampled *counter `metric:"spans" tags:"group=sampling,sampled=y"`

	// Number of not-sampled spans started by this tracer
	SpansNotSampled *counter `metric:"spans" tags:"group=sampling,sampled=n"`

	// Number of errors decoding tracing context
	DecodingErrors *counter `metric:"decoding-errors"`

	// Number of spans successfully reported
	ReporterSuccess *counter `metric:"reporter-spans" tags:"state=success"`

	// Number of spans in failed attempts to report
	ReporterFailure *counter `metric:"reporter-spans" tags:"state=failure"`

	// Number of spans dropped due to internal queue overflow
	ReporterDropped *counter `metric:"reporter-spans" tags:"state=dropped"`

	// Current number of spans in the reporter queue
	ReporterQueueLength *gauge `metric:"reporter-queue"`

	// Number of times the Sampler succeeded to retrieve sampling strategy
	SamplerRetrieved *counter `metric:"sampler" tags:"state=retrieved"`

	// Number of times the Sampler succeeded to retrieve and update sampling strategy
	SamplerUpdated *counter `metric:"sampler" tags:"state=updated"`

	// Number of times the Sampler failed to retrieve sampling strategy
	SamplerQueryFailure *counter `metric:"sampler" tags:"state=failure,phase=query"`

	// Number of times the Sampler failed to parse retrieved sampling strategy
	SamplerParsingFailure *counter `metric:"sampler" tags:"state=failure,phase=parsing"`
}

Metrics is a container of all stats emitted by Jaeger tracer.

func NewMetrics

func NewMetrics(reporter StatsReporter, globalTags map[string]string) *Metrics

NewMetrics creates a new Metrics struct and initializes its fields using reflection.

type ProbabilisticSampler

type ProbabilisticSampler struct {
	SamplingBoundary uint64
	// contains filtered or unexported fields
}

ProbabilisticSampler is a sampler that randomly samples a certain percentage of traces.

func (*ProbabilisticSampler) Close

func (s *ProbabilisticSampler) Close()

Close implements Close() of Sampler.

func (*ProbabilisticSampler) Equal

func (s *ProbabilisticSampler) Equal(other Sampler) bool

Equal implements Equal() of Sampler.

func (*ProbabilisticSampler) IsSampled

func (s *ProbabilisticSampler) IsSampled(id uint64) bool

IsSampled implements IsSampled() of Sampler.

type RemotelyControlledSampler

type RemotelyControlledSampler struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

RemotelyControlledSampler is a delegating sampler that polls a remote server for the appropriate sampling strategy, constructs a corresponding sampler and delegates to it for sampling decisions.

func NewRemotelyControlledSampler

func NewRemotelyControlledSampler(
	serviceName string,
	initial Sampler,
	hostPort string,
	metrics *Metrics,
	logger Logger,
) *RemotelyControlledSampler

NewRemotelyControlledSampler creates a sampler that periodically pulls the sampling strategy from an HTTP sampling server (e.g. jaeger-agent).

func (*RemotelyControlledSampler) Close

func (s *RemotelyControlledSampler) Close()

Close implements Close() of Sampler.

func (*RemotelyControlledSampler) Equal

func (s *RemotelyControlledSampler) Equal(other Sampler) bool

Equal implements Equal() of Sampler.

func (*RemotelyControlledSampler) IsSampled

func (s *RemotelyControlledSampler) IsSampled(id uint64) bool

IsSampled implements IsSampled() of Sampler.

type Reporter

type Reporter interface {
	// Report submits a new span to collectors, possibly asynchronously and/or with buffering.
	Report(span *span)

	// Close does a clean shutdown of the reporter, flushing any traces that may be buffered in memory.
	Close()
}

Reporter is called by the tracer when a span is completed to report the span to the tracing collector.

func NewCompositeReporter

func NewCompositeReporter(reporters ...Reporter) Reporter

NewCompositeReporter creates a reporter that ignores all reported spans.

func NewLoggingReporter

func NewLoggingReporter(logger Logger) Reporter

NewLoggingReporter creates a reporter that logs all reported spans to provided logger.

func NewNullReporter

func NewNullReporter() Reporter

NewNullReporter creates a no-op reporter that ignores all reported spans.

func NewRemoteReporter

func NewRemoteReporter(sender transport.Transport, options *ReporterOptions) Reporter

NewRemoteReporter creates a new reporter that sends spans out of process by means of Sender

type ReporterOptions

type ReporterOptions struct {
	// QueueSize is the size of internal queue where reported spans are stored before they are processed in the background
	QueueSize int
	// BufferFlushInterval is how often the buffer is force-flushed, even if it's not full
	BufferFlushInterval time.Duration
	// Logger is used to log errors of span submissions
	Logger Logger
	// Metrics is used to record runtime stats
	Metrics *Metrics
}

ReporterOptions control behavior of the reporter

type Sampler

type Sampler interface {
	// IsSampled decides whether a trace with given `id` should be sampled.
	IsSampled(id uint64) bool

	// Close does a clean shutdown of the sampler, stopping any background
	// go-routines it may have started.
	Close()

	// Equal checks if the `other` sampler is functionally equivalent
	// to this sampler.
	Equal(other Sampler) bool
	// contains filtered or unexported methods
}

Sampler decides whether a new trace should be sampled or not.

func NewConstSampler

func NewConstSampler(sample bool) Sampler

NewConstSampler creates a ConstSampler.

func NewProbabilisticSampler

func NewProbabilisticSampler(samplingRate float64) (Sampler, error)

NewProbabilisticSampler creates a sampler that randomly samples a certain percentage of traces specified by the samplingRate, in the range between 0.0 and 1.0.

It relies on the fact that new trace IDs are 63bit random numbers themselves, thus making the sampling decision without generating a new random number, but simply calculating if traceID < (samplingRate * 2^63).

func NewRateLimitingSampler

func NewRateLimitingSampler(maxTracesPerSecond float64) (Sampler, error)

NewRateLimitingSampler creates a sampler that samples at most maxTracesPerSecond. The distribution of sampled traces follows burstiness of the service, i.e. a service with uniformly distributed requests will have those requests sampled uniformly as well, but if requests are bursty, especially sub-second, then a number of sequential requests can be sampled each second.

type SpanContext

type SpanContext struct {
	// contains filtered or unexported fields
}

SpanContext represents propagated span identity and state

func ContextFromString

func ContextFromString(value string) (SpanContext, error)

ContextFromString reconstructs the Context encoded in a string

func NewSpanContext

func NewSpanContext(traceID, spanID, parentID uint64, sampled bool, baggage map[string]string) SpanContext

NewSpanContext creates a new instance of SpanContext

func (*SpanContext) CopyFrom

func (c *SpanContext) CopyFrom(ctx *SpanContext)

CopyFrom copies data from ctx into this context, including span identity and baggage. TODO This is only used by interop.go. Remove once TChannel Go supports OpenTracing.

func (SpanContext) ForeachBaggageItem

func (c SpanContext) ForeachBaggageItem(handler func(k, v string) bool)

ForeachBaggageItem implements ForeachBaggageItem() of opentracing.SpanContext

func (SpanContext) IsDebug

func (c SpanContext) IsDebug() bool

IsDebug indicates whether sampling was explicitly requested by the service.

func (SpanContext) IsSampled

func (c SpanContext) IsSampled() bool

IsSampled returns whether this trace was chosen for permanent storage by the sampling mechanism of the tracer.

func (SpanContext) IsValid added in v1.4.1

func (c SpanContext) IsValid() bool

IsValid indicates whether this context actually represents a valid trace.

func (SpanContext) ParentID

func (c SpanContext) ParentID() uint64

ParentID implements ParentID() of SpanID

func (SpanContext) SpanID

func (c SpanContext) SpanID() uint64

SpanID implements SpanID() of SpanID

func (SpanContext) String

func (c SpanContext) String() string

func (SpanContext) TraceID

func (c SpanContext) TraceID() uint64

TraceID implements TraceID() of SpanID

func (SpanContext) WithBaggageItem

func (c SpanContext) WithBaggageItem(key, value string) SpanContext

WithBaggageItem creates a new context with an extra baggage item.

type StatsReporter

type StatsReporter interface {
	// Increment a statsd-like counter with optional tags
	IncCounter(name string, tags map[string]string, value int64)

	// Increment a statsd-like gauge ("set" of the value) with optional tags
	UpdateGauge(name string, tags map[string]string, value int64)

	// Record a statsd-like timer with optional tags
	RecordTimer(name string, tags map[string]string, d time.Duration)
}

StatsReporter is an interface for statsd-like stats reporters accepted by Uber's libraries. Its methods take optional tag dictionaries which may be ignored by concrete implementations.

var NullStatsReporter StatsReporter = nullStatsReporter{}

NullStatsReporter is a stats reporter that discards the statistics.

type TracerOption

type TracerOption func(tracer *tracer)

TracerOption is a function that sets some option on the tracer

Directories

Path Synopsis
log
thrift/tracetest
Package tracetest is generated code used to make or handle TChannel calls using Thrift.
Package tracetest is generated code used to make or handle TChannel calls using Thrift.
internal
thrift-gen
Package transport defines various transports that can be used with RemoteReporter to send spans out of process.
Package transport defines various transports that can be used with RemoteReporter to send spans out of process.
udp
zipkin
Package zipkin provides various Transports that can be used with RemoteReporter for submitting traces to Zipkin backend.
Package zipkin provides various Transports that can be used with RemoteReporter for submitting traces to Zipkin backend.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL