Codebase list golang-github-go-kit-kit / 9fcaac9
BugFixes to opentracing.From*Request logic & Zipkin Wiring The opentracing.FromHTTPRequest and opentracing.FromGRPCRequest incorrectly assumed span would be nil on a Join error. This made the next step crash in a server side implementation. Added Zipkin to the examples to highlight the availability of it through OpenTracing. Bas van Beek 7 years ago
4 changed file(s) with 57 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
88 "strings"
99 "time"
1010
11 zipkin "github.com/basvanbeek/zipkin-go-opentracing"
1112 "github.com/lightstep/lightstep-tracer-go"
1213 "github.com/opentracing/opentracing-go"
1314 appdashot "github.com/sourcegraph/appdash/opentracing"
3637 thriftBufferSize = flag.Int("thrift.buffer.size", 0, "0 for unbuffered")
3738 thriftFramed = flag.Bool("thrift.framed", false, "true to enable framing")
3839
39 // Two OpenTracing backends (to demonstrate how they can be interchanged):
40 // Three OpenTracing backends (to demonstrate how they can be interchanged):
41 zipkinAddr = flag.String("zipkin.kafka.addr", "", "Enable Zipkin tracing via a Kafka Collector host:port")
4042 appdashAddr = flag.String("appdash.addr", "", "Enable Appdash tracing via an Appdash server host:port")
4143 lightstepAccessToken = flag.String("lightstep.token", "", "Enable LightStep tracing via a LightStep access token")
4244 )
6264 var tracer opentracing.Tracer
6365 {
6466 switch {
65 case *appdashAddr != "" && *lightstepAccessToken == "":
67 case *appdashAddr != "" && *lightstepAccessToken == "" && *zipkinAddr == "":
6668 tracer = appdashot.NewTracer(appdash.NewRemoteCollector(*appdashAddr))
67 case *appdashAddr == "" && *lightstepAccessToken != "":
69 case *appdashAddr == "" && *lightstepAccessToken != "" && *zipkinAddr == "":
6870 tracer = lightstep.NewTracer(lightstep.Options{
6971 AccessToken: *lightstepAccessToken,
7072 })
7173 defer lightstep.FlushLightStepTracer(tracer)
72 case *appdashAddr == "" && *lightstepAccessToken == "":
74 case *appdashAddr == "" && *lightstepAccessToken == "" && *zipkinAddr != "":
75 collector, err := zipkin.NewKafkaCollector(
76 strings.Split(*zipkinAddr, ","),
77 zipkin.KafkaLogger(tracingLogger),
78 )
79 if err != nil {
80 tracingLogger.Log("err", "unable to create kafka collector")
81 os.Exit(1)
82 }
83 tracer, err = zipkin.NewTracer(
84 zipkin.NewRecorder(collector, false, "localhost:8000", "addsvc-client"),
85 )
86 if err != nil {
87 tracingLogger.Log("err", "unable to create zipkin tracer")
88 os.Exit(1)
89 }
90 case *appdashAddr == "" && *lightstepAccessToken == "" && *zipkinAddr == "":
7391 tracer = opentracing.GlobalTracer() // no-op
7492 default:
75 panic("specify either -appdash.addr or -lightstep.access.token, not both")
93 panic("specify a single -appdash.addr, -lightstep.access.token or -zipkin.kafka.addr")
7694 }
7795 }
7896
135153 logger.Log("err", "invalid method "+method)
136154 os.Exit(1)
137155 }
156 // wait for collector
157 time.Sleep(2 * time.Second)
138158 }
139159
140160 func buildEndpoint(tracer opentracing.Tracer, operationName string, instances []string, factory loadbalancer.Factory, seed int64, logger log.Logger) endpoint.Endpoint {
1414 "time"
1515
1616 "github.com/apache/thrift/lib/go/thrift"
17 zipkin "github.com/basvanbeek/zipkin-go-opentracing"
1718 "github.com/lightstep/lightstep-tracer-go"
1819 "github.com/opentracing/opentracing-go"
1920 stdprometheus "github.com/prometheus/client_golang/prometheus"
3132 "github.com/go-kit/kit/metrics/expvar"
3233 "github.com/go-kit/kit/metrics/prometheus"
3334 kitot "github.com/go-kit/kit/tracing/opentracing"
34 "github.com/go-kit/kit/tracing/zipkin"
3535 httptransport "github.com/go-kit/kit/transport/http"
3636 )
3737
5050 thriftFramed = fs.Bool("thrift.framed", false, "true to enable framing")
5151
5252 // Supported OpenTracing backends
53 zipkinAddr = fs.String("zipkin.kafka.addr", "", "Enable Zipkin tracing via a Kafka server host:port")
5354 appdashAddr = fs.String("appdash.addr", "", "Enable Appdash tracing via an Appdash server host:port")
5455 lightstepAccessToken = fs.String("lightstep.token", "", "Enable LightStep tracing via a LightStep access token")
5556 )
8788 var tracer opentracing.Tracer
8889 {
8990 switch {
90 case *appdashAddr != "" && *lightstepAccessToken == "":
91 case *appdashAddr != "" && *lightstepAccessToken == "" && *zipkinAddr == "":
9192 tracer = appdashot.NewTracer(appdash.NewRemoteCollector(*appdashAddr))
92 case *appdashAddr == "" && *lightstepAccessToken != "":
93 case *appdashAddr == "" && *lightstepAccessToken != "" && *zipkinAddr == "":
9394 tracer = lightstep.NewTracer(lightstep.Options{
9495 AccessToken: *lightstepAccessToken,
9596 })
9697 defer lightstep.FlushLightStepTracer(tracer)
97 case *appdashAddr == "" && *lightstepAccessToken == "":
98 case *appdashAddr == "" && *lightstepAccessToken == "" && *zipkinAddr != "":
99 collector, err := zipkin.NewKafkaCollector(
100 strings.Split(*zipkinAddr, ","),
101 zipkin.KafkaLogger(logger),
102 )
103 if err != nil {
104 logger.Log("err", "unable to create kafka collector")
105 os.Exit(1)
106 }
107 tracer, err = zipkin.NewTracer(
108 zipkin.NewRecorder(collector, false, "localhost:80", "addsvc"),
109 )
110 if err != nil {
111 logger.Log("err", "unable to create zipkin tracer")
112 os.Exit(1)
113 }
114 case *appdashAddr == "" && *lightstepAccessToken == "" && *zipkinAddr == "":
98115 tracer = opentracing.GlobalTracer() // no-op
99116 default:
100 panic("specify either -appdash.addr or -lightstep.access.token, not both")
117 panic("specify a single -appdash.addr, -lightstep.access.token or -zipkin.kafka.addr")
101118 }
102119 }
103120
236253 signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
237254 return fmt.Errorf("%s", <-c)
238255 }
239
240 type loggingCollector struct{ log.Logger }
241
242 func (c loggingCollector) Collect(s *zipkin.Span) error {
243 annotations := s.Encode().GetAnnotations()
244 values := make([]string, len(annotations))
245 for i, a := range annotations {
246 values[i] = a.Value
247 }
248 c.Logger.Log(
249 "trace_id", s.TraceID(),
250 "span_id", s.SpanID(),
251 "parent_span_id", s.ParentSpanID(),
252 "annotations", strings.Join(values, " "),
253 )
254 return nil
255 }
256
257 func (c loggingCollector) ShouldSample(*zipkin.Span) bool { return true }
258
259 func (c loggingCollector) Close() error { return nil }
3838 func FromGRPCRequest(tracer opentracing.Tracer, operationName string, logger log.Logger) func(ctx context.Context, md *metadata.MD) context.Context {
3939 return func(ctx context.Context, md *metadata.MD) context.Context {
4040 span, err := tracer.Join(operationName, opentracing.TextMap, metadataReaderWriter{md})
41 if err != nil && logger != nil {
42 logger.Log("msg", "Join failed", "err", err)
43 }
44 if span == nil {
41 if err != nil {
4542 span = tracer.StartSpan(operationName)
43 if logger != nil {
44 logger.Log("msg", "Join failed", "err", err)
45 }
4646 }
4747 return opentracing.ContextWithSpan(ctx, span)
4848 }
5656 // The logger is used to report errors and may be nil.
5757 func FromHTTPRequest(tracer opentracing.Tracer, operationName string, logger log.Logger) kithttp.RequestFunc {
5858 return func(ctx context.Context, req *http.Request) context.Context {
59 // Try to join to a trace propagated in `req`. There's nothing we can
60 // do with any errors here, so we ignore them.
59 // Try to join to a trace propagated in `req`.
6160 span, err := tracer.Join(
6261 operationName,
6362 opentracing.TextMap,
6463 opentracing.HTTPHeaderTextMapCarrier(req.Header),
6564 )
66 if err != nil && logger != nil {
67 logger.Log("msg", "Join failed", "err", err)
68 }
69 if span == nil {
70 span = opentracing.StartSpan(operationName)
65 if err != nil {
66 span = tracer.StartSpan(operationName)
67 if logger != nil {
68 logger.Log("msg", "Join failed", "err", err)
69 }
7170 }
7271 return opentracing.ContextWithSpan(ctx, span)
7372 }