关于opentracing的简单介绍
什么是opentracing?
OpenTracing的数据模型
opentracing中的跟踪链由span隐性的定义。可别的,跟踪链可以认为是span的有向无环图(DAG),spans之间的边称为References。
以下是一个跨度的例子图:
解析为时间轴可视化的图:
每个span封装以下的状态:
(1)操作名称
(2)开始时间戳
(3)完成时间戳
(4)一组零个或多个key:value跨度标签。 键必须是字符串。 值可以是字符串,布尔型或数字类型。
(5)一组零个或多个跨度日志,每个跨度日志本身就是与时间戳配对的key:value映射。 键必须是字符串,尽管值可以是任何类型。 并非所有OpenTracing实现都必须支持每种值类型。
(6)SpanContext(请参见下文)
(7)零个或多个因果相关的Span的引用(通过那些相关Span的SpanContext)
每个SpanContext封装以下状态
(1)引用跨过程span的不同process所需的任何OpenTracing实现依赖状态(例如,跟踪和跨度ID)
(2)Baggage Items,仅是k:v键值对,跨越process的边界
span之间的References
Span可以引用因果相关的零个或多个其他SpanContext。
Span可以引用因果相关的零个或多个其他SpanContext。 OpenTracing当前定义了两种类型的引用:ChildOf和FollowsFrom。 两种参考类型都专门为子Span和父Span之间的直接因果关系建模。 将来,OpenTracing可能还会支持具有非因果关系的Span的引用类型(例如,批处理在一起的Span,卡在同一队列中的Span等)。
ChildOf:
span可以是父亲span的子,在ChildOf的reference中父的span某些情况下依赖于子的span,以下所有内容将构成ChildOf关系:
(1)代表RPC的服务器端的Span可以是代表该RPC客户端的Span的ChildOf
(2)表示SQL插入的Span可以是代表ORM保存方法的Span的ChildOf
(3)许多同时执行(可能是分布式的)工作的Span可能全部是单个父Span的ChildOf,它合并了在截止期限内返回的所有子代的结果
这些对于作为父级ChildOf的子级来说都是有效的时序图。
FollowsFrom:
一些父Span完全不依赖于其子Span的结果。 在这些情况下,我们仅说因果关系上子Span从父Span跟随。 有许多不同的FollowsFrom参考子类别,在将来的OpenTracing版本中,它们可能会更正式地加以区分。
这些对于“FollowsFrom”的孩子来说都是有效的时序图。
The OpenTracing API
OpenTracing规范中包含三种关键且相互关联的类型:Tracer,Span和SpanContext。
粗略地说,每种行为在典型的编程语言中都成为一种“方法”,尽管由于类型重载等原因,它实际上可能是一组相关的同级方法。
--------------------------------------------------------------Tracer--------------------------------------------------
Tracer接口创造span并且了解如何将span跨process序列化和反序列化他们。Tracer接口具有以下功能。
1.开始一个新的span:
必要参数:
操作名称,例子:get_account
可选参数:
1.零个或多个对相关SpanContext的引用,如果可能的话,包括ChildOf和FollowsFrom引用类型的简写。
2.可选的显式开始时间戳记; 如果省略,则默认使用当前的walltime
3.零个或多个标签
返回已经启动(但尚未完成)的Span实例
2.将SpanContext注入载体
必要参数:
1.SpanContext实例
2.格式描述符(通常但不一定是字符串常量),它告诉Tracer实现如何在载波参数中对SpanContext进行编码
3.载体,其类型由格式决定。 Tracer实现将根据格式在此载体对象中对SpanContext进行编码。
3.从运营商中提取SpanContext
必要参数:
1.格式描述符(通常但不一定是字符串常量),它告诉Tracer实现如何从载波参数中解码SpanContext
2.载体,其类型由格式决定。 Tracer实现将根据格式从该载体对象解码SpanContext。
当通过Tracer启动新的Span时,返回适合用作参考的SpanContext实例。
注意:注射和提取所需的格式
注入和提取均依赖于可扩展的格式参数,该参数指示关联的“载体”的类型以及如何在该载体中编码SpanContext。 所有Tracer实现都必须支持以下所有格式。
1.文本映射(Text Map):任意字符串到字符串的映射,其中键和值的字符集不受限制
2.HTTP标头(Http Headers):具有适用于HTTP标头(例如RFC 7230)的键和值的字符串到字符串的映射。 在实践中,由于HTTP头的处理方式存在“多样性”,因此强烈建议Tracer实现使用有限的HTTP头密钥空间并保守地转义值。
3.二进制(二进制):表示SpanContext的(单个)任意二进制Blob
--------------------------------------------------------------Span--------------------------------------------------
可以做的事情:
1.检索跨度SpanContext
2.覆盖操作名称
3.完成跨度
4.设置跨度标签
5.记录结构化数据
6.Set a baggage item
7.Get a baggage item
----------------------------------------------------------SpanContext----------------------------------------------
SpanContext不仅仅是通用OpenTracing层上的有用功能,而是更多的“概念”。 也就是说,这对于OpenTracing实现至关重要,并且确实提供了自己的瘦API。 大多数OpenTracing用户在启动新的Span或向某些传输协议注入/从某些传输协议提取跟踪时,仅通过引用与SpanContext进行交互。
在OpenTracing中,我们强制SpanContext实例是不可变的,以避免围绕Span精加工和引用的复杂生命周期问题。
----------------------------------------------------------NoopTracer----------------------------------------------
所有OpenTracing语言API也必须提供某种NoopTracer实现,该实现可用于标记控制OpenTracing或注入对测试无害的东西(等等)。 在某些情况下(例如Java),NoopTracer可能位于其自己的打包工件中。
opentracing-go使用实例
初始化tracer
func TraceInit(serviceName string, samplerType string, samplerParam float64) (opentracing.Tracer, io.Closer) {
cfg := &config.Configuration{
ServiceName: serviceName,
Sampler: &config.SamplerConfig{
Type: samplerType,
Param: samplerParam,
},
Reporter: &config.ReporterConfig{
LocalAgentHostPort: "127.0.0.1:6831",
LogSpans: true,
},
}
tracer, closer, err := cfg.NewTracer(config.Logger(jaeger.StdLogger))
if err != nil {
panic(fmt.Sprintf("Init failed: %v\n", err)