Beego/pkg/orm/filter/opentracing/filter.go

72 lines
2.4 KiB
Go
Raw Normal View History

2020-08-10 15:04:57 +00:00
// Copyright 2020 beego
2020-08-09 12:05:10 +00:00
//
// 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"
2020-08-10 15:04:57 +00:00
"strings"
2020-08-09 12:05:10 +00:00
"github.com/opentracing/opentracing-go"
"github.com/astaxie/beego/pkg/orm"
)
// FilterChainBuilder provides an extension point
// this Filter's behavior looks a little bit strange
// for example:
// if we want to trace QuerySetter
// actually we trace invoking "QueryTable" and "QueryTableWithCtx"
2020-08-10 15:04:57 +00:00
// the method Begin*, Commit and Rollback are ignored.
// When use using those methods, it means that they want to manager their transaction manually, so we won't handle them.
2020-08-09 12:05:10 +00:00
type FilterChainBuilder struct {
// CustomSpanFunc users are able to custom their span
CustomSpanFunc func(span opentracing.Span, ctx context.Context, inv *orm.Invocation)
}
func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter {
2020-08-18 14:31:06 +00:00
return func(ctx context.Context, inv *orm.Invocation) []interface{} {
2020-08-09 12:05:10 +00:00
operationName := builder.operationName(ctx, inv)
2020-08-10 15:04:57 +00:00
if strings.HasPrefix(inv.Method, "Begin") || inv.Method == "Commit" || inv.Method == "Rollback" {
2020-08-18 14:31:06 +00:00
return next(ctx, inv)
2020-08-10 15:04:57 +00:00
}
2020-08-09 12:05:10 +00:00
span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName)
defer span.Finish()
2020-08-18 14:31:06 +00:00
res := next(spanCtx, inv)
2020-08-10 15:04:57 +00:00
builder.buildSpan(span, spanCtx, inv)
2020-08-18 14:31:06 +00:00
return res
2020-08-10 15:04:57 +00:00
}
}
2020-08-09 12:05:10 +00:00
2020-08-10 15:04:57 +00:00
func (builder *FilterChainBuilder) buildSpan(span opentracing.Span, ctx context.Context, inv *orm.Invocation) {
span.SetTag("orm.method", inv.Method)
span.SetTag("orm.table", inv.GetTableName())
span.SetTag("orm.insideTx", inv.InsideTx)
span.SetTag("orm.txName", ctx.Value(orm.TxNameKey))
span.SetTag("span.kind", "client")
span.SetTag("component", "beego")
2020-08-09 12:05:10 +00:00
2020-08-10 15:04:57 +00:00
if builder.CustomSpanFunc != nil {
builder.CustomSpanFunc(span, ctx, inv)
2020-08-09 12:05:10 +00:00
}
}
func (builder *FilterChainBuilder) operationName(ctx context.Context, inv *orm.Invocation) string {
if n, ok := ctx.Value(orm.TxNameKey).(string); ok {
2020-08-10 15:04:57 +00:00
return inv.Method + "#tx(" + n + ")"
2020-08-09 12:05:10 +00:00
}
return inv.Method + "#" + inv.GetTableName()
}