Great efforts have been made to make Zipkin easier to test, develop and experiment against. Zipkin can now be run from a single Docker container or by running its self-contained executable jar without extensive configuration. In its default configuration you will run Zipkin with a HTTP collector, In memory Span storage backend and web UI on port 9411.
Example:
docker run -d -p 9411:9411 openzipkin/zipkin
Follow the addsvc example to check out how to wire the Zipkin Middleware. The changes should be relatively minor.
The zipkin-go package has Reporters to send Spans to the Zipkin HTTP and Kafka Collectors.
To use the HTTP Reporter with a Zipkin instance running on localhost you bootstrap zipkin-go like this:
var (
serviceName = "MyService"
serviceHostPort = "localhost:8000"
zipkinHTTPEndpoint = "http://localhost:9411/api/v2/spans"
)
// create an instance of the HTTP Reporter.
reporter := zipkin.NewReporter(zipkinHTTPEndpoint)
// create our tracer's local endpoint (how the service is identified in Zipkin).
localEndpoint, err := zipkin.NewEndpoint(serviceName, serviceHostPort)
// create our tracer instance.
tracer, err = zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(localEndpoint))
...
Here is an example of how you could trace resources and work with local spans.
import (
zipkin "github.com/openzipkin/zipkin-go"
)
func (svc *Service) GetMeSomeExamples(ctx context.Context, ...) ([]Examples, error) {
// Example of annotating a database query:
var (
spanContext model.SpanContext
serviceName = "MySQL"
serviceHost = "mysql.example.com:3306"
queryLabel = "GetExamplesByParam"
query = "select * from example where param = :value"
)
// retrieve the parent span from context to use as parent if available.
if parentSpan := zipkin.SpanFromContext(ctx); parentSpan != nil {
spanContext = parentSpan.Context()
}
// create the remote Zipkin endpoint
ep, _ := zipkin.NewEndpoint(serviceName, serviceHost)
// create a new span to record the resource interaction
span := zipkin.StartSpan(
queryLabel,
zipkin.Parent(parentSpan.Context()),
zipkin.WithRemoteEndpoint(ep),
)
// add interesting key/value pair to our span
span.SetTag("query", query)
// add interesting timed event to our span
span.Annotate(time.Now(), "query:start")
// do the actual query...
// let's annotate the end...
span.Annotate(time.Now(), "query:end")
// we're done with this span.
span.Finish()
// do other stuff
...
}