【已评审】新增可观测度量指标和调用跟踪定义和描述

ISSUE链接

背景
随着可观测技术的能力构建逐步完善,需要对系统采集和上报的指标和跟踪统一定义和管理,防止定义冲突、含义不清等问题,确保可观测规范持续演进和社区共建共享。

决策点

  • 新增可观测跟踪定义
  • 新增可观测指标定义(RPC访问、持久化管理、微组件管理、硬件管理)
  • 新增可观测指标描述

整体架构/方案(可选,文字/图描述接口设计背后的整体管理架构/方案)
可观测是基于openTelemetry规范构建的可视化能力,主要围绕系统中的可观测数据(包括指标、跟踪和日志),提供采集、上报以及与多种可视化工具集成的能力,帮助用户更好的监控系统性能,预测运行趋势、分析和定位系统故障

跟踪(Trace)

跟踪是一组事件,这些事件是由单个逻辑操作触发的,并通过应用程序的各个组件处理后最终整合在一起。跟踪可能包含跨越进程、网络和安全边界的事件,因此也被称为分布式跟踪,当有人按下按钮在网站上启动一个操作时,就可能会启动分布式跟踪。
具体来说,跟踪可以被认为是跨度(Span)的有向无环图 (DAG),其中跨度之间的边定义为父子关系。例如,以下是一个由6个跨度组成的跟踪示例:

            [Span A]  ←←←(the root span)
               |
        +------+------+
        |             |
    [Span B]      [Span C] ←←←(Span C is a `child` of Span A)
        |             |
    [Span D]      +---+-------+
                  |           |
               [Span E]    [Span F]

使用时间轴来显示跟踪轨迹会更容易理解,如下图所示:

––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time

 [Span A···················································]
   [Span B··············································]
      [Span D··········································]
    [Span C········································]
         [Span E·······]        [Span F··]

跨度的组成

  • 操作名称。
  • 开始和结束时间戳。
  • 属性:键值对列表。
  • 事件:零个或多个事件的集合,每个事件本身都是一个元组(时间戳、名称、属性)。名称必须是字符串。
  • 父级跨度标识符。
  • 链接:指向零个或多个因果相关的跨度的链接(通过这些相关的跨度上下文)。
  • 上下文:引用跨度所需的跨度上下文(Span Context)信息。

跨度的名称

跨度的名称简洁地标识了跨度所代表的工作,例如RPC方法名称、函数名称或更大计算中的子任务或阶段的名称。

跨度的类型

  • SERVER 表示跨度涵盖了服务端处理的远程请求,而客户端等待响应。
  • CLIENT 表示跨度描述了一个远程服务的请求,客户端等待响应。当 CLIENT 跨度的上下文被传播时,CLIENT 跨度通常会成为远程 SERVER 跨度的父级。
  • PRODUCER 表示跨度描述了本地或远程操作的启动或调度。这个启动跨度通常在相关的 CONSUMER 跨度结束之前结束,甚至可能在 CONSUMER 跨度开始之前结束。 在具有批处理的消息传递场景中,跟踪单个消息需要为每条消息创建一个新的 PRODUCER 跨度。
  • CONSUMER 表示跨度代表由生产者启动的操作的处理,生产者不等待结果。
  • INTERNAL 默认值。表示跨度代表应用程序内的内部操作,而不是具有远程父级或子级的操作。

指标(Metric)

指标是是对系统行为、性能或状态的量化测量,可以是任何可测量的数值,例如CPU使用率、内存占用率、请求延迟、错误率等。记录测量值主要涉及计量仪(Meter)、仪表(Instrument)和测量值(Measurement):

  • 计量器(Meter):主要负责创建和管理仪表(Instrument)。
  • 仪表(Instrument):具有名称、类型、描述和单位等标识,主要用于捕捉和记录测量值。
  • 测量值(Measurement):单次记录的原始值,包含键值对属性标签,用于标记和区分不同场景下的测量值。
+------------------+
| MeterProvider    |                 +-----------------+             +--------------+
|   Meter A        | Measurements... |                 | Metrics...  |              |
|     Instrument X +-----------------> In-memory state +-------------> MetricReader |
|     Instrument Y |                 |                 |             |              |
|   Meter B        |                 +-----------------+             +--------------+
|     Instrument Z |
|     ...          |                 +-----------------+             +--------------+
|     ...          | Measurements... |                 | Metrics...  |              |
|     ...          +-----------------> In-memory state +-------------> MetricReader |
|     ...          |                 |                 |             |              |
|     ...          |                 +-----------------+             +--------------+
+------------------+

指标的组成

  • 指标由元数据和数据组成。
  • 元数据部分包含多个属性:
    • 指标名称。
    • 属性 (维度,也被称为标签)。
    • 值类型(整数、浮点等)。
    • 计量单位。
  • 数据是计数器、仪表、直方图等类型之一。
    • 数据点包含时间戳、属性和值。

指标名称

  1. 它们不是空字符串。
  2. 它们是不区分大小写的 ASCII 字符串。
  3. 第一个字符必须是字母。后续字符必须是字母数字字符、“_”、“.”、“-”和“/”。
  4. 它们的最大长度为 255 个字符。

指标名称使用约定

指标名称不应复数化。

  1. limit - 一种测量某种已知总量的恒定值的工具应称为 entity.limit。例如,system.memory.limit 表示系统内存的总量。
  2. usage - 一种测量已知总量(限制)中已使用量的工具应称为 entity.usage。例如,system.memory.usage 带有属性 state = used | cached | free |… 表示每种状态下的内存量。在适当的情况下,所有属性值的总使用量应等于限制。
    对无限资源或其限制不可知的资源消耗量的测量与使用量不同。例如,一个进程可能消耗的最大虚拟内存量可能会随时间波动,通常无法得知。
  3. utilization - 一种测量使用量相对于其限制的比例工具应称为 entity.utilization。例如,system.memory.utilization 表示正在使用的内存比例。利用率可以是相对于固定限制或软限制的。利用率值以比率表示,通常在范围 [0, 1] 内,但在超过软限制时可能超过 1。
  4. time - 一种测量时间流逝的工具应称为 entity.time。例如,system.cpu.time 带有属性 state = idle | user | system |… 时间测量不一定是墙钟时间,可能小于或大于测量之间的实际墙钟时间。
    时间工具是使用量指标的特殊情况,其中限制通常可以计算为所有属性值的时间总和。时间工具的利用率可以通过使用指标事件时间戳自动推导。例如,system.cpu.utilization 定义为 system.cpu.time 测量值之间的差值除以经过的时间和 CPU 数量。
  5. io - 一种测量双向数据流的工具应称为 entity.io,并具有方向属性。例如,system.network.io

属性

属性是一个键值对,必须具有以下属性:

  1. 属性键必须是一个非空的字符串。键的大小写敏感,大小写不同的键被视为不同的键。
  2. 属性值可以是:
    一个原始类型:字符串、布尔值、双精度浮点数(IEEE 754-1985)或带符号的 64 位整数。
    一个原始类型值的数组。数组必须是同质的,即它不能包含不同类型的值。
  3. 属性的最大个数128。

属性名称

otel.开头的属性名称属于OpenTelemetry规范保留定义。
名称应遵循以下规则:

  1. 名称应为小写。
  2. 使用命名空间。使用点字符分隔命名空间。例如,service.version 表示服务版本,其中 service 是命名空间,version 是该命名空间中的一个属性。
  3. 命名空间可以嵌套。例如,telemetry.sdk 是顶级 telemetry 命名空间中的一个命名空间,而 telemetry.sdk.name 是 telemetry.sdk 命名空间中的一个属性。
    在合适的情况下使用命名空间(和点分隔符)。例如,在引入表示某个对象属性的属性时,遵循 {object}.{property} 模式。如果该对象可能有其他属性,避免使用下划线({object}_{property})。
  4. 对于名称中每个多词的点分隔组件,使用下划线分隔单词(即使用 snake_case)。例如,http.response.status_code 表示 http 命名空间中的状态码。
    仅在点(命名空间)的使用没有意义或改变名称的语义意义时使用下划线。例如,使用 rate_limiting 而不是 rate.limiting。
  5. 属性、事件、指标和其他名称应具有描述性和明确性。
    在引入描述对象某个属性的名称时,包含属性名称。例如,使用 file.owner.name 而不是 file.owner,以及 system.network.packet.dropped 而不是 system.network.dropped。
    避免引入在不同约定或工具中使用时含义不同的名称和命名空间。例如,使用 security_rule 而不是 rule。
  6. 在不影响清晰度的情况下使用更短的名称。在多词组件中删除不必要的命名空间组件或单词。例如,vcs.change.id 与 vcs.repository.change.id 一样精确地描述拉取请求 ID。

详细描述(必填,描述待评审接口的详细内容)

新增可观测跟踪定义

类型 应用场景 关键字段 使用规范 描述 示例 备注
Server 服务端处理的接口远程请求 span.name <app_name>.server.request.<method_name/property_name> 以组件名开头,明确标识收到请求的组件,后面跟对应请求的资源协作接口方法或属性 hwproxy.dbus.Read
span.attributes client.mc.name 必选 请求发起方(客户端)的名称 hwdiscovery
rpc.dbus.path 必选 资源协作路径
rpc.dbus.interface 必选 资源协作接口
rpc.dbus.method 条件必选 资源协作方法
rpc.dbus.property 条件必选 资源协作属性
Client 客户端发起的远程请求 span.name <app_name>.client.request.<method_name/property_name> 以组件名开头,明确标识发起请求的组件,后面跟对应请求的资源协作接口方法或属性
span.attributes server.mc.name 必选 请求接收方(服务端)的名称
rpc.dbus.path 必选 资源协作路径
rpc.dbus.interface 必选 资源协作接口
rpc.dbus.method 条件必选 资源协作方法
rpc.dbus.property 条件必选 资源协作属性
Producer 本地或远程操作的启动或调度 span.name <app_name>.producer.signal.<signal_name> 以组件名开头,明确标识发送信号的组件,后面跟对应请求的资源协作接口信号名称
span.attributes producer.dbus.path 必选 资源协作路径
producer.dbus.interface 必选 资源协作接口
Consumer 生产者启动的操作的处理 span.name <app_name>.consumer.signal.<signal_name> 以组件名开头,明确标识接收信号的组件,后面跟对应请求的资源协作接口方法或属性
span.attributes producer.dbus.path 必选 资源协作路径
producer.dbus.interface 必选 资源协作接口
Internal 应用程序内的内部操作 span.name <app_name>.<file_name>.<method_name>
<app_name>.<file_name>
<app_name>.<module_name>.<method_name>
以组件名开头,明确标识当前处理的组件;后面紧跟模块名和方法名 1、支持应用层不指定名称,不指定时,默认采用该名称;应用层指定名称时,应当采用<app_name>.<module_name>.<opertion_name>的格式
2、进程名称已包含在resource头中,待补充进程id
span.attributes service.name 必选 服务名称。对于C/C++语言,线程名称;lua语言,skynet服务名称 保留属性名,应用框架填入
service.id 必选 服务id,对于C/C++语言,线程id;lua语言,skynet服务id 保留属性名,应用框架填入
file.name 条件必选 文件名。应用层不指定span.name时,可以不填。 保留属性名,应用框架填入
file.method 条件必选 方法名。应用层不指定span.name时,可以不填;对于匿名场景,可以不填。 保留属性名,应用框架填入
file.lineno 必选 文件行号 保留属性名,应用框架填入
table.name 持久化表名 必选

新增可观测指标定义

指标类型:Counter(计数器)、UpDownCounter(增减计数器)、Guage(仪表盘)、Histogram(直方图)
属性要求:必选、条件必选、推荐、可选

分类 指标名称 指标类型 指标单位 属性列表 属性描述 属性要求 描述 标准定义
硬件管理 bmc.hw.chip.io counter count(次) hw.bus.name 硬件总线的名称 必选 硬件器件IO指标 否,自定义指标
hw.chip.name 硬件器件的名称 必选
hw.operation.name 硬件操作的名称,包括write、read 必选
hw.operation.result 硬件操作的结果,包括success、failed 必选
bmc.hw.chip.accessor counter count(次) hw.bus.name 硬件总线的名称 必选 硬件器件访问器指标 否,自定义指标
hw.chip.name 硬件器件的名称 必选
hw.chip.accessor.name 硬件器件的访问器名称 必选
hw.chip.accessor.direction 硬件器件的访问器的访问方向,包括write, read 必选
hw.chip.accessor.result 硬件器件的访问器的访问结果,包括success、failed、emitSignal 必选
bmc.hw.chip.scanner counter count(次) hw.bus.name 硬件总线的名称 必选 硬件器件扫描器指标 否,自定义指标
hw.chip.name 硬件器件的名称 必选
hw.chip.scanner.name 硬件器件扫描器的名称 必选
hw.chip.scanner.result 硬件器件扫描器的扫描结果,包括success、failed、emitSignal 必选
微组件管理 bmc.mc.flash.io counter By(字节) mc.name 微组件名称 必选 微组件flash IO指标 否,自定义指标
fs.file.name 文件名称 条件必选,普通文件
fs.file.type 文件类型:日志文件 log、持久化文件 persistence、普通文件 regular 必选
flash.io.direction flash IO操作方向 必选
RPC访问 bmc.rpc.client.request counter count(次) server.mc.name RPC服务端组件名称 必选 rpc客户端请求指标 否,自定义指标
client.mc.name RPC请求端组件名称 必选
rpc.dbus.path RPC请求的dbus路径 必选
rpc.dbus.interface RPC请求的dbus接口 必选
rpc.dbus.method RPC请求的dbus方法 条件必选,方法访问
rpc.dbus.property RPC请求的dbus属性 条件必选,属性访问
持久化管理 bmc.persistence.server.request counter count(次) client.mc.name 持久化请求端组件名称 必选 持久化服务侧请求指标 否,自定义指标
persistence.data.type 持久化类型,例如PermanentPer(跟模型定义保持一致) 必选
persistence.container.name 持久化容器名 必选
persistence.operation.name 持久化操作类型,例如insert, update, delete 必选
bmc.persistence.flash.io counter By(字节) client.mc.name 持久化请求端组件名称 必选 持久化flash IO指标
(基于数据类型预估,跟实际写入量存在偏差)
否,自定义指标
persistence.data.type 持久化数据类型,例如PermanentPer(跟模型定义保持一致) 必选
persistence.container.name 持久化存储容器名 必选
flash.io.direction flash IO操作方向 必选

新增可观测指标描述

使用场景:

  1. 统一定义和管理系统指标,解决命名冲突、含义模糊等问题
  2. 北向接口提供指标查询和使能能力
  3. 应用框架对指标进行校验和管控,禁止不合理的指标和属性标签
{
    "metrics": [
        {
            "name": "bmc.hw.chip.io",
            "description": "硬件器件IO操作",
            "unit": "count",
            "type": "Counter",
            "attributes": [
                {
                    "name": "hw.bus.name",
                    "description": "硬件总线的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.name",
                    "description": "硬件器件的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.operation.name",
                    "description": "硬件操作的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.operation.result",
                    "description": "硬件操作的结果",
                    "type": "String",
                    "level": "Required"
                }
            ]
        },
        {
            "name": "bmc.hw.chip.accessor",
            "description": "硬件器件访问器",
            "unit": "count",
            "type": "Counter",
            "attributes": [
                {
                    "name": "hw.bus.name",
                    "description": "硬件总线的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.name",
                    "description": "硬件器件的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.accessor.name",
                    "description": "硬件器件的访问器名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.accessor.direction",
                    "description": "硬件器件的访问器的访问方向",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.accessor.result",
                    "description": "硬件器件的访问器的访问结果",
                    "type": "String",
                    "level": "Required"
                }
            ]
        },
        {
            "name": "bmc.hw.chip.scanner",
            "description": "硬件器件扫描器",
            "unit": "count",
            "type": "Counter",
            "attributes": [
                {
                    "name": "hw.bus.name",
                    "description": "硬件总线的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.name",
                    "description": "硬件器件的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.scanner.name",
                    "description": "硬件器件扫描器的名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "hw.chip.scanner.result",
                    "description": "硬件器件扫描器的扫描结果",
                    "type": "String",
                    "level": "Required"
                }
            ]
        },
        {
            "name": "bmc.mc.flash.io",
            "description": "微组件flash IO",
            "unit": "By",
            "type": "Counter",
            "attributes": [
                {
                    "name": "mc.name",
                    "description": "微组件名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "fs.file.name",
                    "description": "文件名称",
                    "type": "String",
                    "level": "Recommended"
                },
                {
                    "name": "fs.file.type",
                    "description": "文件类型",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "flash.io.direction",
                    "description": "flash IO操作方向",
                    "type": "String",
                    "level": "Required"
                }
            ]
        },
        {
            "name": "bmc.rpc.client.request",
            "description": "RPC客户端请求",
            "unit": "count",
            "type": "Counter",
            "attributes": [
                {
                    "name": "server.mc.name",
                    "description": "RPC服务端组件名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "rpc.dbus.path",
                    "description": "RPC请求的dbus路径",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "rpc.dbus.interface",
                    "description": "RPC请求的dbus接口",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "rpc.dbus.method",
                    "description": "RPC请求的dbus方法",
                    "type": "String",
                    "level": "Conditionally-Required"
                },
                {
                    "name": "rpc.dbus.property",
                    "description": "RPC请求的dbus属性",
                    "type": "String",
                    "level": "Conditionally-Required"
                }
            ]
        },
        {
            "name": "bmc.persistence.server.request",
            "description": "持久化服务请求",
            "unit": "count",
            "type": "Counter",
            "attributes": [
                {
                    "name": "client.mc.name",
                    "description": "持久化请求端组件名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "persistence.data.type",
                    "description": "持久化数据类型",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "persistence.container.name",
                    "description": "持久化存储容器名",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "persistence.operation.name",
                    "description": "持久化操作类型",
                    "type": "String",
                    "level": "Required"
                }
            ]
        },
        {
            "name": "bmc.persistence.flash.io",
            "description": "持久化服务flash IO",
            "unit": "By",
            "type": "Counter",
            "attributes": [
                {
                    "name": "client.mc.name",
                    "description": "持久化请求端组件名称",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "persistence.data.type",
                    "description": "持久化数据类型",
                    "type": "String",
                    "level": "Required"
                },
                {
                    "name": "persistence.container.name",
                    "description": "持久化存储容器名",
                    "type": "String",
                    "level": "Required"
                }
            ]
        }
    ]
}

评审结论(评审结束后录入,描述全面且清晰,不能是通过或不通过、同意或不同意)

  • 同意新增可观测指标定义,BMC侧指标调整如下:
    • 指标名称加上bmc.的命名空间
    • 指标属性(标签)名称加上更精准的命名空间约定
  • 同意新增可观测指标指标描述,采用json格式,由observability可观测组件承载
1 个赞

使用场景:

  1. 应用框架对度量指标进行校验和管控,禁止不合理的度量指标和属性标签
  2. 北向接口提供度量指标查询和使能能力
  3. 统一定义和管理系统度量指标,解决命名冲突、含义模糊等问题