trace

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jul 22, 2022 License: MIT Imports: 8 Imported by: 0

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.

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

Jump to

Keyboard shortcuts

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