update deps (#686)

This commit is contained in:
Miek Gieben
2017-06-01 18:11:50 +01:00
committed by GitHub
parent 30ecb83dce
commit 3752a97135
6538 changed files with 9 additions and 2217448 deletions

View File

@@ -1,150 +0,0 @@
// Autogenerated by Thrift Compiler (0.9.3)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package main
import (
"flag"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
"math"
"net"
"net/url"
"os"
"scribe"
"strconv"
"strings"
)
func Usage() {
fmt.Fprintln(os.Stderr, "Usage of ", os.Args[0], " [-h host:port] [-u url] [-f[ramed]] function [arg1 [arg2...]]:")
flag.PrintDefaults()
fmt.Fprintln(os.Stderr, "\nFunctions:")
fmt.Fprintln(os.Stderr, " ResultCode Log( messages)")
fmt.Fprintln(os.Stderr)
os.Exit(0)
}
func main() {
flag.Usage = Usage
var host string
var port int
var protocol string
var urlString string
var framed bool
var useHttp bool
var parsedUrl url.URL
var trans thrift.TTransport
_ = strconv.Atoi
_ = math.Abs
flag.Usage = Usage
flag.StringVar(&host, "h", "localhost", "Specify host and port")
flag.IntVar(&port, "p", 9090, "Specify port")
flag.StringVar(&protocol, "P", "binary", "Specify the protocol (binary, compact, simplejson, json)")
flag.StringVar(&urlString, "u", "", "Specify the url")
flag.BoolVar(&framed, "framed", false, "Use framed transport")
flag.BoolVar(&useHttp, "http", false, "Use http")
flag.Parse()
if len(urlString) > 0 {
parsedUrl, err := url.Parse(urlString)
if err != nil {
fmt.Fprintln(os.Stderr, "Error parsing URL: ", err)
flag.Usage()
}
host = parsedUrl.Host
useHttp = len(parsedUrl.Scheme) <= 0 || parsedUrl.Scheme == "http"
} else if useHttp {
_, err := url.Parse(fmt.Sprint("http://", host, ":", port))
if err != nil {
fmt.Fprintln(os.Stderr, "Error parsing URL: ", err)
flag.Usage()
}
}
cmd := flag.Arg(0)
var err error
if useHttp {
trans, err = thrift.NewTHttpClient(parsedUrl.String())
} else {
portStr := fmt.Sprint(port)
if strings.Contains(host, ":") {
host, portStr, err = net.SplitHostPort(host)
if err != nil {
fmt.Fprintln(os.Stderr, "error with host:", err)
os.Exit(1)
}
}
trans, err = thrift.NewTSocket(net.JoinHostPort(host, portStr))
if err != nil {
fmt.Fprintln(os.Stderr, "error resolving address:", err)
os.Exit(1)
}
if framed {
trans = thrift.NewTFramedTransport(trans)
}
}
if err != nil {
fmt.Fprintln(os.Stderr, "Error creating transport", err)
os.Exit(1)
}
defer trans.Close()
var protocolFactory thrift.TProtocolFactory
switch protocol {
case "compact":
protocolFactory = thrift.NewTCompactProtocolFactory()
break
case "simplejson":
protocolFactory = thrift.NewTSimpleJSONProtocolFactory()
break
case "json":
protocolFactory = thrift.NewTJSONProtocolFactory()
break
case "binary", "":
protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()
break
default:
fmt.Fprintln(os.Stderr, "Invalid protocol specified: ", protocol)
Usage()
os.Exit(1)
}
client := scribe.NewScribeClientFactory(trans, protocolFactory)
if err := trans.Open(); err != nil {
fmt.Fprintln(os.Stderr, "Error opening socket to ", host, ":", port, " ", err)
os.Exit(1)
}
switch cmd {
case "Log":
if flag.NArg()-1 != 1 {
fmt.Fprintln(os.Stderr, "Log requires 1 args")
flag.Usage()
}
arg5 := flag.Arg(1)
mbTrans6 := thrift.NewTMemoryBufferLen(len(arg5))
defer mbTrans6.Close()
_, err7 := mbTrans6.WriteString(arg5)
if err7 != nil {
Usage()
return
}
factory8 := thrift.NewTSimpleJSONProtocolFactory()
jsProt9 := factory8.GetProtocol(mbTrans6)
containerStruct0 := scribe.NewScribeLogArgs()
err10 := containerStruct0.ReadField1(jsProt9)
if err10 != nil {
Usage()
return
}
argvalue0 := containerStruct0.Messages
value0 := argvalue0
fmt.Print(client.Log(value0))
fmt.Print("\n")
break
case "":
Usage()
break
default:
fmt.Fprintln(os.Stderr, "Invalid function ", cmd)
}
}

View File

@@ -1,43 +0,0 @@
package events
import (
"bytes"
"fmt"
"golang.org/x/net/trace"
"github.com/openzipkin/zipkin-go-opentracing"
)
// NetTraceIntegrator can be passed into a zipkintracer as NewSpanEventListener
// and causes all traces to be registered with the net/trace endpoint.
var NetTraceIntegrator = func() func(zipkintracer.SpanEvent) {
var tr trace.Trace
return func(e zipkintracer.SpanEvent) {
switch t := e.(type) {
case zipkintracer.EventCreate:
tr = trace.New("tracing", t.OperationName)
tr.SetMaxEvents(1000)
case zipkintracer.EventFinish:
tr.Finish()
case zipkintracer.EventTag:
tr.LazyPrintf("%s:%v", t.Key, t.Value)
case zipkintracer.EventLogFields:
var buf bytes.Buffer
for i, f := range t.Fields {
if i > 0 {
buf.WriteByte(' ')
}
fmt.Fprintf(&buf, "%s:%v", f.Key(), f.Value())
}
tr.LazyPrintf("%s", buf.String())
case zipkintracer.EventLog:
if t.Payload != nil {
tr.LazyPrintf("%s (payload %v)", t.Event, t.Payload)
} else {
tr.LazyPrintf("%s", t.Event)
}
}
}
}

View File

@@ -1,10 +0,0 @@
# builds the Cli and Svc1 & Svc2 projects
all: clean
@go get -v ./...
@go build -v -o build/svc1 ./svc1/cmd
@go build -v -o build/svc2 ./svc2/cmd
@go build -v -o build/cli ./cli
clean:
@rm -rf build

View File

@@ -1,35 +0,0 @@
## Zipkin tracing using OpenTracing API
This directory contains a super simple command line client and two HTTP services
which are instrumented using the OpenTracing API using the
[zipkin-go-opentracing](https://github.com/openzipkin/zipkin-go-opentracing)
tracer.
The code is a quick hack to solely demonstrate the usage of
[OpenTracing](http://opentracing.io) with a [Zipkin](http://zipkin.io) backend.
```
note: the examples will only compile with Go 1.7 or higher
```
## Usage:
Build `svc1`, `svc2` and `cli` with `make` and start both compiled services
found in the newly created `build` subdirectory.
When you call the `cli` program it will trigger two calls to `svc1` of which one
call will be proxied from `svc1` over to `svc2` to handle the method and by that
generating a couple of spans across services.
Methods have been instrumented with some examples of
[OpenTracing](http://opentracing.io) Tags which will be transformed into
[Zipkin](http://zipkin.io) binary annotations and
[OpenTracing](http://opentracing.io) LogEvents which will be transformed into
[Zipkin](http://zipkin.io) annotations.
The most interesting piece of code is found in `examples/middleware` which is
kind of the missing link for people looking for a tracing framework. I advise
you to seriously look into using [Go kit](https://gokit.io) and use its
abstractions and OpenTracing middleware with which this Tracer is fully
compatible, instead of rolling your own. If you still want to roll your own you
can use `examples/middleware` as a starting point.

View File

@@ -1,89 +0,0 @@
// +build go1.7
package main
import (
"fmt"
"os"
"github.com/opentracing/opentracing-go"
"golang.org/x/net/context"
zipkin "github.com/openzipkin/zipkin-go-opentracing"
"github.com/openzipkin/zipkin-go-opentracing/examples/cli_with_2_services/svc1"
)
const (
// Our service name.
serviceName = "cli"
// Host + port of our service.
hostPort = "0.0.0.0:0"
// Endpoint to send Zipkin spans to.
zipkinHTTPEndpoint = "http://localhost:9411/api/v1/spans"
// Debug mode.
debug = false
// Base endpoint of our SVC1 service.
svc1Endpoint = "http://localhost:61001"
// same span can be set to true for RPC style spans (Zipkin V1) vs Node style (OpenTracing)
sameSpan = true
// make Tracer generate 128 bit traceID's for root spans.
traceID128Bit = true
)
//ci
func main() {
// Create our HTTP collector.
collector, err := zipkin.NewHTTPCollector(zipkinHTTPEndpoint)
if err != nil {
fmt.Printf("unable to create Zipkin HTTP collector: %+v", err)
os.Exit(-1)
}
// Create our recorder.
recorder := zipkin.NewRecorder(collector, debug, hostPort, serviceName)
// Create our tracer.
tracer, err := zipkin.NewTracer(
recorder,
zipkin.ClientServerSameSpan(sameSpan),
zipkin.TraceID128Bit(traceID128Bit),
)
if err != nil {
fmt.Printf("unable to create Zipkin tracer: %+v", err)
os.Exit(-1)
}
// Explicitly set our tracer to be the default tracer.
opentracing.InitGlobalTracer(tracer)
// Create Client to svc1 Service
client := svc1.NewHTTPClient(tracer, svc1Endpoint)
// Create Root Span for duration of the interaction with svc1
span := opentracing.StartSpan("Run")
// Put root span in context so it will be used in our calls to the client.
ctx := opentracing.ContextWithSpan(context.Background(), span)
// Call the Concat Method
span.LogEvent("Call Concat")
res1, err := client.Concat(ctx, "Hello", " World!")
fmt.Printf("Concat: %s Err: %+v\n", res1, err)
// Call the Sum Method
span.LogEvent("Call Sum")
res2, err := client.Sum(ctx, 10, 20)
fmt.Printf("Sum: %d Err: %+v\n", res2, err)
// Finish our CLI span
span.Finish()
// Close collector to ensure spans are sent before exiting.
collector.Close()
}

View File

@@ -1,78 +0,0 @@
// +build go1.7
package main
import (
"fmt"
"net/http"
"os"
"github.com/opentracing/opentracing-go"
zipkin "github.com/openzipkin/zipkin-go-opentracing"
"github.com/openzipkin/zipkin-go-opentracing/examples/cli_with_2_services/svc1"
"github.com/openzipkin/zipkin-go-opentracing/examples/cli_with_2_services/svc2"
)
const (
// Our service name.
serviceName = "svc1"
// Host + port of our service.
hostPort = "127.0.0.1:61001"
// Endpoint to send Zipkin spans to.
zipkinHTTPEndpoint = "http://localhost:9411/api/v1/spans"
// Debug mode.
debug = false
// Base endpoint of our SVC2 service.
svc2Endpoint = "http://localhost:61002"
// same span can be set to true for RPC style spans (Zipkin V1) vs Node style (OpenTracing)
sameSpan = true
// make Tracer generate 128 bit traceID's for root spans.
traceID128Bit = true
)
//svc1
func main() {
// create collector.
collector, err := zipkin.NewHTTPCollector(zipkinHTTPEndpoint)
if err != nil {
fmt.Printf("unable to create Zipkin HTTP collector: %+v", err)
os.Exit(-1)
}
// create recorder.
recorder := zipkin.NewRecorder(collector, debug, hostPort, serviceName)
// create tracer.
tracer, err := zipkin.NewTracer(
recorder,
zipkin.ClientServerSameSpan(sameSpan),
zipkin.TraceID128Bit(traceID128Bit),
)
if err != nil {
fmt.Printf("unable to create Zipkin tracer: %+v", err)
os.Exit(-1)
}
// explicitly set our tracer to be the default tracer.
opentracing.InitGlobalTracer(tracer)
// create the client to svc2
svc2Client := svc2.NewHTTPClient(tracer, svc2Endpoint)
// create the service implementation
service := svc1.NewService(svc2Client)
// create the HTTP Server Handler for the service
handler := svc1.NewHTTPHandler(tracer, service)
// start the service
fmt.Printf("Starting %s on %s\n", serviceName, hostPort)
http.ListenAndServe(hostPort, handler)
}

View File

@@ -1,125 +0,0 @@
// +build go1.7
package svc1
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
opentracing "github.com/opentracing/opentracing-go"
"golang.org/x/net/context"
"github.com/openzipkin/zipkin-go-opentracing/examples/middleware"
)
// client is our actual client implementation
type client struct {
baseURL string
httpClient *http.Client
tracer opentracing.Tracer
traceRequest middleware.RequestFunc
}
// Concat implements our Service interface.
func (c *client) Concat(ctx context.Context, a, b string) (string, error) {
// create new span using span found in context as parent (if none is found,
// our span becomes the trace root).
span, ctx := opentracing.StartSpanFromContext(ctx, "Concat")
defer span.Finish()
// assemble URL query
url := fmt.Sprintf(
"%s/concat/?a=%s&b=%s", c.baseURL, url.QueryEscape(a), url.QueryEscape(b),
)
// create the HTTP request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", err
}
// use our middleware to propagate our trace
req = c.traceRequest(req.WithContext(ctx))
// execute the HTTP request
resp, err := c.httpClient.Do(req)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return "", err
}
defer resp.Body.Close()
// read the http response body
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return "", err
}
// return the result
return string(data), nil
}
// Sum implements our Service interface.
func (c *client) Sum(ctx context.Context, a, b int64) (int64, error) {
// create new span using span found in context as parent (if none is found,
// our span becomes the trace root).
span, ctx := opentracing.StartSpanFromContext(ctx, "Sum")
defer span.Finish()
// assemble URL query
url := fmt.Sprintf("%s/sum/?a=%d&b=%d", c.baseURL, a, b)
// create the HTTP request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return 0, err
}
// use our middleware to propagate our trace
req = c.traceRequest(req.WithContext(ctx))
// execute the HTTP request
resp, err := c.httpClient.Do(req)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return 0, err
}
defer resp.Body.Close()
// read the http response body
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return 0, err
}
// convert html response to expected result type (int64)
result, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return 0, err
}
// return the result
return result, nil
}
// NewHTTPClient returns a new client instance to our svc1 using the HTTP
// transport.
func NewHTTPClient(tracer opentracing.Tracer, baseURL string) Service {
return &client{
baseURL: baseURL,
httpClient: &http.Client{},
tracer: tracer,
traceRequest: middleware.ToHTTPRequest(tracer),
}
}

View File

@@ -1,84 +0,0 @@
// +build go1.7
package svc1
import (
"fmt"
"net/http"
"strconv"
opentracing "github.com/opentracing/opentracing-go"
"github.com/openzipkin/zipkin-go-opentracing/examples/middleware"
)
type httpService struct {
service Service
}
// concatHandler is our HTTP HandlerFunc for a Concat request.
func (s *httpService) concatHandler(w http.ResponseWriter, req *http.Request) {
// parse query parameters
v := req.URL.Query()
result, err := s.service.Concat(req.Context(), v.Get("a"), v.Get("b"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// return the result
w.Write([]byte(result))
}
// sumHandler is our HTTP Handlerfunc for a Sum request.
func (s *httpService) sumHandler(w http.ResponseWriter, req *http.Request) {
// parse query parameters
v := req.URL.Query()
a, err := strconv.ParseInt(v.Get("a"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
b, err := strconv.ParseInt(v.Get("b"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// call our Sum binding
result, err := s.service.Sum(req.Context(), a, b)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// return the result
w.Write([]byte(fmt.Sprintf("%d", result)))
}
// NewHTTPHandler returns a new HTTP handler our svc1.
func NewHTTPHandler(tracer opentracing.Tracer, service Service) http.Handler {
// Create our HTTP Service.
svc := &httpService{service: service}
// Create the mux.
mux := http.NewServeMux()
// Create the Concat handler.
var concatHandler http.Handler
concatHandler = http.HandlerFunc(svc.concatHandler)
// Wrap the Concat handler with our tracing middleware.
concatHandler = middleware.FromHTTPRequest(tracer, "Concat")(concatHandler)
// Create the Sum handler.
var sumHandler http.Handler
sumHandler = http.HandlerFunc(svc.sumHandler)
// Wrap the Sum handler with our tracing middleware.
sumHandler = middleware.FromHTTPRequest(tracer, "Sum")(sumHandler)
// Wire up the mux.
mux.Handle("/concat/", concatHandler)
mux.Handle("/sum/", sumHandler)
// Return the mux.
return mux
}

View File

@@ -1,49 +0,0 @@
// +build go1.7
package svc1
import (
opentracing "github.com/opentracing/opentracing-go"
"golang.org/x/net/context"
"github.com/openzipkin/zipkin-go-opentracing/examples/cli_with_2_services/svc2"
)
// svc1 is our actual service implementation
type svc1 struct {
svc2Client svc2.Service
}
func (s *svc1) Concat(ctx context.Context, a, b string) (string, error) {
// test for length overflow
if len(a)+len(b) > StrMaxSize {
// pull span from context (has already been created by our middleware)
span := opentracing.SpanFromContext(ctx)
span.SetTag("error", ErrMaxSize.Error())
return "", ErrMaxSize
}
return a + b, nil
}
func (s *svc1) Sum(ctx context.Context, a, b int64) (int64, error) {
// pull span from context (has already been created by our middleware)
span := opentracing.SpanFromContext(ctx)
span.SetTag("proxy-to", "svc2")
// proxy request to svc2
result, err := s.svc2Client.Sum(ctx, a, b)
if err != nil {
span.SetTag("error", err.Error())
return 0, err
}
return result, nil
}
// NewService returns a new implementation of our Service.
func NewService(svc2Client svc2.Service) Service {
return &svc1{
svc2Client: svc2Client,
}
}

View File

@@ -1,25 +0,0 @@
// +build go1.7
package svc1
import (
"errors"
"golang.org/x/net/context"
)
// Service constants
const (
StrMaxSize = 1024
)
// Service errors
var (
ErrMaxSize = errors.New("maximum size of 1024 bytes exceeded")
)
// Service interface
type Service interface {
Concat(ctx context.Context, a, b string) (string, error)
Sum(ctx context.Context, a, b int64) (int64, error)
}

View File

@@ -1,71 +0,0 @@
// +build go1.7
package main
import (
"fmt"
"net/http"
"os"
"github.com/opentracing/opentracing-go"
zipkin "github.com/openzipkin/zipkin-go-opentracing"
"github.com/openzipkin/zipkin-go-opentracing/examples/cli_with_2_services/svc2"
)
const (
// Our service name.
serviceName = "svc2"
// Host + port of our service.
hostPort = "127.0.0.1:61002"
// Endpoint to send Zipkin spans to.
zipkinHTTPEndpoint = "http://localhost:9411/api/v1/spans"
// Debug mode.
debug = false
// same span can be set to true for RPC style spans (Zipkin V1) vs Node style (OpenTracing)
sameSpan = true
// make Tracer generate 128 bit traceID's for root spans.
traceID128Bit = true
)
//svc2
func main() {
// create collector.
collector, err := zipkin.NewHTTPCollector(zipkinHTTPEndpoint)
if err != nil {
fmt.Printf("unable to create Zipkin HTTP collector: %+v", err)
os.Exit(-1)
}
// create recorder.
recorder := zipkin.NewRecorder(collector, debug, hostPort, serviceName)
// create tracer.
tracer, err := zipkin.NewTracer(
recorder,
zipkin.ClientServerSameSpan(sameSpan),
zipkin.TraceID128Bit(traceID128Bit),
)
if err != nil {
fmt.Printf("unable to create Zipkin tracer: %+v", err)
os.Exit(-1)
}
// explicitly set our tracer to be the default tracer.
opentracing.InitGlobalTracer(tracer)
// create the service implementation
service := svc2.NewService()
// create the HTTP Server Handler for the service
handler := svc2.NewHTTPHandler(tracer, service)
// start the service
fmt.Printf("Starting %s on %s\n", serviceName, hostPort)
http.ListenAndServe(hostPort, handler)
}

View File

@@ -1,82 +0,0 @@
// +build go1.7
package svc2
import (
"fmt"
"io/ioutil"
"net/http"
"strconv"
opentracing "github.com/opentracing/opentracing-go"
"golang.org/x/net/context"
"github.com/openzipkin/zipkin-go-opentracing/examples/middleware"
)
// client is our actual client implementation
type client struct {
baseURL string
httpClient *http.Client
tracer opentracing.Tracer
traceRequest middleware.RequestFunc
}
// Sum implements our Service interface.
func (c *client) Sum(ctx context.Context, a int64, b int64) (int64, error) {
// create new span using span found in context as parent (if none is found,
// our span becomes the trace root).
span, ctx := opentracing.StartSpanFromContext(ctx, "Sum")
defer span.Finish()
// assemble URL query
url := fmt.Sprintf("%s/sum/?a=%d&b=%d", c.baseURL, a, b)
// create the HTTP request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return 0, err
}
// use our middleware to propagate our trace
req = c.traceRequest(req.WithContext(ctx))
// execute the HTTP request
resp, err := c.httpClient.Do(req)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return 0, err
}
defer resp.Body.Close()
// read the http response body
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return 0, err
}
// convert html response to expected result type (int64)
result, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
// annotate our span with the error condition
span.SetTag("error", err.Error())
return 0, err
}
// return the result
return result, nil
}
// NewHTTPClient returns a new client instance to our svc2 using the HTTP
// transport.
func NewHTTPClient(tracer opentracing.Tracer, baseURL string) Service {
return &client{
baseURL: baseURL,
httpClient: &http.Client{},
tracer: tracer,
traceRequest: middleware.ToHTTPRequest(tracer),
}
}

View File

@@ -1,63 +0,0 @@
// +build go1.7
package svc2
import (
"fmt"
"net/http"
"strconv"
opentracing "github.com/opentracing/opentracing-go"
"github.com/openzipkin/zipkin-go-opentracing/examples/middleware"
)
type httpService struct {
service Service
}
// sumHandler is our HTTP Handlerfunc for a Sum request.
func (s *httpService) sumHandler(w http.ResponseWriter, req *http.Request) {
// parse query parameters
v := req.URL.Query()
a, err := strconv.ParseInt(v.Get("a"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
b, err := strconv.ParseInt(v.Get("b"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// call our Sum binding
result, err := s.service.Sum(req.Context(), a, b)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// return the result
w.Write([]byte(fmt.Sprintf("%d", result)))
}
// NewHTTPHandler returns a new HTTP handler our svc2.
func NewHTTPHandler(tracer opentracing.Tracer, service Service) http.Handler {
// Create our HTTP Service.
svc := &httpService{service: service}
// Create the mux.
mux := http.NewServeMux()
// Create the Sum handler.
var sumHandler http.Handler
sumHandler = http.HandlerFunc(svc.sumHandler)
// Wrap the Sum handler with our tracing middleware.
sumHandler = middleware.FromHTTPRequest(tracer, "Sum")(sumHandler)
// Wire up the mux.
mux.Handle("/sum/", sumHandler)
// Return the mux.
return mux
}

View File

@@ -1,77 +0,0 @@
// +build go1.7
package svc2
import (
"time"
opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"golang.org/x/net/context"
)
// svc2 is our actual service implementation.
type svc2 struct{}
// NewService returns a new implementation of our Service.
func NewService() Service {
return &svc2{}
}
// Sum implements our Service interface.
func (s *svc2) Sum(ctx context.Context, a int64, b int64) (int64, error) {
// We love starting up slow
time.Sleep(5 * time.Millisecond)
// Pull span from context.
span := opentracing.SpanFromContext(ctx)
// Example binary annotations.
span.SetTag("service", "svc2")
span.SetTag("key1", "value1")
span.SetTag("key2", 2)
// Example annotation
span.LogEvent("MyEventAnnotation")
// Let's wait a little so it shows up nicely in our tracing graphics.
time.Sleep(10 * time.Millisecond)
// Let's assume we want to trace a call we do to a database.
s.fakeDBCall(span)
// Check for Int overflow condition.
if (b > 0 && a > (Int64Max-b)) || (b < 0 && a < (Int64Min-b)) {
span.SetTag("error", ErrIntOverflow.Error())
return 0, ErrIntOverflow
}
// calculate and return the result (all that boilerplate for this?) ;)
return a + b, nil
}
func (s *svc2) fakeDBCall(span opentracing.Span) {
resourceSpan := opentracing.StartSpan(
"myComplexQuery",
opentracing.ChildOf(span.Context()),
)
defer resourceSpan.Finish()
// mark span as resource type
ext.SpanKind.Set(resourceSpan, "resource")
// name of the resource we try to reach
ext.PeerService.Set(resourceSpan, "PostgreSQL")
// hostname of the resource
ext.PeerHostname.Set(resourceSpan, "localhost")
// port of the resource
ext.PeerPort.Set(resourceSpan, 5432)
// let's binary annotate the query we run
resourceSpan.SetTag(
"query", "SELECT recipes FROM cookbook WHERE topic = 'world domination'",
)
// Let's assume the query is going to take some time. Finding the right
// world domination recipes is like searching for a needle in a haystack.
time.Sleep(20 * time.Millisecond)
// sweet... all done
}

View File

@@ -1,25 +0,0 @@
// +build go1.7
package svc2
import (
"errors"
"golang.org/x/net/context"
)
// Service constants
const (
Int64Max = 1<<63 - 1
Int64Min = -(Int64Max + 1)
)
// Service errors
var (
ErrIntOverflow = errors.New("integer overflow occurred")
)
// Service interface to our svc2 service.
type Service interface {
Sum(ctx context.Context, a int64, b int64) (int64, error)
}

View File

@@ -1,102 +0,0 @@
// +build go1.7
// Package middleware provides some usable transport middleware to deal with
// propagating Zipkin traces across service boundaries.
package middleware
import (
"fmt"
"net"
"net/http"
"strconv"
opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore"
)
// RequestFunc is a middleware function for outgoing HTTP requests.
type RequestFunc func(req *http.Request) *http.Request
// ToHTTPRequest returns a RequestFunc that injects an OpenTracing Span found in
// context into the HTTP Headers. If no such Span can be found, the RequestFunc
// is a noop.
func ToHTTPRequest(tracer opentracing.Tracer) RequestFunc {
return func(req *http.Request) *http.Request {
// Retrieve the Span from context.
if span := opentracing.SpanFromContext(req.Context()); span != nil {
// We are going to use this span in a client request, so mark as such.
ext.SpanKindRPCClient.Set(span)
// Add some standard OpenTracing tags, useful in an HTTP request.
ext.HTTPMethod.Set(span, req.Method)
span.SetTag(zipkincore.HTTP_HOST, req.URL.Host)
span.SetTag(zipkincore.HTTP_PATH, req.URL.Path)
ext.HTTPUrl.Set(
span,
fmt.Sprintf("%s://%s%s", req.URL.Scheme, req.URL.Host, req.URL.Path),
)
// Add information on the peer service we're about to contact.
if host, portString, err := net.SplitHostPort(req.URL.Host); err == nil {
ext.PeerHostname.Set(span, host)
if port, err := strconv.Atoi(portString); err != nil {
ext.PeerPort.Set(span, uint16(port))
}
} else {
ext.PeerHostname.Set(span, req.URL.Host)
}
// Inject the Span context into the outgoing HTTP Request.
if err := tracer.Inject(
span.Context(),
opentracing.TextMap,
opentracing.HTTPHeadersCarrier(req.Header),
); err != nil {
fmt.Printf("error encountered while trying to inject span: %+v", err)
}
}
return req
}
}
// HandlerFunc is a middleware function for incoming HTTP requests.
type HandlerFunc func(next http.Handler) http.Handler
// FromHTTPRequest returns a Middleware HandlerFunc that tries to join with an
// OpenTracing trace found in the HTTP request headers and starts a new Span
// called `operationName`. If no trace could be found in the HTTP request
// headers, the Span will be a trace root. The Span is incorporated in the
// HTTP Context object and can be retrieved with
// opentracing.SpanFromContext(ctx).
func FromHTTPRequest(tracer opentracing.Tracer, operationName string,
) HandlerFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// Try to join to a trace propagated in `req`.
wireContext, err := tracer.Extract(
opentracing.TextMap,
opentracing.HTTPHeadersCarrier(req.Header),
)
if err != nil {
fmt.Printf("error encountered while trying to extract span: %+v\n", err)
}
// create span
span := tracer.StartSpan(operationName, ext.RPCServerOption(wireContext))
span.SetTag("serverSide", "here")
defer span.Finish()
// store span in context
ctx := opentracing.ContextWithSpan(req.Context(), span)
// update request context to include our new span
req = req.WithContext(ctx)
// next middleware or actual request handler
next.ServeHTTP(w, req)
})
}
}