trace

package
v1.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 19, 2023 License: MIT Imports: 11 Imported by: 3

README

分布式链路追踪

主要是使用 opentracing 协议,基于 jaeger client 来使用

本地快速部署

docker run -d -p 6831:6831/udp -p 16686:16686 jaegertracing/all-in-one:latest

主要使用步骤

1、初始化 Jaeger 并将 tracer设为全局,方便后续调用
// initJaeger 将jaeger tracer设置为全局tracer
func initJaeger(service string) (opentracing.Tracer, io.Closer) {
	cfg := jaegercfg.Configuration{
		// 将采样频率设置为1,每一个span都记录,方便查看测试结果
		Sampler: &jaegercfg.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1,
		},
		Reporter: &jaegercfg.ReporterConfig{
			LogSpans: true,
			// 将span发往jaeger-collector的服务地址
			CollectorEndpoint: "http://localhost:14268/api/traces",
		},
	}

    tracer, closer, err := cfg.NewTracer(
		config.Logger(jaeger.StdLogger),
		config.ZipkinSharedRPCSpan(true),
	)
	if err != nil {
		panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))
	}
	return tracer, closer
}
2、在 main函数或者中间件中获取全局 tracer,创建 root span 并执行我们第一个服务(MyFirstSpan)
func main() {
	closer := initJaeger("MyProcess")
	defer closer.Close()
	// 获取jaeger tracer
	t := opentracing.GlobalTracer()
	// 创建root span
	sp := t.StartSpan("MyServer")
	// main执行完结束这个span
	defer sp.Finish()
	// 将span传递给MyFirstSpan
	ctx := opentracing.ContextWithSpan(context.Background(), sp)
	MyFirstSpan(ctx)
}
3、在 MyFirstSpan 中调用另一个服务(MySecondSpan)
func MyFirstSpan(ctx context.Context) {
	// 开始一个span, 设置span的operation_name=MyFirstSpan
	span, ctx := opentracing.StartSpanFromContext(ctx, "MyFirstSpan")
	defer span.Finish()
	// 将context传递给MySecondSpan
	MySecondSpan(ctx)
	// 假设执行了 http请求
	span.SetTag("http_method", "GET")
	span.SetTag("http_code", "200")
	// 模拟执行耗时
	time.Sleep(1 * time.Second)
}
4、MySecondSpan:
func MySecondSpan(ctx context.Context) {
	// 开始一个span,设置span的operation_name=MySecondSpan
	span, ctx := opentracing.StartSpanFromContext(ctx, "MySecondSpan")
	defer span.Finish()
	// 模拟执行耗时
	time.Sleep(2 * time.Second)
	// 假设MySecondSpan发生了某些错误
	err := errors.New("something wrong")
	// 记录 log
	span.LogFields(
		log.String("event", "error"),
		log.String("message", err.Error()),
		log.Int64("error time ", time.Now().Unix()),
	)
	span.SetTag("error", true)
}
5、执行完后在 127.0.0.1:16686 查看本次 tracer
![tracer demo](https://static001.geekbang.org/infoq/14/14e851a82437efd4b812375558f7178b.png)

使用demo

go-redis
    span := opentracing.SpanFromContext(c.Request.Context())
	if span == nil {
		api.SendResponse(c, errno.ErrUserNotFound, "span is nil")
		return
	}
	err := tracing.Inject(span, c.Request)
	if err != nil {
		api.SendResponse(c, errno.ErrUserNotFound, err.Error())
		return
	}

	_ = apmgoredis.Wrap(redis.RedisClient).WithContext(c.Request.Context()).Set("test", 1, 100000).Err()
	_ = apmgoredis.Wrap(redis.RedisClient).WithContext(c.Request.Context()).Get("test").Err()

FAQ

1、如何生成span

var sp opentracing.Span
carrier := opentracing.HTTPHeadersCarrier(c.Request.Header)
ctx, _ := tracer.Extract(opentracing.HTTPHeaders, carrier)
sp = tracer.StartSpan(c.Request.URL.Path, ext.RPCServerOption(ctx))
defer sp.Finish()

2、如何注册span到下游

// 生成span
span := opentracing.SpanFromContext(c.Request.Context())
if span == nil {
    api.SendResponse(c, errno.ErrUserNotFound, "span is nil")
    return
}
// 注入
err := tracing.Inject(span, c.Request)
if err != nil {
    api.SendResponse(c, errno.ErrUserNotFound, err.Error())
    return
}

3、如何记录tag

// record HTTP method
ext.HTTPMethod.Set(sp, c.Request.Method)
// record HTTP url
ext.HTTPUrl.Set(sp, c.Request.URL.String())
...

4、如果记录日志到span

参考:github.com/opentracing/opentracing-go/span.go

span.LogFields(
       log.String("event", "soft error"),
       log.String("type", "cache timeout"),
      log.Int("waited.millis", 1500))

Reference

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func InitTracerProvider

func InitTracerProvider(serviceName, endpoint string, options ...Option) (*tracesdk.TracerProvider, error)

InitTracerProvider returns an OpenTelemetry TracerProvider configured to use the Jaeger exporter that will send spans to the provided url. The returned TracerProvider will also use a Resource configured with all the information about the application.

func SetSpanError added in v1.7.0

func SetSpanError(ctx context.Context, err error)

SetSpanError record error to tracing system

Types

type Config

type Config struct {
	ServiceName        string // The name of this service
	LocalAgentHostPort string
	CollectorEndpoint  string
}

Config jaeger config

type Option

type Option func(c *Options)

Option is a function that sets some option on the client.

type Options

type Options struct {
	SamplingRatio float64
}

Options control behavior of the client.

Directories

Path Synopsis
plugins

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL