官方网站https://opentracing.io/
官方Github:https://github.com/opentracing
Opentracing是分布式链路追踪的一种规范标准,是CNCF(云原生计算基金会)下的项目之一。和一般的规范标准不同,Opentracing不是传输协议,消息格式层面上的规范标准,而是一种语言层面上的API标准。以Go语言为例,只要某链路追踪系统实现了Opentracing规定的接口(interface),符合Opentracing定义的表现行为,那么就可以说该应用符合Opentracing标准。开发者只需修改少量的配置代码,就可以在符合Opentracing标准的链路追踪系统之间自由切换。
Span
“span”是分布式追踪系统的主要组成部分,表示一个工作单元。
分布式系统的每个组件都提供一个span——一个指定名称、一定时间范围的操作,以此表示工作流中一部分。
span可以(通常是这样)包含对其他span的“引用”,这允许将多个span组装成一个完整的追踪—当请求在分布式系统中移动时,对其生命周期进行可视化处理。
根据OpenTracing规范,每个span封装了以下状态:
一个操作名称
开始时间戳和结束时间戳
一组键值形式标记(Tags)
一组键值形式日志(Logs)
SpanContext
Tags
标记是span中用户自定义的键值,以便查询、筛选和理解追踪数据。
Span标记应该应用于整个Span。在semantic_conventions.md上列出了常见场景的常规span标记。示例包括标记键,如用于标识数据库主机的db.instance、用于表示http响应代码的http.status_code,或者如果由Span表示的操作失败,则可以将错误设置为True。
Logs
日志是用于获取特定范围的日志信息以及应用程序本身的其他调试或信息输出的键-值对。日志对于记录span内的特定时刻或事件可能很有用(与应用于整个span的标记不同)。
SpanContext
SpanContext跨进程/服务传递数据,主要由两部分组成:
•一个依赖于实现的状态,用于引用跟踪中的不同跨度,例如spanID和traceID
• Baggage 跨进程/服务边界的键值对。在整个跟踪过程中提供的一些可访问的数据可能会很有用。
Example Span
t=0 operation name: db_query t=x
+-----------------------------------------------------+
| · · · · · · · · · · Span · · · · · · · · · · |
+-----------------------------------------------------+
Tags:
- db.instance:"customers"
- db.statement:"SELECT * FROM mytable WHERE foo='bar'"
- peer.address:"mysql://127.0.0.1:3306/customers"
Logs:
- message:"Can't connect to mysql server on '127.0.0.1'(10061)"
SpanContext:
- trace_id:"abc123"
- span_id:"xyz789"
- Baggage Items:
- special_id:"vsid1738"
Hello World
通过docker启动追踪服务的jaeger的all-in-one
$ docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
package main
import (
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
"github.com/uber/jaeger-client-go/config"
"log"
"time"
)
func main() {
cfg := config.Configuration{
Sampler: &config.SamplerConfig{
Type: "const",
Param: 1,
},
Reporter: &config.ReporterConfig{
BufferFlushInterval: 1 * time.Second,
LogSpans: true,
},
ServiceName: "hello-world",
}
tracer, closer, err := cfg.NewTracer(config.Logger(jaeger.StdLogger))
if err != nil {
log.Fatal(err)
}
opentracing.SetGlobalTracer(tracer)
defer closer.Close()
parent := opentracing.GlobalTracer().StartSpan("hello")
defer parent.Finish()
child := opentracing.GlobalTracer().StartSpan(
"world", opentracing.ChildOf(parent.Context()))
defer child.Finish()
}