Skip to content

Commit

Permalink
初始化项目
Browse files Browse the repository at this point in the history
  • Loading branch information
fw committed Sep 20, 2019
1 parent 2a8e932 commit 6a79230
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 2 deletions.
30 changes: 28 additions & 2 deletions README.md
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,
}
```
5 changes: 5 additions & 0 deletions go.mod
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
2 changes: 2 additions & 0 deletions go.sum
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=
92 changes: 92 additions & 0 deletions httptracer.go
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
}

107 changes: 107 additions & 0 deletions httptracer_test.go
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
}

0 comments on commit 6a79230

Please sign in to comment.