zipkin-go: github.com/openzipkin/zipkin-go Index | Examples | Files | Directories

package zipkin

import "github.com/openzipkin/zipkin-go"

Package zipkin implements a native Zipkin instrumentation library for Go.

See https://zipkin.io for more information about Zipkin.

Code:

package main

import (
    "log"
    "net/http"
    "net/http/httptest"
    "os"
    "time"

    "github.com/gorilla/mux"

    zipkin "github.com/openzipkin/zipkin-go"
    zipkinhttp "github.com/openzipkin/zipkin-go/middleware/http"
    logreporter "github.com/openzipkin/zipkin-go/reporter/log"
)

func main() {
    // set up a span reporter
    reporter := logreporter.NewReporter(log.New(os.Stderr, "", log.LstdFlags))
    defer reporter.Close()

    // create our local service endpoint
    endpoint, err := zipkin.NewEndpoint("myService", "localhost:0")
    if err != nil {
        log.Fatalf("unable to create local endpoint: %+v\n", err)
    }

    // initialize our tracer
    tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
    if err != nil {
        log.Fatalf("unable to create tracer: %+v\n", err)
    }

    // create global zipkin http server middleware
    serverMiddleware := zipkinhttp.NewServerMiddleware(
        tracer, zipkinhttp.TagResponseSize(true),
    )

    // create global zipkin traced http client
    client, err := zipkinhttp.NewClient(tracer, zipkinhttp.ClientTrace(true))
    if err != nil {
        log.Fatalf("unable to create client: %+v\n", err)
    }

    // initialize router
    router := mux.NewRouter()

    // start web service with zipkin http server middleware
    ts := httptest.NewServer(serverMiddleware(router))
    defer ts.Close()

    // set-up handlers
    router.Methods("GET").Path("/some_function").HandlerFunc(someFunc(client, ts.URL))
    router.Methods("POST").Path("/other_function").HandlerFunc(otherFunc(client))

    // initiate a call to some_func
    req, err := http.NewRequest("GET", ts.URL+"/some_function", nil)
    if err != nil {
        log.Fatalf("unable to create http request: %+v\n", err)
    }

    res, err := client.DoWithAppSpan(req, "some_function")
    if err != nil {
        log.Fatalf("unable to do http request: %+v\n", err)
    }
    res.Body.Close()

}

func someFunc(client *zipkinhttp.Client, url string) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Printf("some_function called with method: %s\n", r.Method)

        // retrieve span from context (created by server middleware)
        span := zipkin.SpanFromContext(r.Context())
        span.Tag("custom_key", "some value")

        // doing some expensive calculations....
        time.Sleep(25 * time.Millisecond)
        span.Annotate(time.Now(), "expensive_calc_done")

        newRequest, err := http.NewRequest("POST", url+"/other_function", nil)
        if err != nil {
            log.Printf("unable to create client: %+v\n", err)
            http.Error(w, err.Error(), 500)
            return
        }

        ctx := zipkin.NewContext(newRequest.Context(), span)

        newRequest = newRequest.WithContext(ctx)

        res, err := client.DoWithAppSpan(newRequest, "other_function")
        if err != nil {
            log.Printf("call to other_function returned error: %+v\n", err)
            http.Error(w, err.Error(), 500)
            return
        }
        res.Body.Close()
    }
}

func otherFunc(client *zipkinhttp.Client) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Printf("other_function called with method: %s\n", r.Method)
        time.Sleep(50 * time.Millisecond)
    }
}

Index

Examples

Package Files

context.go doc.go endpoint.go noop.go sample.go span.go span_implementation.go span_options.go tags.go tracer.go tracer_options.go

Variables

var (
    ErrInvalidEndpoint             = errors.New("requires valid local endpoint")
    ErrInvalidExtractFailurePolicy = errors.New("invalid extract failure policy provided")
)

Tracer Option Errors

func AlwaysSample Uses

func AlwaysSample(_ uint64) bool

AlwaysSample will always return true. If used by a service it will always start traces if no upstream trace has been propagated. If an incoming upstream trace is not sampled the service will adhere to this and only propagate the context.

func NeverSample Uses

func NeverSample(_ uint64) bool

NeverSample will always return false. If used by a service it will not allow the service to start traces but will still allow the service to participate in traces started upstream.

func NewContext Uses

func NewContext(ctx context.Context, s Span) context.Context

NewContext stores a Zipkin Span into Go's context propagation mechanism.

Code:

var (
    tracer, _ = zipkin.NewTracer(reporter.NewNoopReporter())
    ctx       = context.Background()
)

// span for this function
span := tracer.StartSpan("ExampleNewContext")
defer span.Finish()

// add span to Context
ctx = zipkin.NewContext(ctx, span)

// pass along Context which holds the span to another function
doSomeWork(ctx)

func NewEndpoint Uses

func NewEndpoint(serviceName string, hostPort string) (*model.Endpoint, error)

NewEndpoint creates a new endpoint given the provided serviceName and hostPort.

type ExtractFailurePolicy Uses

type ExtractFailurePolicy int

ExtractFailurePolicy deals with Extraction errors

const (
    ExtractFailurePolicyRestart ExtractFailurePolicy = iota
    ExtractFailurePolicyError
    ExtractFailurePolicyTagAndRestart
)

ExtractFailurePolicyOptions

type Sampler Uses

type Sampler func(id uint64) bool

Sampler functions return if a Zipkin span should be sampled, based on its traceID.

func NewBoundarySampler Uses

func NewBoundarySampler(rate float64, salt int64) (Sampler, error)

NewBoundarySampler is appropriate for high-traffic instrumentation who provision random trace ids, and make the sampling decision only once. It defends against nodes in the cluster selecting exactly the same ids.

func NewCountingSampler Uses

func NewCountingSampler(rate float64) (Sampler, error)

NewCountingSampler is appropriate for low-traffic instrumentation or those who do not provision random trace ids. It is not appropriate for collectors as the sampling decision isn't idempotent (consistent based on trace id).

func NewModuloSampler Uses

func NewModuloSampler(mod uint64) Sampler

NewModuloSampler provides a generic type Sampler.

type Span Uses

type Span interface {
    // Context returns the Span's SpanContext.
    Context() model.SpanContext

    // SetName updates the Span's name.
    SetName(string)

    // SetRemoteEndpoint updates the Span's Remote Endpoint.
    SetRemoteEndpoint(*model.Endpoint)

    // Annotate adds a timed event to the Span.
    Annotate(time.Time, string)

    // Tag sets Tag with given key and value to the Span. If key already exists in
    // the Span the value will be overridden except for error tags where the first
    // value is persisted.
    Tag(string, string)

    // Finish the Span and send to Reporter. If DelaySend option was used at
    // Span creation time, Finish will not send the Span to the Reporter. It then
    // becomes the user's responsibility to get the Span reported (by using
    // span.Flush).
    Finish()

    // Finish the Span with duration and send to Reporter. If DelaySend option was used at
    // Span creation time, FinishedWithDuration will not send the Span to the Reporter. It then
    // becomes the user's responsibility to get the Span reported (by using
    // span.Flush).
    FinishedWithDuration(duration time.Duration)

    // Flush the Span to the Reporter (regardless of being finished or not).
    // This can be used if the DelaySend SpanOption was set or when dealing with
    // one-way RPC tracing where duration might not be measured.
    Flush()
}

Span interface as returned by Tracer.StartSpan()

func SpanFromContext Uses

func SpanFromContext(ctx context.Context) Span

SpanFromContext retrieves a Zipkin Span from Go's context propagation mechanism if found. If not found, returns nil.

func SpanOrNoopFromContext Uses

func SpanOrNoopFromContext(ctx context.Context) Span

SpanOrNoopFromContext retrieves a Zipkin Span from Go's context propagation mechanism if found. If not found, returns a noopSpan. This function typically is used for modules that want to provide existing Zipkin spans with additional data, but can't guarantee that spans are properly propagated. It is preferred to use SpanFromContext() and test for Nil instead of using this function.

type SpanOption Uses

type SpanOption func(t *Tracer, s *spanImpl)

SpanOption allows for functional options to adjust behavior and payload of the Span to be created with tracer.StartSpan().

Code:

tracer, _ := zipkin.NewTracer(reporter.NewNoopReporter())

// set-up the remote endpoint for the service we're about to call
endpoint, err := zipkin.NewEndpoint("otherService", "172.20.23.101:80")
if err != nil {
    log.Fatalf("unable to create remote endpoint: %+v\n", err)
}

// start a client side RPC span and use RemoteEndpoint SpanOption
span := tracer.StartSpan(
    "some-operation",
    zipkin.RemoteEndpoint(endpoint),
    zipkin.Kind(model.Client),
)
// ... call other service ...
span.Finish()

func FlushOnFinish Uses

func FlushOnFinish(b bool) SpanOption

FlushOnFinish when set to false will disable span.Finish() to send the Span to the Reporter automatically (which is the default behavior). If set to false, having the Span be reported becomes the responsibility of the user. This is available if late tag data is expected to be only available after the required finish time of the Span.

func Kind Uses

func Kind(kind model.Kind) SpanOption

Kind sets the kind of the span being created..

func Parent Uses

func Parent(sc model.SpanContext) SpanOption

Parent will use provided SpanContext as parent to the span being created.

func RemoteEndpoint Uses

func RemoteEndpoint(e *model.Endpoint) SpanOption

RemoteEndpoint sets the remote endpoint of the span being created.

func StartTime Uses

func StartTime(start time.Time) SpanOption

StartTime uses a given start time for the span being created.

func Tags Uses

func Tags(tags map[string]string) SpanOption

Tags sets initial tags for the span being created. If default tracer tags are present they will be overwritten on key collisions.

type Tag Uses

type Tag string

Tag holds available types

const (
    TagHTTPMethod       Tag = "http.method"
    TagHTTPPath         Tag = "http.path"
    TagHTTPUrl          Tag = "http.url"
    TagHTTPRoute        Tag = "http.route"
    TagHTTPStatusCode   Tag = "http.status_code"
    TagHTTPRequestSize  Tag = "http.request.size"
    TagHTTPResponseSize Tag = "http.response.size"
    TagGRPCStatusCode   Tag = "grpc.status_code"
    TagSQLQuery         Tag = "sql.query"
    TagError            Tag = "error"
)

Common Tag values

func (Tag) Set Uses

func (t Tag) Set(s Span, value string)

Set a standard Tag with a payload on provided Span.

type Tracer Uses

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

Tracer is our Zipkin tracer implementation. It should be initialized using the NewTracer method.

func NewTracer Uses

func NewTracer(rep reporter.Reporter, opts ...TracerOption) (*Tracer, error)

NewTracer returns a new Zipkin Tracer.

Code:

// create a reporter to be used by the tracer
reporter := httpreporter.NewReporter("http://localhost:9411/api/v2/spans")
defer reporter.Close()

// set-up the local endpoint for our service
endpoint, err := zipkin.NewEndpoint("demoService", "172.20.23.100:80")
if err != nil {
    log.Fatalf("unable to create local endpoint: %+v\n", err)
}

// set-up our sampling strategy
sampler, err := zipkin.NewBoundarySampler(0.01, time.Now().UnixNano())
if err != nil {
    log.Fatalf("unable to create sampler: %+v\n", err)
}

// initialize the tracer
tracer, err := zipkin.NewTracer(
    reporter,
    zipkin.WithLocalEndpoint(endpoint),
    zipkin.WithSampler(sampler),
)
if err != nil {
    log.Fatalf("unable to create tracer: %+v\n", err)
}

// tracer can now be used to create spans.
span := tracer.StartSpan("some_operation")
// ... do some work ...
span.Finish()

func (*Tracer) Extract Uses

func (t *Tracer) Extract(extractor propagation.Extractor) (sc model.SpanContext)

Extract extracts a SpanContext using the provided Extractor function.

func (*Tracer) LocalEndpoint Uses

func (t *Tracer) LocalEndpoint() *model.Endpoint

LocalEndpoint returns a copy of the currently set local endpoint of the tracer instance.

func (*Tracer) SetNoop Uses

func (t *Tracer) SetNoop(noop bool)

SetNoop allows for killswitch behavior. If set to true the tracer will return noopSpans and all data is dropped. This allows operators to stop tracing in risk scenarios. Set back to false to resume tracing.

func (*Tracer) StartSpan Uses

func (t *Tracer) StartSpan(name string, options ...SpanOption) Span

StartSpan creates and starts a span.

func (*Tracer) StartSpanFromContext Uses

func (t *Tracer) StartSpanFromContext(ctx context.Context, name string, options ...SpanOption) (Span, context.Context)

StartSpanFromContext creates and starts a span using the span found in context as parent. If no parent span is found a root span is created.

type TracerOption Uses

type TracerOption func(o *Tracer) error

TracerOption allows for functional options to adjust behavior of the Tracer to be created with NewTracer().

Code:

// initialize the tracer and use the WithNoopSpan TracerOption
tracer, _ := zipkin.NewTracer(
    reporter.NewNoopReporter(),
    zipkin.WithNoopSpan(true),
)

// tracer can now be used to create spans
span := tracer.StartSpan("some_operation")
// ... do some work ...
span.Finish()

func WithExtractFailurePolicy Uses

func WithExtractFailurePolicy(p ExtractFailurePolicy) TracerOption

WithExtractFailurePolicy allows one to set the ExtractFailurePolicy.

func WithIDGenerator Uses

func WithIDGenerator(generator idgenerator.IDGenerator) TracerOption

WithIDGenerator allows one to set a custom ID Generator

func WithLocalEndpoint Uses

func WithLocalEndpoint(e *model.Endpoint) TracerOption

WithLocalEndpoint sets the local endpoint of the tracer.

func WithNoopSpan Uses

func WithNoopSpan(unsampledNoop bool) TracerOption

WithNoopSpan if set to true will switch to a NoopSpan implementation if the trace is not sampled.

func WithNoopTracer Uses

func WithNoopTracer(tracerNoop bool) TracerOption

WithNoopTracer allows one to start the Tracer as Noop implementation.

func WithSampler Uses

func WithSampler(sampler Sampler) TracerOption

WithSampler allows one to set a Sampler function

func WithSharedSpans Uses

func WithSharedSpans(val bool) TracerOption

WithSharedSpans allows to place client-side and server-side annotations for a RPC call in the same span (Zipkin V1 behavior) or different spans (more in line with other tracing solutions). By default this Tracer uses shared host spans (so client-side and server-side in the same span).

func WithTags Uses

func WithTags(tags map[string]string) TracerOption

WithTags allows one to set default tags to be added to each created span

func WithTraceID128Bit Uses

func WithTraceID128Bit(val bool) TracerOption

WithTraceID128Bit if set to true will instruct the Tracer to start traces with 128 bit TraceID's. If set to false the Tracer will start traces with 64 bits.

Directories

PathSynopsis
idgeneratorPackage idgenerator contains several Span and Trace ID generators which can be used by the Zipkin tracer.
middleware/grpcPackage grpc contains several gRPC handlers which can be used for instrumenting calls with Zipkin.
middleware/httpPackage http contains several http middlewares which can be used for instrumenting calls with Zipkin.
modelPackage model contains the Zipkin V2 model which is used by the Zipkin Go tracer implementation.
propagationPackage propagation holds the required function signatures for Injection and Extraction as used by the Zipkin Tracer.
propagation/b3Package b3 implements serialization and deserialization logic for Zipkin B3 Headers.
proto/testing
proto/v2Package zipkin_proto3 adds support for the Zipkin protobuf definition to allow Go applications to consume model.SpanModel from protobuf serialized data.
reporterPackage reporter holds the Reporter interface which is used by the Zipkin Tracer to send finished spans.
reporter/amqpPackage amqp implements a RabbitMq reporter to send spans to a Rabbit server/cluster.
reporter/httpPackage http implements a HTTP reporter to send spans to Zipkin V2 collectors.
reporter/kafkaPackage kafka implements a Kafka reporter to send spans to a Kafka server/cluster.
reporter/logPackage log implements a reporter to send spans in V2 JSON format to the Go standard Logger.
reporter/recorderPackage recorder implements a reporter to record spans in v2 format.

Package zipkin imports 15 packages (graph) and is imported by 55 packages. Updated 2019-11-04. Refresh now. Tools for package owners.