# Zipkin
## Development and Testing Set-up
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
```
[zipkin]: http://zipkin.io
## Middleware Usage
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.
### Configuring the Zipkin HTTP Reporter
To use the HTTP Reporter with a [Zipkin] instance running on localhost you
bootstrap [zipkin-go] like this:
```go
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))
...
```
[zipkin-go]: https://github.com/openzipkin/zipkin-go
[addsvc]: https://github.com/go-kit/examples/tree/master/addsvc
[Log]: https://github.com/go-kit/kit/tree/master/log
### Tracing Resources
Here is an example of how you could trace resources and work with local spans.
```go
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
...
}
```