OpenTelemetry,简称OTel,是一个与供应商无关的开源可观测性框架,用于检测、生成、收集和导出
遥测数据,如轨迹、度量、日志。OTel的目标是提供一套标准化的供应商无关SDK、API和工具,用于接
收、转换数据并将数据发送到可观测系统(监控系统)后端(开源或商业)
OpenTelemetry 是以解决观测性为初衷的项目,观测性包含链路,监控,日志。主要解决的问题是观测性领域模型的统一,观测性数据收集的统一,观测性数据输出的统一。这些统一性主要体现在 API 规范,SDK 实现规范,接口规范等。OpenTelemetry 不会负责观测数据的存储,需要存储这些观测数据的 backend。OpenTelemetry 定义来数据输出的规范,由各大厂商自行完成数据的持久化。
OpenTelemetry 也提供了很多开发语言的 SDK,开发者需要使用自己熟悉的语言的 SDK 完成应用程序的观测性能力。目前不同的开发语言的支持程度不一样。
主要组成:
Specification:这个组件是语言无关的,主要是定义了规范,如 API 的规范,SDK 的开发规范,数据规范。使用不同开发源于开发具体 SDK 的时候会按照标准开发,保证了规范性。
Proto:这个组件是语言无关的,主要是定义了 OpenTelemetry 的 OTLP 协议定义,OTLP 协议是 OpenTelemetry 中数据传输的重要部分。如 SDK 到Collector,Collector 到 Collector,Collector 到 Backend这些过程的数据传输都是遵循了 OTLP 协议。
Instrumentation Libraries:是根据 SDK 的开发规范开发的支持不同语言的 SDK,如 java,golang,c 等语言的 SDK。客户在构建观测性的时候,可以直接使用社区提供的已经开发好的 SDK 来构建观测能力。社区也在此基础上提供了一些工具,这些工具已经集成了常见软件的对接。
Collector:负责收集观测数据,处理观测数据,导出观测数据。
文档
go源码
demo
语义
otel-collector配置文档
OpenTelemetry收集器组件库
Application: 一般的应用程序,同时使用了 OpenTelemetry 的 Library (实现了 API 的 SDK)。
OTel Libraty:也称为 SDK,负责在客户端程序里采集观测数据,包括 metrics,traces,logs,对观测数据进行处理,之后观测数据按照 exporter 的不同方式,通过 OTLP 方式发送到 Collector 或者直接发送到 Backend 中。
OTel Collector:负责根据 OpenTelemetry 的协议收集数据的组件,以及将观测数据导出到外部系统。这里的协议指的是 OTLP (OpenTelemetry Protocol)。不同的提供商要想能让观测数据持久化到自己的产品里,需要按照 OpenTelemetry 的标准 exporter 的协议接受数据和存储数据。同时社区已经提供了常见开源软件的输出能力,如 Prometheus,Jaeger,Kafka,zipkin 等。图中看到的不同的颜色的 Collector,Agent Collector 是单机的部署方式,每一个机器或者容器使用一个,避免大规模的 Application 直接连接 Service Collector;Service Collector 是可以多副本部署的,可以根据负载进行扩容。
Backend: 负责持久化观测数据,Collector 本身不会去负责持久化观测数据,需要外部系统提供,在 Collector 的 exporter 部分,需要将 OTLP 的数据格式转换成 Backend 能识别的数据格式。目前社区的已经集成的厂商非常多,除了上述的开源的,常见的厂商包括 AWS,阿里,Azure,Datadog,Dynatrace,Google,Splunk,VMWare 等都实现了 Collector 的 exporter 能力。
观测性常见方案主要总结:
日志方案:filebeats->elasticsearch->kibana;filebeats->kafka->logstash->elasticsearch->kibana; fluentd->elasticsearch->kibana;fluentd->kafka->fluentd->elasticsearch->kibana 。
监控方案:比较统一的都在使用 prometheus,prometheus-operator,thanos,grafana。
链路方案:主要方案有开源的 skywalking,jaeger,zipkin,还有商业的方案,如 dynatrace 等。
opentelemetry解决方案就是为了统一Trace, metrics, loggingd 标准
是Tracer的工厂。在大多数应用程序中,Tracer提供程序初始化一次,其生命周期与应用程序的生命周
期相匹配。Tracer Provider初始化还包括Resource和Exporter初始化。这通常是使用OpenTelemetry进
行跟踪的第一步
Tracer(跟踪程序)用于创建span,其中包含有关给定操作(例如服务中的请求)所发生情况的更多信
息。跟踪程序是从跟踪程序提供程序创建的
跟踪导出器将跟踪发送给消费者。此使用者可以是调试和开发时的标准输出、OpenTelemetry收集器或
您选择的任何开源或供应商后端
跨度表示一个工作或操作单元。跨度是痕迹的组成部分。在OpenTelemetry中,它们包括以下信息:
span context 是每个跨度上的一个不可变对象,包含以下内容:
Trace ID表示跨度所属的跟踪
Span ID 跨度的跨度ID
Trace Flags,一种包含跟踪信息的二进制编码
Trace State,可以携带特定于供应商的跟踪信息的键值对列表
span context 是与分布式上下文和Baggage一起序列化和传播的跨度的一部分。
由于“span context”包含跟踪ID,因此在创建“span link”时会使用它
属性是包含元数据的键值对,您可以使用这些元数据对跨度进行注释,以携带有关其正在跟踪的操作的
信息。
例如,如果跨度跟踪在电子商务系统中将商品添加到用户购物车的操作,则可以捕获用户的ID、要添加到购物车的商品的ID和购物车ID。
属性具有每个语言SDK实现的以下规则:
键必须是非空字符串值
值必须是非空字符串、布尔值、浮点值、整数或这些值的数组
此外,还有语义属性,这是常见操作中通常存在的元数据的已知命名约定。尽可能使用语义属性命名有
助于跨系统标准化常见类型的元数据。语义约定详见文档:https://github.com/opentelemetry/semantic-conventions
跨度事件可以被认为是跨度上的结构化日志消息(或注释),通常用于表示跨度持续时间内的一个有意义的奇异时间点。
例如,考虑web浏览器中的两种情况:
链接的存在使您可以将一个跨度与一个或多个跨度相关联,从而暗示因果关系。例如,假设我们有一个分布式系统,其中一些操作由跟踪跟踪。作为对其中一些操作的响应,额外的操作排队等待执行,但其执行是异步的。我们也可以通过跟踪来跟踪此后续操作。我们希望将后续操作的跟踪与第一个跟踪相关联,但我们无法预测后续操作何时开始。我们需要将这两个轨迹关联起来,所以我们将使用跨度链接。
您可以将第一个跟踪中的最后一个跨度链接到第二个跟踪的第一个跨度。现在,它们是因果关联的。
链接是可选的,但也是将跟踪跨度相互关联的好方法
span的状态可选值:Unset,Ok,Error。当应用程序代码中存在已知错误(例如异常)时,可将状态可以设置为“Error”
创建跨度时,它是客户端(Client)、服务器(Server)、内部(Internal)、生产者(Producer)或消费者(Consumer)之一。这种span类型为跟踪后端提供了一个关于应该如何组装跟踪的提示。根据OpenTelemetry规范,服务器跨度的父跨度通常是远程客户端跨度,而客户端跨度的子跨度通常是服务器跨度。类似地,消费者跨度的父代始终是生产者,生产者跨度的子代始终是消费者。如果未提供,则假定跨度类型为内部
度量是在运行时捕获的关于服务的度量。从逻辑上讲,捕获其中一个测量的时刻被称为度量事件,它不仅包括测量本身,还包括捕获它的时间和相关的元数据。
应用程序和请求度量是可用性和性能的重要指标。自定义指标可以深入了解可用性指标如何影响用户体验或业务。收集的数据可用于警告停机或触发调度决策,以在高需求时自动扩大部署规模
是 Meters的工厂。在大多数应用程序中,Meter Provider初始化一次,其生命周期与应用程序的生命周期相匹配。Meter Provider初始化还包括资源和导出程序初始化。这通常是使用OpenTelemetry进行测量的第一步
Meter创建度量仪表,在运行时捕获有关服务的测量值。meter 是从Meter Provider 创建的
Metric Exporter 向消费者发送度量数据。此使用者可以是调试和开发时的标准输出、OpenTelemetry收集器或您选择的任何开源或供应商后端
在OpenTelemetry中,测量由公制仪器捕获。这种公制仪器由名称、种类、可选单位和可选说明定义。这种工具的名称、单元和描述由开发人员选择,或通过常见的语义约定(如请求或过程度量)进行定义。语义约定详见文档:https://github.com/open-telemetry/semantic-conventions
仪器类型为以下六种之一:(类似promethues里的指标)
一个随着时间积累的值——你可以把它想象成汽车上的里程表;它只会上升
与Counter相同,但每次导出都会收集一次。如果您不能访问连续增量,而只能访问聚合值,则可以使用
一种随着时间的推移而积累的值,但也可能再次下降。例如,队列长度会随着队列中工作项的数量而增加或减少
与UpDownCounter相同,但每次导出都会收集一次。如果您不需要访问连续更改,而只能访问聚合值(例如,当前队列大小),则可以使用
测量读取时的当前值。一个例子是车辆中的燃油表。仪表总是异步的
直方图是客户端值的集合,例如请求延迟。如果你有很多值,并且不是对每个单独的值都感兴趣,而是对这些值的统计数据感兴趣,那么直方图可能是一个不错的选择
除了度量工具之外,聚合的概念也是一个需要理解的重要概念。聚合是一种技术,通过该技术,将大量测量值组合成关于在时间窗口期间发生的度量事件的精确或估计统计数据。OTLP协议传输这样的聚合度量。OpenTelemetry API为每个仪器提供了一个默认聚合,可以使用视图覆盖这些聚合。OpenTelemetry项目旨在提供可视化工具和遥测后端支持的默认聚合
与请求追踪不同,metrics旨在提供汇总的统计信息。例如:
视图为SDK用户提供了自定义SDK输出的度量的灵活性。他们可以自定义要处理或忽略的Metrics。他们可以自定义聚合以及要在度量上报告的属性
Baggage提供了一种统一的方式来存储和传播轨迹和其他信号中的信息。在OpenTelemetry中,Baggage是跨段之间传递的上下文信息。它是一个键值存储,位于跟踪中的span上下文旁边,使在该跟踪中创建的任何span都可以使用值。例如,假设您希望在跟踪中的每个跨度上都有一个CustomerId属性,该属性涉及多个服务;但是,
CustomerId仅在一个特定服务中可用。为了实现您的目标,您可以使用OpenTelemetry Baggage在系统中传播此值。
OpenTelemetry使用上下文传播来传递Baggage,每个不同的库实现都有传播程序,可以解析并使Baggage可用,而无需显式实现它Baggage不属于span属性的子集,因此不会自动出现在子系统span的属性中,需要明确的将信息从baggage中取出并附加到span的属性。
资源是一种特殊类型的属性,适用于流程生成的所有跨度。这些应该用于表示关于非临时进程的底层元数据,例如,进程的主机名或其实例ID。资源应该在初始化时分配给跟踪程序提供程序,并且创建时与属性非常相似
无go版本
日志是一种带有时间戳的文本记录,可以是结构化的(推荐的),也可以是非结构化的,带有元数据。在所有遥测信号日志中,具有最大的遗留问题。大多数编程语言都有内置的日志记录功能或众所周知的、广泛使用的日志记录库。尽管日志是一个独立的数据源,但它们也可以连接到跨度。在OpenTelemetry中,任何不属于分布式跟踪或度量的数据都是日志。例如,事件是一种特定类型的日志。
日志通常包含详细的调试/诊断信息,例如操作的输入、操作的结果以及该操作的任何支持元数据对于跟踪和度量,OpenTelemetry采用了一种干净的设计方法,指定了一个新的API,并在多语言SDK中提供了此API的完整实现OpenTelemetry使用日志的方法不同。由于现有的日志记录解决方案在语言和操作生态系统中广泛存
在,OpenTelemetry充当了这些日志、跟踪和度量信号以及其他OpenTelemetrys组件之间的“桥梁”。事实上,由于这个原因,日志的API被称为“Logs Bridge API”
作为应用程序开发人员,您不应该直接调用Logs Bridge API,因为它是为日志库作者提供的,用于构建日志附加程序/桥。相反,您只需使用首选的日志记录库,并将其配置为使用能够将日志发送到OpenTelemetry LogRecordExporter的日志附加器(或日志桥)
记录器提供程序(有时称为LoggerProvider)是记录器的工厂。在大多数情况下,Logger Provider只初始化一次,其生命周期与应用程序的生命周期相匹配。Logger Provider初始化还包括Resource和Exporter初始化是Logs Bridge API的一部分,仅当您是日志库的作者时才应使用
Logger创建日志记录。记录器是从日志提供程序创建的
是Logs Bridge API的一部分,仅当您是日志库的作者时才应使用
日志记录导出器将日志记录发送给使用者。此使用者可以是调试和开发时的标准输出、OpenTelemetry收集器或您选择的任何开源或供应商后端
日志记录表示事件的记录。在OpenTelemetry中,日志记录包含两种字段:
Timestamp 事件发生的时间
ObservedTimestamp 观察到事件的时间
TraceId 请求跟踪ID
SpanId 请求跨度ID
TraceFlags W3C跟踪标志
SeverityText 严重性文本(也称为日志级别)
SeverityNumber 严重程度的数值
Body 日志记录的正文
Resource 描述日志的来源
InstrumentationScope 描述发出日志的作用域
Attributes 有关该事件的其他信息
详见文档:https://opentelemetry.io/docs/specs/otel/logs/data-model/