mirror of
https://github.com/astaxie/beego.git
synced 2024-11-21 22:00:54 +00:00
Support opentracing filter
This commit is contained in:
parent
2e891152dd
commit
75107f735e
77
pkg/httplib/filter/opentracing/filter.go
Normal file
77
pkg/httplib/filter/opentracing/filter.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2020 beego
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package opentracing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
logKit "github.com/go-kit/kit/log"
|
||||||
|
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
||||||
|
"github.com/opentracing/opentracing-go"
|
||||||
|
"github.com/opentracing/opentracing-go/log"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/httplib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterChainBuilder struct {
|
||||||
|
// CustomSpanFunc users are able to custom their span
|
||||||
|
CustomSpanFunc func(span opentracing.Span, ctx context.Context,
|
||||||
|
req *httplib.BeegoHTTPRequest, resp *http.Response, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filter {
|
||||||
|
|
||||||
|
return func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
|
||||||
|
|
||||||
|
method := req.GetRequest().Method
|
||||||
|
host := req.GetRequest().URL.Host
|
||||||
|
path := req.GetRequest().URL.Path
|
||||||
|
|
||||||
|
proto := req.GetRequest().Proto
|
||||||
|
|
||||||
|
scheme := req.GetRequest().URL.Scheme
|
||||||
|
|
||||||
|
operationName := host + path + "#" + method
|
||||||
|
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
inject := opentracingKit.ContextToHTTP(opentracing.GlobalTracer(), logKit.NewNopLogger())
|
||||||
|
inject(spanCtx, req.GetRequest())
|
||||||
|
resp, err := next(spanCtx, req)
|
||||||
|
|
||||||
|
if resp != nil {
|
||||||
|
span.SetTag("status", strconv.Itoa(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
span.SetTag("method", method)
|
||||||
|
span.SetTag("host", host)
|
||||||
|
span.SetTag("path", path)
|
||||||
|
span.SetTag("proto", proto)
|
||||||
|
span.SetTag("scheme", scheme)
|
||||||
|
|
||||||
|
span.LogFields(log.String("url", req.GetRequest().URL.String()))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
span.LogFields(log.String("error", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if builder.CustomSpanFunc != nil {
|
||||||
|
builder.CustomSpanFunc(span, ctx, req, resp, err)
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
42
pkg/httplib/filter/opentracing/filter_test.go
Normal file
42
pkg/httplib/filter/opentracing/filter_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2020 beego
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package opentracing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/pkg/httplib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterChainBuilder_FilterChain(t *testing.T) {
|
||||||
|
next := func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: 404,
|
||||||
|
}, errors.New("hello")
|
||||||
|
}
|
||||||
|
builder := &FilterChainBuilder{}
|
||||||
|
filter := builder.FilterChain(next)
|
||||||
|
req := httplib.Get("https://github.com/notifications?query=repo%3Aastaxie%2Fbeego")
|
||||||
|
resp, err := filter(context.Background(), req)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
}
|
@ -15,24 +15,39 @@
|
|||||||
package opentracing
|
package opentracing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
logKit "github.com/go-kit/kit/log"
|
||||||
|
opentracingKit "github.com/go-kit/kit/tracing/opentracing"
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
|
|
||||||
beego "github.com/astaxie/beego/pkg"
|
beego "github.com/astaxie/beego/pkg"
|
||||||
"github.com/astaxie/beego/pkg/context"
|
beegoCtx "github.com/astaxie/beego/pkg/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
// FilterChainBuilder provides an extension point that we can support more configurations if necessary
|
||||||
type FilterChainBuilder struct {
|
type FilterChainBuilder struct {
|
||||||
// CustomSpanFunc makes users to custom the span.
|
// CustomSpanFunc makes users to custom the span.
|
||||||
CustomSpanFunc func(span opentracing.Span, ctx *context.Context)
|
CustomSpanFunc func(span opentracing.Span, ctx *beegoCtx.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc {
|
func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc {
|
||||||
return func(ctx *context.Context) {
|
return func(ctx *beegoCtx.Context) {
|
||||||
|
var (
|
||||||
|
spanCtx context.Context
|
||||||
|
span opentracing.Span
|
||||||
|
)
|
||||||
operationName := builder.operationName(ctx)
|
operationName := builder.operationName(ctx)
|
||||||
|
|
||||||
span, spanCtx := opentracing.StartSpanFromContext(ctx.Request.Context(), operationName)
|
if preSpan := opentracing.SpanFromContext(ctx.Request.Context()); preSpan == nil {
|
||||||
|
inject := opentracingKit.HTTPToContext(opentracing.GlobalTracer(), operationName, logKit.NewNopLogger())
|
||||||
|
spanCtx = inject(ctx.Request.Context(), ctx.Request)
|
||||||
|
span = opentracing.SpanFromContext(spanCtx)
|
||||||
|
} else {
|
||||||
|
span, spanCtx = opentracing.StartSpanFromContext(ctx.Request.Context(), operationName)
|
||||||
|
}
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
newReq := ctx.Request.Clone(spanCtx)
|
newReq := ctx.Request.Clone(spanCtx)
|
||||||
@ -49,7 +64,7 @@ func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.Filt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (builder *FilterChainBuilder) operationName(ctx *context.Context) string {
|
func (builder *FilterChainBuilder) operationName(ctx *beegoCtx.Context) string {
|
||||||
operationName := ctx.Input.URL()
|
operationName := ctx.Input.URL()
|
||||||
// it means that there is not any span, so we create a span as the root span.
|
// it means that there is not any span, so we create a span as the root span.
|
||||||
// TODO, if we support multiple servers, this need to be changed
|
// TODO, if we support multiple servers, this need to be changed
|
||||||
|
Loading…
Reference in New Issue
Block a user