-
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from hb-chen/master
mv starter-kit's gateway plugin to x-gateway
- Loading branch information
Showing
27 changed files
with
82 additions
and
400 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
plugin/metrics/options.go → pkg/plugin/wrapper/metrics/options.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,188 +1,91 @@ | ||
// Package opentracing provides wrappers for OpenTracing | ||
package opentracing | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/micro/go-micro/client" | ||
"github.com/micro/go-micro/metadata" | ||
"github.com/micro/go-micro/registry" | ||
"github.com/micro/go-micro/server" | ||
"github.com/micro/micro/plugin" | ||
"github.com/opentracing/opentracing-go" | ||
) | ||
|
||
type otWrapper struct { | ||
ot opentracing.Tracer | ||
client.Client | ||
} | ||
|
||
// StartSpanFromContext returns a new span with the given operation name and options. If a span | ||
// is found in the context, it will be used as the parent of the resulting span. | ||
func StartSpanFromContext(ctx context.Context, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (context.Context, opentracing.Span, error) { | ||
md, ok := metadata.FromContext(ctx) | ||
if !ok { | ||
md = make(map[string]string) | ||
} | ||
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/util/response" | ||
) | ||
|
||
// copy the metadata to prevent race | ||
md = metadata.Copy(md) | ||
// StartSpanFromHeader returns a new span with the given operation name and options. If a span | ||
// is found in the header, it will be used as the parent of the resulting span. | ||
func StartSpanFromHeader(header http.Header, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (opentracing.Span, error) { | ||
|
||
// Find parent span. | ||
// First try to get span within current service boundary. | ||
// If there doesn't exist, try to get it from go-micro metadata(which is cross boundary) | ||
if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil { | ||
opts = append(opts, opentracing.ChildOf(parentSpan.Context())) | ||
} else if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(md)); err == nil { | ||
if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err == nil { | ||
opts = append(opts, opentracing.ChildOf(spanCtx)) | ||
} | ||
|
||
sp := tracer.StartSpan(name, opts...) | ||
|
||
if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.TextMapCarrier(md)); err != nil { | ||
return nil, nil, err | ||
if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err != nil { | ||
return nil, err | ||
} | ||
|
||
ctx = opentracing.ContextWithSpan(ctx, sp) | ||
ctx = metadata.NewContext(ctx, md) | ||
return ctx, sp, nil | ||
return sp, nil | ||
} | ||
|
||
// SpanFromContext returns a new span with the given operation name and options. | ||
// 如果没在context中没有找到span,返回nil | ||
func SpanFromContext(ctx context.Context, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (context.Context, opentracing.Span, error) { | ||
md, ok := metadata.FromContext(ctx) | ||
if !ok { | ||
md = make(map[string]string) | ||
} | ||
|
||
// copy the metadata to prevent race | ||
md = metadata.Copy(md) | ||
func SpanFromHeader(header http.Header, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (opentracing.Span, error) { | ||
|
||
// Find parent span. | ||
// First try to get span within current service boundary. | ||
// If there doesn't exist, try to get it from go-micro metadata(which is cross boundary) | ||
if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil { | ||
opts = append(opts, opentracing.ChildOf(parentSpan.Context())) | ||
} else if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(md)); err == nil { | ||
if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err == nil { | ||
opts = append(opts, opentracing.ChildOf(spanCtx)) | ||
} else { | ||
return ctx, nil, nil | ||
return nil, nil | ||
} | ||
|
||
sp := tracer.StartSpan(name, opts...) | ||
|
||
if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.TextMapCarrier(md)); err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
ctx = opentracing.ContextWithSpan(ctx, sp) | ||
ctx = metadata.NewContext(ctx, md) | ||
return ctx, sp, nil | ||
} | ||
|
||
func (o *otWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { | ||
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) | ||
ctx, span, err := SpanFromContext(ctx, o.ot, name) | ||
if err != nil { | ||
return err | ||
} else if span != nil { | ||
defer span.Finish() | ||
} | ||
|
||
return o.Client.Call(ctx, req, rsp, opts...) | ||
} | ||
|
||
func (o *otWrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { | ||
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) | ||
ctx, span, err := SpanFromContext(ctx, o.ot, name) | ||
if err != nil { | ||
if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err != nil { | ||
return nil, err | ||
} else if span != nil { | ||
defer span.Finish() | ||
} | ||
|
||
return o.Client.Stream(ctx, req, opts...) | ||
} | ||
|
||
func (o *otWrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error { | ||
name := fmt.Sprintf("Pub to %s", p.Topic()) | ||
ctx, span, err := SpanFromContext(ctx, o.ot, name) | ||
if err != nil { | ||
return err | ||
} else if span != nil { | ||
defer span.Finish() | ||
} | ||
|
||
return o.Client.Publish(ctx, p, opts...) | ||
return sp, nil | ||
} | ||
|
||
// NewClientWrapper accepts an open tracing Trace and returns a Client Wrapper | ||
func NewClientWrapper(ot opentracing.Tracer) client.Wrapper { | ||
return func(c client.Client) client.Client { | ||
if ot == nil { | ||
ot = opentracing.GlobalTracer() | ||
} | ||
return &otWrapper{ot, c} | ||
} | ||
func newPlugin(opts ...Option) plugin.Plugin { | ||
options := newOptions(opts...) | ||
return plugin.NewPlugin( | ||
plugin.WithName("trace"), | ||
plugin.WithHandler(func(h http.Handler) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
if options.skipperFunc(r) { | ||
h.ServeHTTP(w, r) | ||
return | ||
} | ||
|
||
name := r.URL.Path | ||
var span opentracing.Span | ||
var err error | ||
if options.autoStart { | ||
span, err = StartSpanFromHeader(r.Header, options.tracer, name) | ||
|
||
} else { | ||
span, err = SpanFromHeader(r.Header, options.tracer, name) | ||
} | ||
|
||
if err != nil { | ||
options.responseHandler(w, r, err) | ||
return | ||
} else if span != nil { | ||
defer span.Finish() | ||
|
||
span.SetTag("http.host", r.Host) | ||
span.SetTag("http.method", r.Method) | ||
|
||
ww := response.WrapWriter{ResponseWriter: w} | ||
h.ServeHTTP(&ww, r) | ||
|
||
span.SetTag("http.status_code", ww.StatusCode) | ||
} else { | ||
h.ServeHTTP(w, r) | ||
} | ||
}) | ||
}), | ||
) | ||
} | ||
|
||
// NewCallWrapper accepts an opentracing Tracer and returns a Call Wrapper | ||
func NewCallWrapper(ot opentracing.Tracer) client.CallWrapper { | ||
return func(cf client.CallFunc) client.CallFunc { | ||
return func(ctx context.Context, node *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error { | ||
if ot == nil { | ||
ot = opentracing.GlobalTracer() | ||
} | ||
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) | ||
ctx, span, err := SpanFromContext(ctx, ot, name) | ||
if err != nil { | ||
return err | ||
} else if span != nil { | ||
defer span.Finish() | ||
} | ||
|
||
return cf(ctx, node, req, rsp, opts) | ||
} | ||
} | ||
} | ||
|
||
// NewHandlerWrapper accepts an opentracing Tracer and returns a Handler Wrapper | ||
func NewHandlerWrapper(ot opentracing.Tracer) server.HandlerWrapper { | ||
return func(h server.HandlerFunc) server.HandlerFunc { | ||
return func(ctx context.Context, req server.Request, rsp interface{}) error { | ||
if ot == nil { | ||
ot = opentracing.GlobalTracer() | ||
} | ||
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) | ||
ctx, span, err := SpanFromContext(ctx, ot, name) | ||
if err != nil { | ||
return err | ||
} else if span != nil { | ||
defer span.Finish() | ||
} | ||
|
||
return h(ctx, req, rsp) | ||
} | ||
} | ||
} | ||
|
||
// NewSubscriberWrapper accepts an opentracing Tracer and returns a Subscriber Wrapper | ||
func NewSubscriberWrapper(ot opentracing.Tracer) server.SubscriberWrapper { | ||
return func(next server.SubscriberFunc) server.SubscriberFunc { | ||
return func(ctx context.Context, msg server.Message) error { | ||
name := "Pub to " + msg.Topic() | ||
if ot == nil { | ||
ot = opentracing.GlobalTracer() | ||
} | ||
ctx, span, err := SpanFromContext(ctx, ot, name) | ||
if err != nil { | ||
return err | ||
} else if span != nil { | ||
defer span.Finish() | ||
} | ||
|
||
return next(ctx, msg) | ||
} | ||
} | ||
func NewPlugin(opts ...Option) plugin.Plugin { | ||
return newPlugin(opts...) | ||
} |
Oops, something went wrong.