-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
fw
committed
Sep 20, 2019
1 parent
2a8e932
commit 6a79230
Showing
5 changed files
with
234 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,28 @@ | ||
# http-opentracing | ||
用于http调用链增加opentracing协议 | ||
# opentracing net/http | ||
|
||
|
||
|
||
[OpenTracing](http://opentracing.io/) instrumentation for [net/http] | ||
|
||
## Usage | ||
|
||
implements http RoundTrip by `NewTraceTracesport(rt http.RoundTripper, activeSpanKey string,peerService string, extraTags ...opentracing.Tag)` . | ||
|
||
Example : | ||
|
||
```go | ||
tracertan := httpinvoke.NewTraceTracesport(http.DefaultTransport,"","",opentracing.Tag{Key:"ab",Value:"b"}) | ||
|
||
client := &http.Client{ | ||
Transport:tracertan, | ||
} | ||
``` | ||
Example for rpcx : | ||
|
||
```go | ||
tracertan := httpinvoke.NewTraceTracesport(http.DefaultTransport,share.OpentracingSpanServerKey,"",opentracing.Tag{Key:"ab",Value:"b"}) | ||
|
||
client := &http.Client{ | ||
Transport:tracertan, | ||
} | ||
``` |
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module . | ||
|
||
go 1.12 | ||
|
||
require github.com/opentracing/opentracing-go v1.1.0 // indirect |
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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= | ||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= |
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 |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package httpinvoke | ||
|
||
import ( | ||
"github.com/opentracing/opentracing-go" | ||
"github.com/opentracing/opentracing-go/ext" | ||
"github.com/opentracing/opentracing-go/log" | ||
"net/http" | ||
) | ||
|
||
const _defaultComponentName = "net/http" | ||
|
||
|
||
// TraceTransport wraps a RoundTripper. If a request is being traced with | ||
// Tracer, Transport will inject the current span into the headers, | ||
// and set HTTP related tags on the span. | ||
type TraceTransport struct { | ||
//spankey from parentTrace | ||
activeSpanKey string | ||
//peerService addr | ||
peerService string | ||
//extraTags to be set | ||
extraTags []opentracing.Tag | ||
// The actual RoundTripper to use for the request. A nil | ||
// RoundTripper defaults to http.DefaultTransport. | ||
http.RoundTripper | ||
} | ||
|
||
// NewTraceTracesport NewTraceTracesport | ||
func NewTraceTracesport(rt http.RoundTripper, activeSpanKey string,peerService string, extraTags ...opentracing.Tag) *TraceTransport { | ||
return &TraceTransport{RoundTripper: rt,activeSpanKey:activeSpanKey, peerService: peerService, extraTags: extraTags} | ||
} | ||
|
||
// RoundTrip implements the RoundTripper interface | ||
func (t *TraceTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||
rt := t.RoundTripper | ||
if rt == nil { | ||
rt = http.DefaultTransport | ||
} | ||
var tr opentracing.Span | ||
if t.activeSpanKey != "" { | ||
acvspans := req.Context().Value(t.activeSpanKey) | ||
if acvspans == nil{ | ||
return rt.RoundTrip(req) | ||
} | ||
tr = opentracing.SpanFromContext(opentracing.ContextWithSpan(req.Context(), acvspans.(opentracing.Span))) | ||
} else { | ||
tr = opentracing.SpanFromContext(req.Context()) | ||
} | ||
|
||
if tr == nil { | ||
return rt.RoundTrip(req) | ||
} | ||
operationName := "HTTP:" + req.Method | ||
//get start new tracer | ||
tracer := tr.Tracer() | ||
span := tracer.StartSpan(operationName, opentracing.ChildOf(tr.Context())) | ||
|
||
ext.DBType.Set(span, "http") | ||
//ext.PeerAddress.Set(span, req.URL.String()) | ||
ext.HTTPMethod.Set(span,req.Method) | ||
ext.HTTPUrl.Set(span, req.URL.String()) | ||
/*ext.SpanKind.Set(span, ext.SpanKindRPCClientEnum)*/ | ||
ext.Component.Set(span,_defaultComponentName) | ||
//end | ||
if t.peerService != "" { | ||
ext.PeerService.Set(span,t.peerService) | ||
} | ||
for _, v := range t.extraTags { | ||
span.SetTag(v.Key, v.Value) | ||
} | ||
// inject trace to http header | ||
tracer.Inject(span.Context(),opentracing.HTTPHeaders,req.Header) | ||
|
||
// ct := clientTracer{tr: tr} | ||
// req = req.WithContext(httptrace.WithClientTrace(req.Context(), ct.clientTrace())) | ||
resp, err := rt.RoundTrip(req) | ||
|
||
if err != nil { | ||
ext.Error.Set(span, true) | ||
span.LogFields(log.String("event", "error"), log.String("message", err.Error())) | ||
span.Finish() | ||
return resp, err | ||
} | ||
|
||
ext.HTTPStatusCode.Set(span,uint16(resp.StatusCode)) | ||
if resp.StatusCode >= 400 { | ||
ext.Error.Set(span, true) | ||
} | ||
span.Finish() | ||
return resp, err | ||
} | ||
|
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 |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package httpinvoke | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/opentracing/opentracing-go" | ||
zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing" | ||
"github.com/openzipkin/zipkin-go" | ||
"github.com/openzipkin/zipkin-go/reporter" | ||
zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http" | ||
"log" | ||
"net/http" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestHttpTrace(t *testing.T) { | ||
|
||
initZipkinV2() | ||
span := opentracing.StartSpan("test-case") | ||
span.Finish() | ||
ctx := opentracing.ContextWithSpan(context.Background(),span) | ||
mux := http.NewServeMux() | ||
wait := make(chan bool,1) | ||
mux.HandleFunc("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
keys := []string{"x-b3-traceid","x-b3-spanid","x-b3-parentspanid","x-b3-sampled"} | ||
for _, key := range keys { | ||
fmt.Println(r.Header.Get(key)) | ||
if r.Header.Get(key) == "" { | ||
t.Errorf("empty key: %s", key) | ||
} | ||
} | ||
wait <- true | ||
})) | ||
|
||
server := &http.Server{ | ||
Addr: ":4400", | ||
WriteTimeout: 4 * time.Second, | ||
Handler: mux, | ||
} | ||
|
||
defer server.Close() | ||
//创建http服务监听 | ||
go func(){ | ||
err := server.ListenAndServe() | ||
if err != nil { | ||
if err == http.ErrServerClosed { | ||
log.Print("Server closed under requeset!!") | ||
} else { | ||
log.Fatal("Server closed unexpecteed!!") | ||
} | ||
|
||
} | ||
}() | ||
|
||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1"+server.Addr, nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
req = req.WithContext(ctx) | ||
tracertan := NewTraceTracesport(http.DefaultTransport,"","",opentracing.Tag{Key:"ab",Value:"b"}) | ||
client := &http.Client{Transport: tracertan} | ||
if _, err = client.Do(req); err != nil { | ||
t.Fatal(err) | ||
} | ||
<-wait | ||
|
||
} | ||
|
||
/** | ||
*init zipkin tracer | ||
*/ | ||
func initZipkinV2() reporter.Reporter { | ||
msg := "init_zipkin-v2_err" | ||
|
||
// set up a span reporter | ||
reporter := zipkinhttp.NewReporter("") | ||
if reporter == nil { | ||
|
||
panic(msg) | ||
} | ||
|
||
// create our local service endpoint | ||
endpoint, err := zipkin.NewEndpoint("test", "127.0.0.1:4400") | ||
if err != nil || endpoint == nil { | ||
msg := fmt.Sprintf("%v\t%v", msg, err) | ||
panic(msg) | ||
} | ||
|
||
// initialize our tracer | ||
nativeTracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint)) | ||
if err != nil || nativeTracer == nil { | ||
msg := fmt.Sprintf("%v\t%v", msg, err) | ||
panic(msg) | ||
} | ||
|
||
// use zipkin-go-opentracing to wrap our tracer | ||
tracer := zipkinot.Wrap(nativeTracer) | ||
if tracer == nil { | ||
panic(msg) | ||
} | ||
|
||
// optionally set as Global OpenTracing tracer instance | ||
opentracing.SetGlobalTracer(tracer) | ||
|
||
return reporter | ||
} |