feat: add trace in redis & mon & sql (#1799)

* feat: add sub spanId with redis

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* add tests

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* fix a bug

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* feat: add sub spanId in sql

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* feat: add sub spanId in mon

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* chore: optimize code

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* feat: add breaker in warpSession

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* chore: optimize code

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* test: add tests

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* chore: reformat code

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* fix: fix typo

Signed-off-by: chenquan <chenquan.dev@gmail.com>

* fix a bug

Signed-off-by: chenquan <chenquan.dev@gmail.com>
This commit is contained in:
chen quan
2022-04-21 20:04:44 -05:00
committed by GitHub
parent 94ddb3380e
commit 162e9cef86
7 changed files with 268 additions and 15 deletions

View File

@@ -9,23 +9,31 @@ import (
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mapping"
"github.com/zeromicro/go-zero/core/timex"
"github.com/zeromicro/go-zero/core/trace"
"go.opentelemetry.io/otel"
tracestd "go.opentelemetry.io/otel/trace"
)
var (
startTimeKey = contextKey("startTime")
durationHook = hook{}
spanKey = contextKey("span")
durationHook = hook{tracer: otel.GetTracerProvider().Tracer(trace.TraceName)}
)
type (
contextKey string
hook struct{}
hook struct {
tracer tracestd.Tracer
}
)
func (h hook) BeforeProcess(ctx context.Context, _ red.Cmder) (context.Context, error) {
return context.WithValue(ctx, startTimeKey, timex.Now()), nil
return h.spanStart(context.WithValue(ctx, startTimeKey, timex.Now())), nil
}
func (h hook) AfterProcess(ctx context.Context, cmd red.Cmder) error {
h.spanEnd(ctx)
val := ctx.Value(startTimeKey)
if val == nil {
return nil
@@ -45,10 +53,12 @@ func (h hook) AfterProcess(ctx context.Context, cmd red.Cmder) error {
}
func (h hook) BeforeProcessPipeline(ctx context.Context, _ []red.Cmder) (context.Context, error) {
return context.WithValue(ctx, startTimeKey, timex.Now()), nil
return h.spanStart(context.WithValue(ctx, startTimeKey, timex.Now())), nil
}
func (h hook) AfterProcessPipeline(ctx context.Context, cmds []red.Cmder) error {
h.spanEnd(ctx)
if len(cmds) == 0 {
return nil
}
@@ -81,3 +91,19 @@ func logDuration(ctx context.Context, cmd red.Cmder, duration time.Duration) {
}
logx.WithContext(ctx).WithDuration(duration).Slowf("[REDIS] slowcall on executing: %s", buf.String())
}
func (h hook) spanStart(ctx context.Context) context.Context {
ctx, span := h.tracer.Start(ctx, "redis")
return context.WithValue(ctx, spanKey, span)
}
func (h hook) spanEnd(ctx context.Context) {
spanVal := ctx.Value(spanKey)
if spanVal == nil {
return
}
if span, ok := spanVal.(tracestd.Span); ok {
span.End()
}
}

View File

@@ -9,9 +9,17 @@ import (
red "github.com/go-redis/redis/v8"
"github.com/stretchr/testify/assert"
ztrace "github.com/zeromicro/go-zero/core/trace"
)
func TestHookProcessCase1(t *testing.T) {
ztrace.StartAgent(ztrace.Config{
Name: "go-zero-test",
Endpoint: "http://localhost:14268/api/traces",
Batcher: "jaeger",
Sampler: 1.0,
})
writer := log.Writer()
var buf strings.Builder
log.SetOutput(&buf)
@@ -24,9 +32,17 @@ func TestHookProcessCase1(t *testing.T) {
assert.Nil(t, durationHook.AfterProcess(ctx, red.NewCmd(context.Background())))
assert.False(t, strings.Contains(buf.String(), "slow"))
assert.Equal(t, "redis", ctx.Value(spanKey).(interface{ Name() string }).Name())
}
func TestHookProcessCase2(t *testing.T) {
ztrace.StartAgent(ztrace.Config{
Name: "go-zero-test",
Endpoint: "http://localhost:14268/api/traces",
Batcher: "jaeger",
Sampler: 1.0,
})
writer := log.Writer()
var buf strings.Builder
log.SetOutput(&buf)
@@ -36,11 +52,14 @@ func TestHookProcessCase2(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "redis", ctx.Value(spanKey).(interface{ Name() string }).Name())
time.Sleep(slowThreshold.Load() + time.Millisecond)
assert.Nil(t, durationHook.AfterProcess(ctx, red.NewCmd(context.Background(), "foo", "bar")))
assert.True(t, strings.Contains(buf.String(), "slow"))
assert.True(t, strings.Contains(buf.String(), "trace"))
assert.True(t, strings.Contains(buf.String(), "span"))
}
func TestHookProcessCase3(t *testing.T) {
@@ -74,6 +93,7 @@ func TestHookProcessPipelineCase1(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "redis", ctx.Value(spanKey).(interface{ Name() string }).Name())
assert.Nil(t, durationHook.AfterProcessPipeline(ctx, []red.Cmder{
red.NewCmd(context.Background()),
@@ -82,6 +102,13 @@ func TestHookProcessPipelineCase1(t *testing.T) {
}
func TestHookProcessPipelineCase2(t *testing.T) {
ztrace.StartAgent(ztrace.Config{
Name: "go-zero-test",
Endpoint: "http://localhost:14268/api/traces",
Batcher: "jaeger",
Sampler: 1.0,
})
writer := log.Writer()
var buf strings.Builder
log.SetOutput(&buf)
@@ -91,6 +118,7 @@ func TestHookProcessPipelineCase2(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "redis", ctx.Value(spanKey).(interface{ Name() string }).Name())
time.Sleep(slowThreshold.Load() + time.Millisecond)
@@ -98,6 +126,8 @@ func TestHookProcessPipelineCase2(t *testing.T) {
red.NewCmd(context.Background(), "foo", "bar"),
}))
assert.True(t, strings.Contains(buf.String(), "slow"))
assert.True(t, strings.Contains(buf.String(), "trace"))
assert.True(t, strings.Contains(buf.String(), "span"))
}
func TestHookProcessPipelineCase3(t *testing.T) {