原文档地址是:
    https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md#logs

    在架构的最高层上,OpenTelemetry 客户端被组织为 signals。每一个 signals 定义了一个可观察的特定格式。例如:tracing,metrics,baggage 它们是分离三种不同的 signals。signals 共享一个公共的子系统 — context propagation — 但是它们是彼此独立的功能。

    每一个 signal 定义了软件描述自己的机制。一个代码库,例如一个 web 框架或者一个数据库客户端,为了描述自身需要依赖很多个 signals。OpenTelemetry 的代码可以混和到其他的代码在这个代码库中。这使得 OpenTelemetry 成为了 cross-cutting concern(跨领域) - 为了提供价值混合入其他的软件代码中。Cross-cutting concerns,就其本身而言,违反了核心的设计原则 — 关注点分离。 因此 OpenTelemetry 客户端设计需要格外的小心和注意来避免由于依赖于这些 cross-cutting APIs 对当前的代码库引入问题

    OpenTelemerty 客户端被设计成将每个 signal 中必须导入的(cross-cutting concerns)点必须是可分离独立管理的。OpenTelemetry 客户端被设计成可延展的框架。为了完成这些目标,每一个 signal 由包括了四种类型的包组成: API,SDK,Semantic Conventions,Contrib

    API 包是提供给仪表的一组 cross-cutting 的公共接口组成的。被导入进第三方库以及程序代码中的 Opentelemetry 的客户端的任何部分都被认为是的 API 的部分

    SDK 是 API 的实现,它通过 OpenTelemetry 的工程来实现,通过程序自身来安装以及管理 SDK。注意 SDK 中会包含额外的公共接口这些不被认为是 API 包的一部分,它们不是 cross-cutting concerns。这些公共的接口被定义为 constructors 以及 plugin interfaces。程序自身使用 SDK 的 constructors;plugin authors 使用 SDK 的 plugin 接口。instrumentation authors 不能直接引用 SDK 包中的任何类型,只允许使用 API

    Semantic Conventions 定义了 keys 以及 values 它们描述应用程序使用的常见的概念,协议,操作。

    • Resource Conventions
    • Span Conventions
    • Metrics Conventions

    OpenTelemetry 项目维护已经于流行的 OSS 项目整合,后者被认为是对现代 Web 服务的观察是非常重要的。例如 API 的仪表包括了 Web 框架,database 客户端,消息队列。例如 SDK 整合的 Plugin 包括了将测量数据导出到流行的分析工具和测量存储系统中

    一些插件,例如 OTLP 导出以及 TraceContext 传播,是 OpenTelemetry 规范所规定的。这些必须的插件被作为 SDK 的一部分

    插件和工具是可选的,并且与 SDK 是分离的,它们被称为 Contrib 包。API Contrib 是指完全依赖于 API 的包;SDK Contrib 是指完全依赖 SDK 的包

    Contrib 术语特别是指由 OpenTelemetry 项目维护的插件以及工具的集合;它不会引用到任何的第三方的插件

    OpenTelemetry 保持稳定性以及向后的兼容性。

    分布式跟踪是一组事件的集合,一个单独的逻辑操作的结果来触发,它是跨应用程序的各个组件的整合。一个分布式的追踪包含的事件跨越多个程序,网络以及安全边界。当在一个网站上一个按钮被被点击发起一个动作的时候一个分布式的追踪也就启动了 — 在这个例子里,追踪表示按下此请求按钮后,请求链的下游服务之前的调用

    OpenTelemetry 中的 Traces 被隐式的通过它们的 Spans 来定义。特别的,一个 Trace 可以被认为是 Spans 的有向无环图 (DAG), 其中跨越 Spans 之间的情形被定义为 parent/child 关系

    例如,下面的追踪包含了 6 个 Spans:

    1. Causal relationships between Spans in a single Trace
    2. [Span A] ←←←(the root span)
    3. |
    4. +------+------+
    5. | |
    6. [Span B] [Span C] ←←←(Span C is a `child` of Span A)
    7. | |
    8. [Span D] +---+-------+
    9. | |
    10. [Span E] [Span F]

    同时,也可以用时间序列来表现它们的关系

    Temporal relationships between Spans in a single Trace
    
    ––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time
    
     [Span A···················································]
       [Span B··············································]
          [Span D··········································]
        [Span C········································]
             [Span E·······]        [Span F··]
    

    一个 Span 表示的是在一个事务中的一个操作;每一个 Span 封装了下面的状态:

    • 一个操作名
    • 启动以及结束的时间戳
    • 属性:一个 k-v 对列表
    • 零个或者多个 Events, 每一个本身就是一个元组(时间戳,名称,属性)。名称必须是字符串
    • 父级的 Span 标识符
    • 链接到零个或者多个有关联的 Span(通过这些相关联 Span 的 SpanContext)
    • SpanContext 信息引用一个 Span。见下文

    在追踪中,代表所有的信息它被识别为 Span,必须被传播给子 Span 以及跨越进程边界。一个 SpanContext 包含追踪的标识符以及可以从父 Span 到子 Span 传播的选项

    • Traceld 是一个 Trace 的标识符。它在全局范围内是独一无二的,是一个 16 字节的随机串。针对一个特定的跨越多个进程的 trace,TraceId 被用来对所有的 Span 进行分组

    • SpanId 一个 span 的标识符。它也在全局是唯一的,是一个 8 字节的随机字符串。如果传递给一个子 Span,那么这个 ID 就会变成子 Span 的父 Span 的 ID

    • TraceFlags 代表了一个追踪的选项。它是一个字节的 bitmap 格式

    • Sampling bit - 标示当前的追踪是否样本

    • Tracestate 在一个 k-v 对的列表中携带追踪系统的特定上下文。Trancestate 允许不同的供应商传播额外的信息,并与它们传统的 ID 格式进行交互

    一个 Span 可以链接到零个或者多个其他的 Spans(通过 SpanContext 定义),它们之间有因果关系。Links 可以在一个独立的 Trace 中或者跨越不同的 Traces 中指向到 Spans。Links 可以被用来表示一个已经发起的 Span,它通过再发起多个 Span 来执行一个批量操作,每一个都表示在一个批处理中的需要被处理的项目

    使用 Link 另外一个例子就是声明一个原始的以及后续的 Trace 之间的关系。这个可以被用来当一个 Trace 进入到一个服务的可信边界,并且服务策略需要生成一个新的 Trace,而不是信任当前的进入的 Trace context。这个新的被链接的 Trace 可能是一个长时间运行的异步数据处理操作,它被多个快速进入的请求来初始化

    当使用 scatter/gather(通常也被称作 fork/join)模式,根操作启动了很多个下游的处理操作并且它们都会被聚合到一个单独的 Span。这个最后的 Span 链接到它总计的很多操作。它们所有的 Spans 都归属于相关的 Trace。类似于 Span 的父字段。但是,建议不要在此方案中设置 Span 的父级,因为从语义上父级字段代表的是单个父级的方案。在许多情况下,父级完全包含了子级,在 scatter/gather 的情形下以及 batch 的情形下不属于这种情况。

    OpenTelemetry 允许用预定义的聚合和标签集(labels)来记录原始的测量或者指标

    记录原始的测量使用 OpenTelemetry API 允许终端用户延迟决定针对这些指标数据使用什么聚合算法以及定义标签。它将在客户端库比如 grpc 中记录原始的 server_latency 或者 received_bytes。因此最终用户将决定针对这些原始的测试数据使用的统计的类型。它可以是简单的平均或者复杂的直方图计算

    使用 OpenTelemetry API 记录预定义的汇总 metrics 是不太重要的。它允许收集 cpu 以及内存的消耗的值,或者简单的 metric 比如 “队列长度”

    用于记录原始测量的类型有 Measure 以及 Measurement。Measurement 的列表可以附加额外的上下文使用 OpenTelemetry API 一起来记录。因此用户可以定义总计这些 Measurement 然后使用 context 透传给定义了结果的 metric 的附加维度上。

    Measure 描述通过库记录单个值的类型。它定义了在库导出的 measurement 和一个程序之间的协议,它将汇总这些独立的值到一个 Metric。Measure 是由标识符,描述以及值单元组成

    Measurement 描述了针对一个 Measure 将被收集的一个值。Measurement 是一个空的接口在 API 层面。这个接口被定义在 SDK 里

    所有类型的预定义统计基类被称为 Metric。它定义了基础的 metric 的属性比如 name 以及 labels。从 Metric 中继承的类型,定义它们的统计的类型,单个测量或者点的结构。API 定义了下面预定义的 metrics 的类型

    • Counter metric 报告当时的测量值。Counter 值可以增加或者保持原来的,但是不能减小。Counter 的值不能为负。这里有两种类型的 counter metric 值 - double 以及 long
    • Gauage metric 报告数字类型的当时的值。Gauage 可以增加或者减小。gauge 值可以是负的。这里有两种类型的 gauge metric 值 - double 以及 long

    API 允许构造所选类型的 Metric。SDK 定义了一种方式去查询一个 Metric 的当前值的方法

    每一个 Metric 的类型都有它的 API 来记录它需要统计的值。API 支持两种 — 设置 Metric 值的 push 以及 pull 模型

    Metrics 数据模型被定义在 SDK 中,并且基于 metrics.proto。这个数据模型被用来给所有的 OpenTelemetry 导出程序作为它的输入。不同的导出有不同的能力(例如:什么数据类型被支持)以及不同的限制(例如,那些字符允许出现在 label keys 中)。Metrics 的目的是成为一个可能的超集,而不是低层级的支持所有特性公约数。所有的 exporter 通过定义在 OpenTelemetry SDK 中的 Metric 的生产者中产生的 Metric 数据作为消费源

    因此,Metrics 对数据的限制是最小的 (例如:keys 里面那些字符是允许的),并且对 Metrics 的代码处理中应该避免对 Metrics 的数据做有效性的处理。取而代之的是,透传数据到后端,信任后端对数据的处理,并且从后端透传任何的错误

    Log Data Model 定义了 OpenTelemetry 如何定义 logs 以及 events

    除了追踪传播,OpenTelemetry 提供了简单机制来传播 name/value 对,称为 Baggage。Baggage 的目的是为了索引一个服务中的可观察事件,这些事件的属性是通过在同一个事务中的之前的一个服务提供。这个有助于在这些事件中建立因果关系

    同时 Baggage 可以被用来建立其他的 cross-cutting concerns 的原型,这个机制主要的目的是为了在 OpenTelemetry 的可观测系统中传递值

    这些值可以从 Baggage 中被消费,以及用作 metrics 的附加的维度,或者作为日志以及 traces 的附加的上下文。一些例子是:

    • 一个 web 服务可以从包含了上下文的场景中受益,这个上下文中可以知道什么服务发送的这个请求
    • SaaS 支持一个包含了上下文的场景,上下文里面会包含关于负责发起请求的 API 用户或者 Token
    • 确定特定浏览器版本与图像处理服务中的故障的关联

    为了与 OpenTracing 保持向后的兼容,当使用 OpenTracing 桥的时候 Baggage 的传播必须是一个 Baggage。具有不同标准的 concerns 应该被认为是创建了一个新的 cross-cutting concern 来覆盖用户的案例;它们可能从 W3C 的编码格式中受益,但是会使用一个新的 HTTP 头来在分布式追踪中传递数据

    资源捕获的关于实体被记录的测量的信息。例如,Kubernetes 容器导出的指标是可以链接到资源上的,资源可以是指定的集群,命名空间,pod,容器名称

    资源可以捕获整个层级中的实体的标识。它可能描述在云服务中的一个主机中的特定的容器或者一个在运行中的应用程序

    注意,某些处理流程的标识符信息可以通过 OpenTelemetry SDK 或者特定的 exporter 自动的关联到当前的测量 (有的数据里面就定义了 ProcessIdentifier 字段)

    所有的 OpenTelemetry 的 cross-cutting concerns,例如 trace 以及 metrics,共享了一个底层的 Context 机制,在整个的分布式事务的声明周期内存储状态和访问数据

    OpenTelemetry 使用传播期来序列化和反序列化 cross-concern 的值,例如 Span(通常指的是 SpanContext 部分)和 Baggage。不同的传播类型定义了特定的传输所要求的限制,并且绑定到数据类型上

    传播 API 当前定义了一种传播类型:

    • TextMapPropagator: 将值注入到携带的文本中,并且可以解析出这个值

    OpenTelemetry collector 是一组组件,它可以通过 OpenTelemetry 或者其他的 monitoing/tracing 库 (Jaeger, Prometheus 等等) 的处理程序上收集 traces,metrics 以及最终的其他测量数据(例如,日志),然后进行聚合和智能采样,最后导出 traces 和 metrics 到一个或者多个 monitoing/tracing 后端。collector 允许丰富和转换收集的测量数据(例如添加额外的属性或者清理个人信息)

    OpenTelemetry collector 有两种操作模式:Agent(与应用程序一起在本地运行的守护程序)和 Collector(独立运行的服务)

    更多细节参考
    https://github.com/open-telemetry/opentelemetry-collector/blob/master/docs/vision.md

    详情
    https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library

    该项目的思想在于通过直接调用 OpenTelemetry API 使每个库和应用程序开箱即用。然而,很多的库没有这样的集成,因此需要一个单独的库,该库将注入到调用中,使用机制类似与接口的封装,订阅到库指定的回调上,或者变换现有的测量数据为 OpenTelemetryd 的数据模型

    一个库如果启用了 OpenTelemetry 可观察行的库称为工具库。

    一个 instrumentation 库应该命名为遵循下面的命名约定 (例如 middleware 是针对的 web 框架)

    如果没有确定的名称,建议在程序包前面加上
    opentelemetry-instrumentation 前缀,然后加上 instrumented 库自己的名字,例如: