系统语义约定:仪表化设计理念

系统语义约定与其他 semconv 组不同,陷入了一种奇怪的二分法。虽然我们希望确保涵盖明显的通用用例,但监控系统健康是一项非常古老的实践,拥有许多不同的现有策略。虽然我们可以以跨平台的方式涵盖基本用例,但我们希望确保特定平台的专家用户不会被忽视;如果用户没有获得针对特定类型数据的建议,而这些数据不是跨平台且通用的,他们可能会想出自己对该仪器应该是什么样子的不同想法,从而导致语义约定本应避免的那种分裂。

以下各节将解决一些最常见的仪器设计问题,以及我们作为工作组如何选择解决它们。在某些情况下,由于我们独特的情况,它们对于通用语义约定指南来说是独特的,并且在这些情况下将被特别指出。

命名空间

相关讨论:#1161

系统语义约定通常涵盖以下命名空间

  • system
  • process
  • host
  • memory
  • network
  • disk
  • memory
  • os

决定指标/属性的命名空间通常受以下信念的启发

指标/属性的命名空间应在逻辑上映射到被视为仪器来源的操作系统概念。

最明显的例子是语言运行时指标和 process 命名空间指标。其中许多指标非常相似;大多数语言运行时都提供某种形式的 cpu.timememory.usage 和类似指标。如果我们考虑在设计中将去重作为首要考虑因素,那么 process.cpu.timeprocess.memory.usage 应该简单地由可能生成这些指标的任何语言运行时引用。然而,作为工作组,我们认为 process 命名空间和运行时命名空间指标保持分离非常重要,因为 process 指标旨在将**操作系统级别的进程作为仪器来源**,而运行时指标代表**语言运行时作为仪器来源**。

在某些情况下,这只是使仪器的目的尽可能清晰的问题,但在尝试跨不同仪器来源共享定义的情况下,存在发生冲突的潜在可能。我们接受这种后果的时间的具体例子是 cpu.mode;决定是将所有独立的 *.cpu.state 属性实例统一为一个共享的 cpu.mode 属性。其后果是,cpu.mode 需要在其根定义中具有广泛的枚举,并在每个不同的 cpu.mode ref 中进行特殊豁免,因为在 process.cpu.timecontainer.cpu.timesystem.cpu.time 等中使用的 cpu.mode 具有不同子集的整体枚举值。然而,我们作为一个工作组决定在这种情况下接受后果,但我们并不热衷于在整个系统 semconv 中处理这个问题,因为仪器最终会充斥着每个命名空间中的大量边缘情况,这反而违背了共享属性的初衷。

两类设计策略

相关讨论:#1403(特定评论)

我们正在为系统 semconv 仪器考虑两种角色。如果我们有一种仪器,我们会决定它适合哪种角色,并以此来决定我们应该如何命名/处理该仪器。

通用类别:一个通用的跨平台用例,我们希望任何仪器用户都能轻松访问

当仪器用于通用类别时,我们将努力使名称和示例尽可能具有指导性。这些仪器将驱动我们真正希望通过系统语义约定涵盖的最重要的用例。诸如仪表板、警报和更广泛的 o11y 设置教程等内容,将主要使用通用类别的仪器来涵盖我们作为一个工作组制定的基本用例。我们希望这些仪器能够非常清楚地说明它们应该如何以及何时使用。通用类别的仪器将被推荐为**默认启用**。

专家类别:一个更具体的用例,专家可以启用它来获取他们已经知道如何使用的更深入信息

当仪器属于专家类别时,我们假定目标受众已经熟悉该概念,并且确切知道他们正在寻找什么以及为什么。专家类别仪器的目标是确保那些具有非常具体和详细需求的用户仍然能够得到我们语义约定的支持,这样他们就不必费力去想出自己的方法,从而面临语义约定旨在解决的同类仪器碎片化问题。我们处理专家类别仪器方式的主要区别在于:

  1. 名称和由此产生的价值观将直接映射到用户在自己寻找信息时所期望的内容。我们很少会规定信息应该如何使用或如何细分。例如,用于表示进程 cgroup 的指标将产生与用户调用 cat /proc/PID/cgroup 时产生的值完全匹配的值。
  2. 如果某项仪器特定于某个操作系统,则操作系统的名称将包含在仪器名称中。有关更多信息,请参阅操作系统名称。例如,进程 cgroup 的指标将是 process.linux.cgroup,因为 cgroup 是 Linux 内核特有的功能。

示例

一些通用类别的例子

  • 内存/CPU 使用率和利用率指标
  • 通用磁盘和网络指标
  • 通用系统/进程信息(名称、标识符、基本规范)

一些专家类别的例子

  • 特定的 Linux 功能,例如 /procfs 中的特殊进程/系统信息(参见 /proc/meminfocgroups
  • 特定的 Windows 功能,例如特殊进程信息(参见 Windows HandlesProcess Working Set
  • 细粒度的进程信息,如打开的文件描述符、页面错误等

仪器设计指南

在设计新的仪器时,我们将尽可能遵循以下步骤

选择仪器类别

在系统语义约定中,在决定一项仪器是通用类还是专家类时,最重要的问题是:

  • 它是跨平台的吗?
  • 它支持我们的最重要的用例吗?如果是,我们将将其设为通用类别。

这两个问题的答案很可能都需要是“是”,仪器才会被认为是通用类别。由于通用类别仪器是我们期望最广泛的受众使用的,因此我们需要更仔细地审查它,以确保它都尽可能必要和有用。

如果其中任何一个问题的答案是“否”,那么我们很可能会将其视为专家类别。

命名

对于通用类别,选择一个最能准确描述通用概念的名称,而不偏向于某个平台。尽可能倾向于简单,因为这是将由最广泛受众使用的仪器;我们希望它尽可能易于理解和符合人体工程学。

对于专家类别,选择一个最能直接匹配在上下文中通常用于描述该概念的词语。由于这种仪器将是可选的,并且很可能被那些确切知道自己想要什么的人寻找,因此我们可以优先将名称尽可能地与其定义匹配。对于平台专有的专家类别指标,如果该指标名称不太可能以跨平台方式应用,我们将把 OS 包含在命名空间中作为子命名空间(而不是根命名空间)。有关更多详细信息,请参阅本节

对于通用类别,我们可以规定仪器的值是什么。我们希望确保通用类别仪器最符合我们对通用用例的设想,并且我们希望确保那些不是专家但只想要最重要的基本信息的用户能够通过开箱即用的 semconv 仪器轻松获取它。这意味着在通用类别仪器中,我们更有可能判断出确切的值应该是什么,以及是否应该在从源拉取值时对值进行重塑,以服务于通用用例。

对于专家类别,我们应努力不规定,而是尽可能地匹配所建模的概念。我们期望专家类别的仪器由那些已经理解它的人启用。在系统 Semconv 的上下文中,这些可能是用户以前手动或通过现有 OS 工具收集的内容,他们想将其建模为 OTLP。

描述

系统语义约定所建模的概念可能非常复杂,有时需要比大多数普通从业者更深入地了解操作系统和计算概念。因此,人们倾向于提供对我们正在建模的概念的详细解释。然而,我们认为,要向没有知识的读者传授这些概念所需的解释量,将需要大量的背景和细微差别,这会使文档变得混乱,并模糊我们真正需要传达的信息,即不仅仪器是什么,还包括有关如何以及为何以特定方式进行仪器化的详细信息。

这意味着,对于系统语义约定文档,**我们假定读者具备所仪器化概念的基本知识**。指标和属性的 briefnote 字段应用于传达对理解仪器意图至关重要的信息,即:

  • 在不同平台上仪器化同一数据时的差异
  • 当我们推荐对特定数据进行计算而不是直接显示来自现有工具的值时
  • 当我们选择特定名称或枚举值而存在同一概念的常用替代术语时

对于根指标和属性,我们将努力始终包含一个 brief 字段。brief 字段应解释指标/属性是什么,如果值本身的解释很简单(例如,只是从 procfs 等常见源获取值),那么关于值应该是什么的解释可以放在 brief 中。如果该值需要一些计算解释和理由,信息应移至 note 字段。
对于枚举值,其意图通常在给定属性整体的 brief 说明的情况下是显而易见的。在某些情况下,当我们在值上做出了不太明显但必须做出的选择时,可以包含 brief。最常见的情况是,当某些术语在不同平台之间存在差异,而我们不得不选择一个术语来代表所有情况。在这种情况下,brief 可用于澄清我们的意图。

在需要有关概念的信息来描述我们的仪器意图的情况下,所有信息都必须附有权威文档的引用(例如,Linux man pages、Win32 API 文档等)。我们不想在我们的约定文档中使用自己的话来发明任何关于现有概念的新解释。

案例研究:process.cgroup

相关讨论:#1357#1364(特定讨论串)

hostmetricsreceiver 中,有一个 Resource Attribute 称为 process.cgroup。此属性应如何在系统语义约定中采用?

根据我们的定义,此属性属于专家类别

  • cgroups 是 Linux 特有的功能
  • 它不直接属于我们默认开箱即用的任何用例,我们希望涵盖这些用例

在此属性的情况下,在决定名称时有两个重要考虑因素

  • 该属性是专家类别
  • 它是 Linux 独有的,并且不太可能在其他操作系统中引入,因为其他主要平台都有自己的版本(Windows Job Objects、BSD Jails 等)

这意味着我们应该选择一个名称,该名称在上下文中匹配专家们在提及此概念时使用的措辞。您将以此名称指代:“进程的 cgroup,从 /proc/<pid>/cgroup 收集”。因此,我们将从名称 process.cgroup 开始。我们还确定此属性是 Linux 独有的,并且我们有信心它将保持不变,因此我们将其命名为 process.linux.cgroup

由于此指标属于专家类别,我们不希望对此值过于规定。需要知道进程 cgroup 的用户可能已经很好地理解了如何解释和进一步使用它,并且对于本工作组来说,尝试找出其所有可能的用法场景并不值得。对于此属性而言,只要它在我们管辖范围内,最简单的方法就是直接反映来自操作系统的该值,即来自 cat /proc/<pid>/cgroup 的直接值。特别是对于 cgroups,很可能会开发出更专业的 semconv 仪器,特别是在支持更专业的容器运行时或 systemd 仪器方面。对于开发利用 cgroups 的专业仪器的工作组来说,在解释和细分 cgroup 信息时更具体地规定如何做会更有用。

操作系统名称

相关讨论:#1255#1364

监控操作系统是一项古老的实践,并且不同平台之间存在许多截然不同的方法。存在大量的指标,即使考虑到诸如内存使用情况等常见统计数据,也存在平台专有的信息,这些信息仅对专门从事该平台的专家有价值。

因此,我们决定任何仪器,如果:

  1. 特定于某个操作系统
  2. 不打算成为我们认为最重要的通用用例的一部分

那么它将在命名空间中包含操作系统名称。

例如,指标和属性可能存在 process.linuxprocess.windowsprocess.posix 名称。我们不会有根目录 linux.*windows.*posix.* 命名空间。这是因为我们试图从命名空间部分遵循的原则;我们仍然希望仪器来源由属性/指标的根命名空间表示。如果我们有 OS 根命名空间,那么像 systemprocess 等不同来源可能会在每个 OS 命名空间中变得非常混乱,从而破坏了预期的设计理念。