golang工程——opentelemetry简介、架构、概念、追踪原理-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

opentelemetry

简介

OpenTelemetry简称OTel是一个与供应商无关的开源可观测性框架用于检测、生成、收集和导出
遥测数据如轨迹、度量、日志。OTel的目标是提供一套标准化的供应商无关SDK、API和工具用于接
收、转换数据并将数据发送到可观测系统监控系统后端开源或商业

OpenTelemetry 是以解决观测性为初衷的项目观测性包含链路监控日志。主要解决的问题是观测性领域模型的统一观测性数据收集的统一观测性数据输出的统一。这些统一性主要体现在 API 规范SDK 实现规范接口规范等。OpenTelemetry 不会负责观测数据的存储需要存储这些观测数据的 backend。OpenTelemetry 定义来数据输出的规范由各大厂商自行完成数据的持久化。

OpenTelemetry 也提供了很多开发语言的 SDK开发者需要使用自己熟悉的语言的 SDK 完成应用程序的观测性能力。目前不同的开发语言的支持程度不一样。

主要组成

Specification这个组件是语言无关的主要是定义了规范如 API 的规范SDK 的开发规范数据规范。使用不同开发源于开发具体 SDK 的时候会按照标准开发保证了规范性。

Proto这个组件是语言无关的主要是定义了 OpenTelemetry 的 OTLP 协议定义OTLP 协议是 OpenTelemetry 中数据传输的重要部分。如 SDK 到CollectorCollector 到 CollectorCollector 到 Backend这些过程的数据传输都是遵循了 OTLP 协议。

Instrumentation Libraries是根据 SDK 的开发规范开发的支持不同语言的 SDK如 javagolangc 等语言的 SDK。客户在构建观测性的时候可以直接使用社区提供的已经开发好的 SDK 来构建观测能力。社区也在此基础上提供了一些工具这些工具已经集成了常见软件的对接。

Collector负责收集观测数据处理观测数据导出观测数据。

文档

go源码

demo

语义

otel-collector配置文档

OpenTelemetry收集器组件库

架构

在这里插入图片描述

Application 一般的应用程序同时使用了 OpenTelemetry 的 Library (实现了 API 的 SDK)。

OTel Libraty也称为 SDK负责在客户端程序里采集观测数据包括 metricstraceslogs对观测数据进行处理之后观测数据按照 exporter 的不同方式通过 OTLP 方式发送到 Collector 或者直接发送到 Backend 中。

OTel Collector负责根据 OpenTelemetry 的协议收集数据的组件以及将观测数据导出到外部系统。这里的协议指的是 OTLP (OpenTelemetry Protocol)。不同的提供商要想能让观测数据持久化到自己的产品里需要按照 OpenTelemetry 的标准 exporter 的协议接受数据和存储数据。同时社区已经提供了常见开源软件的输出能力如 PrometheusJaegerKafkazipkin 等。图中看到的不同的颜色的 CollectorAgent Collector 是单机的部署方式每一个机器或者容器使用一个避免大规模的 Application 直接连接 Service CollectorService Collector 是可以多副本部署的可以根据负载进行扩容。

Backend 负责持久化观测数据Collector 本身不会去负责持久化观测数据需要外部系统提供在 Collector 的 exporter 部分需要将 OTLP 的数据格式转换成 Backend 能识别的数据格式。目前社区的已经集成的厂商非常多除了上述的开源的常见的厂商包括 AWS阿里AzureDatadogDynatraceGoogleSplunkVMWare 等都实现了 Collector 的 exporter 能力。

观测性方案

观测性常见方案主要总结

日志方案filebeats->elasticsearch->kibanafilebeats->kafka->logstash->elasticsearch->kibana; fluentd->elasticsearch->kibanafluentd->kafka->fluentd->elasticsearch->kibana 。

监控方案比较统一的都在使用 prometheusprometheus-operatorthanosgrafana。

链路方案主要方案有开源的 skywalkingjaegerzipkin还有商业的方案如 dynatrace 等。

opentelemetry解决方案就是为了统一Trace, metrics loggingd 标准

数据流

在这里插入图片描述

概念

Traces

TracerProvider

是Tracer的工厂。在大多数应用程序中Tracer提供程序初始化一次其生命周期与应用程序的生命周
期相匹配。Tracer Provider初始化还包括Resource和Exporter初始化。这通常是使用OpenTelemetry进
行跟踪的第一步

Tracer

Tracer跟踪程序用于创建span其中包含有关给定操作例如服务中的请求所发生情况的更多信
息。跟踪程序是从跟踪程序提供程序创建的

Trace Exporters

跟踪导出器将跟踪发送给消费者。此使用者可以是调试和开发时的标准输出、OpenTelemetry收集器或
您选择的任何开源或供应商后端

Context Propagation (上下文传播)
  • 上下文传播是实现分布式跟踪的核心概念。使用上下文传播跨域可以相互关联并组装到跟踪中而不
    管跨域是在哪里生成的
  • 上下文Context是一个对象它包含发送和接收服务的信息以便将一个跨度与另一个跨度相关联
    并将其与整个跟踪相关联
  • 传播Propagation是在服务和流程之间移动上下文的机制。它序列化或反序列化上下文对象并提供
    要从一个服务传播的相关跟踪信息
spans(重要)

跨度表示一个工作或操作单元。跨度是痕迹的组成部分。在OpenTelemetry中它们包括以下信息

  1. Name名称
  2. Parent span ID (empty for root spans)父跨度ID为空则表示根跨度
  3. Start and End Timestamps 开始与结束的时间戳
  4. Span Context 跨度上下文
  5. Attributes属性
  6. Span Events 事件
  7. Span Links 链接
  8. Span Status状态
Span Context

span context 是每个跨度上的一个不可变对象包含以下内容
Trace ID表示跨度所属的跟踪
Span ID 跨度的跨度ID
Trace Flags一种包含跟踪信息的二进制编码
Trace State可以携带特定于供应商的跟踪信息的键值对列表

span context 是与分布式上下文和Baggage一起序列化和传播的跨度的一部分。
由于“span context”包含跟踪ID因此在创建“span link”时会使用它

Attributes

属性是包含元数据的键值对您可以使用这些元数据对跨度进行注释以携带有关其正在跟踪的操作的
信息。
例如如果跨度跟踪在电子商务系统中将商品添加到用户购物车的操作则可以捕获用户的ID、要添加到购物车的商品的ID和购物车ID。
属性具有每个语言SDK实现的以下规则
键必须是非空字符串值
值必须是非空字符串、布尔值、浮点值、整数或这些值的数组
此外还有语义属性这是常见操作中通常存在的元数据的已知命名约定。尽可能使用语义属性命名有
助于跨系统标准化常见类型的元数据。语义约定详见文档https://github.com/opentelemetry/semantic-conventions

Span Events

跨度事件可以被认为是跨度上的结构化日志消息或注释通常用于表示跨度持续时间内的一个有意义的奇异时间点。
例如考虑web浏览器中的两种情况

  • 跟踪页面加载
  • 表示页面何时变为交互式
  • 跨度最适合用于第一种情况因为它是一个有开始和结束的操作。
  • 跨度事件最好用于跟踪第二个场景因为它代表了一个有意义的奇异时间点
Span Links

链接的存在使您可以将一个跨度与一个或多个跨度相关联从而暗示因果关系。例如假设我们有一个分布式系统其中一些操作由跟踪跟踪。作为对其中一些操作的响应额外的操作排队等待执行但其执行是异步的。我们也可以通过跟踪来跟踪此后续操作。我们希望将后续操作的跟踪与第一个跟踪相关联但我们无法预测后续操作何时开始。我们需要将这两个轨迹关联起来所以我们将使用跨度链接。
您可以将第一个跟踪中的最后一个跨度链接到第二个跟踪的第一个跨度。现在它们是因果关联的。

链接是可选的但也是将跟踪跨度相互关联的好方法

Span Status

span的状态可选值UnsetOkError。当应用程序代码中存在已知错误例如异常时可将状态可以设置为“Error”

Spand Kind(span 类型)

创建跨度时它是客户端Client、服务器Server、内部Internal、生产者Producer或消费者Consumer之一。这种span类型为跟踪后端提供了一个关于应该如何组装跟踪的提示。根据OpenTelemetry规范服务器跨度的父跨度通常是远程客户端跨度而客户端跨度的子跨度通常是服务器跨度。类似地消费者跨度的父代始终是生产者生产者跨度的子代始终是消费者。如果未提供则假定跨度类型为内部

  • SERVER表示跨度涵盖同步RPC或其他远程请求的服务器端处理。此跨度通常是预期等待响应的远程CLIENT跨度的子跨度。
  • CLIENT表示跨度描述对某个远程服务的请求。此跨度通常是远程SERVER跨度的父跨度在收到响应之前不会结束。
  • PRODUCER表示跨度描述异步请求的发起方。此父跨度通常会在相应的子“消费者”跨度之前结束甚至可能在子跨度开始之前结束。在使用批处理的消息传递场景中跟踪单个消息需要为每个要创建的消息创建一个新的生产者跨度。
  • CONSUMER表示跨度描述异步生产者请求的子级
  • INTERNAL默认值。指示跨度表示应用程序中的内部操作而不是具有远程父级或子级的操作。

metrics

度量是在运行时捕获的关于服务的度量。从逻辑上讲捕获其中一个测量的时刻被称为度量事件它不仅包括测量本身还包括捕获它的时间和相关的元数据。
应用程序和请求度量是可用性和性能的重要指标。自定义指标可以深入了解可用性指标如何影响用户体验或业务。收集的数据可用于警告停机或触发调度决策以在高需求时自动扩大部署规模

Meter Provider

是 Meters的工厂。在大多数应用程序中Meter Provider初始化一次其生命周期与应用程序的生命周期相匹配。Meter Provider初始化还包括资源和导出程序初始化。这通常是使用OpenTelemetry进行测量的第一步

Meter

Meter创建度量仪表在运行时捕获有关服务的测量值。meter 是从Meter Provider 创建的

Metrics Exporter

Metric Exporter 向消费者发送度量数据。此使用者可以是调试和开发时的标准输出、OpenTelemetry收集器或您选择的任何开源或供应商后端

Metrics Instruments

在OpenTelemetry中测量由公制仪器捕获。这种公制仪器由名称、种类、可选单位和可选说明定义。这种工具的名称、单元和描述由开发人员选择或通过常见的语义约定如请求或过程度量进行定义。语义约定详见文档https://github.com/open-telemetry/semantic-conventions
仪器类型为以下六种之一类似promethues里的指标

Counter

一个随着时间积累的值——你可以把它想象成汽车上的里程表它只会上升

Asynchronous Counter

与Counter相同但每次导出都会收集一次。如果您不能访问连续增量而只能访问聚合值则可以使用

UpDownCounter

一种随着时间的推移而积累的值但也可能再次下降。例如队列长度会随着队列中工作项的数量而增加或减少

Asynchronous UpDownCounter

与UpDownCounter相同但每次导出都会收集一次。如果您不需要访问连续更改而只能访问聚合值例如当前队列大小则可以使用

(Asynchronous)Gauge

测量读取时的当前值。一个例子是车辆中的燃油表。仪表总是异步的

Histogram

直方图是客户端值的集合例如请求延迟。如果你有很多值并且不是对每个单独的值都感兴趣而是对这些值的统计数据感兴趣那么直方图可能是一个不错的选择

Aggregation

除了度量工具之外聚合的概念也是一个需要理解的重要概念。聚合是一种技术通过该技术将大量测量值组合成关于在时间窗口期间发生的度量事件的精确或估计统计数据。OTLP协议传输这样的聚合度量。OpenTelemetry API为每个仪器提供了一个默认聚合可以使用视图覆盖这些聚合。OpenTelemetry项目旨在提供可视化工具和遥测后端支持的默认聚合
与请求追踪不同metrics旨在提供汇总的统计信息。例如

  1. 报告每个协议类型的服务读取的字节总数。
  2. 报告读取的字节总数和每个请求的字节数。
  3. 报告系统调用的持续时间。
  4. 报告请求大小以确定趋势。
  5. 报告进程的CPU或内存使用情况。
  6. 报告帐户的平均余额值。
  7. 报告正在处理的当前活动请求
Views

视图为SDK用户提供了自定义SDK输出的度量的灵活性。他们可以自定义要处理或忽略的Metrics。他们可以自定义聚合以及要在度量上报告的属性

Baggage

  • Baggage提供了一种统一的方式来存储和传播轨迹和其他信号中的信息。在OpenTelemetry中Baggage是跨段之间传递的上下文信息。它是一个键值存储位于跟踪中的span上下文旁边使在该跟踪中创建的任何span都可以使用值。例如假设您希望在跟踪中的每个跨度上都有一个CustomerId属性该属性涉及多个服务但是

  • CustomerId仅在一个特定服务中可用。为了实现您的目标您可以使用OpenTelemetry Baggage在系统中传播此值。

  • OpenTelemetry使用上下文传播来传递Baggage每个不同的库实现都有传播程序可以解析并使Baggage可用而无需显式实现它Baggage不属于span属性的子集因此不会自动出现在子系统span的属性中需要明确的将信息从baggage中取出并附加到span的属性。

Resources

资源是一种特殊类型的属性适用于流程生成的所有跨度。这些应该用于表示关于非临时进程的底层元数据例如进程的主机名或其实例ID。资源应该在初始化时分配给跟踪程序提供程序并且创建时与属性非常相似

logs

无go版本

日志是一种带有时间戳的文本记录可以是结构化的推荐的也可以是非结构化的带有元数据。在所有遥测信号日志中具有最大的遗留问题。大多数编程语言都有内置的日志记录功能或众所周知的、广泛使用的日志记录库。尽管日志是一个独立的数据源但它们也可以连接到跨度。在OpenTelemetry中任何不属于分布式跟踪或度量的数据都是日志。例如事件是一种特定类型的日志。

日志通常包含详细的调试/诊断信息例如操作的输入、操作的结果以及该操作的任何支持元数据对于跟踪和度量OpenTelemetry采用了一种干净的设计方法指定了一个新的API并在多语言SDK中提供了此API的完整实现OpenTelemetry使用日志的方法不同。由于现有的日志记录解决方案在语言和操作生态系统中广泛存
在OpenTelemetry充当了这些日志、跟踪和度量信号以及其他OpenTelemetrys组件之间的“桥梁”。事实上由于这个原因日志的API被称为“Logs Bridge API”

Log Appender / Bridge

作为应用程序开发人员您不应该直接调用Logs Bridge API因为它是为日志库作者提供的用于构建日志附加程序/桥。相反您只需使用首选的日志记录库并将其配置为使用能够将日志发送到OpenTelemetry LogRecordExporter的日志附加器或日志桥

Logger Provider

记录器提供程序有时称为LoggerProvider是记录器的工厂。在大多数情况下Logger Provider只初始化一次其生命周期与应用程序的生命周期相匹配。Logger Provider初始化还包括Resource和Exporter初始化是Logs Bridge API的一部分仅当您是日志库的作者时才应使用

Logger

Logger创建日志记录。记录器是从日志提供程序创建的
是Logs Bridge API的一部分仅当您是日志库的作者时才应使用

Log Record Exporter

日志记录导出器将日志记录发送给使用者。此使用者可以是调试和开发时的标准输出、OpenTelemetry收集器或您选择的任何开源或供应商后端

Log Record

日志记录表示事件的记录。在OpenTelemetry中日志记录包含两种字段

  1. 具有特定类型和含义的命名顶级字段
  2. 任意值和类型的资源和属性字段
    日志记录顶部字段
Timestamp 事件发生的时间
ObservedTimestamp 观察到事件的时间
TraceId 请求跟踪ID
SpanId 请求跨度ID
TraceFlags W3C跟踪标志
SeverityText 严重性文本也称为日志级别
SeverityNumber 严重程度的数值
Body 日志记录的正文
Resource 描述日志的来源
InstrumentationScope 描述发出日志的作用域
Attributes 有关该事件的其他信息

详见文档https://opentelemetry.io/docs/specs/otel/logs/data-model/

Trace跟踪原理

  1. 开始一个span
  2. 当app想要记录一次trace需要在代码里调用对应start方法这个方法会返回一个span。后续span可以调用span的end接收这次的trace
  3. 开始初始化span保存span 的 TraceIDSpanID以及 span 的attributeseventslinks以及处理 span 限制的 spanLimits以及 span 的 startTimespan的parent spanspan 的 name 等span 需要的相关属性。
  4. 初始化处理 span 的所有类型的 processors根据定义的 processor 去处理 span目前只支持 simple 和 batch 两种simple 是不推荐在生产环境用因为是同步的 call而且是一条一条的生产上推荐使用 batch性能好。
  5. 根据配置的所有 span 的 processors使用每一个 processor 的 OnStart 的去处理 span这里的 OnStart 其实是空实现。不管是 simple 类型的还是 batch 类型的目前都是一个是个空的方法这个方法的定义的作用就是在开始处理 span 的时候做一些处理。最后返回一个初始化后的 span 给到客户 (注意要想让这个 span 真正的进入到整个 trace 里还要调用 span 对象的 End 方)。
  6. 由 tracer 返回开始的 span。
  7. 当 call span 的 End 方法时候就会对 span 做一下快照这里的快照只是将可读写的 span复制到只读的 ReadOnlySpan 对象通过 processor 的 OnEnd 方法放到 processor 的 queue 中可见放到 queue 中等待发送出去的 span 都是只读的 sp.sp.OnEnd(s.snapshot()))。
  8. 从 queue 获取 span 放到 batch 中当 batch 的数量满了或者到达了固定时间都会将已经处于 end 状态的 span 通过 exporter 发送出去。
  9. 从 queue 获取 span 放到 batch 中当 batch 的数量满了或者到达了固定时间都会将已经处于 end 状态的 span 通过 processor 的 exportSpans 方法发送出去。
  10. exportSpans 方法处理只会去拿 processor 的 batch 字段的数据去处理每次 exportSpans 时都是一次处理一个 batch 的数据。
  11. 使用一个 batch 里的数据进行转换成 collector 能接受的 trace 数据。
  12. 使用 exporter 的 clientupload trace 数据到 collector。
  13. 循环所有的 trace 数据封装成 tracepb.Span, 由 Spans 方法再封装成 tracepb.ResourceSpans。
  14. 定义一个 traces 发送的请求。
  15. 进行发送 traces。
  16. 在发送 traces 的时候在 send 中 call singleSend 去发送数据会有失败重试。
  17. 使用 http 或者 grpc 的client发送 tracepb.ResourceSpans 数据到 collector。
  18. 将 batch 的数据处理完之后清空一下 batch 字段用于继续从 queue里面拿 span用于下一个发送时机要去处理的 span 数据。
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: go

“golang工程——opentelemetry简介、架构、概念、追踪原理-CSDN博客” 的相关文章