OTEP-0119: システム/ランタイムメトリクス計装器の標準名

本OTEPは、OpenTelemetryにおける一般的なシステム/ランタイムメトリクス計装器のための、標準的な名前、ラベル、セマンティック規約の集合を提案します。 ここで提案する計装器名は、サポートされるオペレーティングシステムおよびランタイム環境を通じて共通のものです。 また、特定のOSやランタイムに固有ではないものも含めて、システム/ランタイムメトリクスのための一般的なセマンティック規約も含まれています。

本OTEPは、主にOpenTelemetry CollectorのHost Metrics Receiverにおける既存の実装に基づいています。 提案する名前は、システム/ランタイムメトリクスを曖昧さなく、簡単に発見できるようにすることを目指しています。 追加の動機については、OTEP #108を参照してください。

トレードオフと緩和策

メトリクス計装器に名前を付ける際には、発見のしやすさと曖昧さとの間にトレードオフがあります。 たとえば、system.cpu.load_average というメトリクスは非常に発見しやすいものですが、このメトリクスの意味は曖昧です。 Load averageはUNIXではきちんと定義されていますが、Windowsでは標準的なメトリクスではありません。 発見のしやすさは重要ですが、名前は曖昧であってはなりません。

先行技術

OpenTelemetryには、システムおよび/またはランタイムメトリクスを収集するいくつかの実装がすでに存在します。

  • OTEP #108

    • メトリクス計装器の命名に関するハイレベルなガイドラインを提供しています。
    • システムメトリクスに関する以前の提案から生まれたものでしょうか。
  • Collector

    • Host Metrics Receiverは、エージェントとして実行された際にホストシステムに関するメトリクスを生成します。
    • 現時点でもっとも包括的な実装です。
    • CPU、メモリ、スワップ、ディスク、ファイルシステム、ネットワーク、ロードに関するシステムメトリクスを収集します。
    • CPU、メモリ、ディスクI/Oに関するプロセスメトリクスを収集する計画があります。
    • 個々のメトリクスを定義するのではなく、ラベルをうまく活用しています。
    • 収集されるメトリクスの概要
  • Go

    • Goには、GC、ヒープ使用量、ゴルーチンに関するランタイムメトリクスを収集する計装があります。
    • このパッケージはラベル付きでメトリクスをエクスポートせず、代わりに個々のメトリクスをエクスポートします。
    • 収集されるメトリクスの概要
  • Python

    • Pythonには、一部のシステムおよびランタイムメトリクスを収集する計装があります。
    • システムのCPU、メモリ、ネットワークメトリクスを収集します。
    • ランタイムのCPU、メモリ、GCメトリクスを収集します。
    • Collectorと同様に、ラベルを活用しています。
    • 収集されるメトリクスの概要

セマンティック規約

以下のセマンティック規約は、命名の一貫性を保つことを目的としています。 これらの規約は、考えられるすべてのメトリクスを網羅しているわけではありませんが、本提案のほとんどのケースに対するガイドラインを提供します。

  • usage - 既知の合計量のうち使用された量を測定する計装器は、entity.usage と呼ぶべきです。 たとえば、使用済みのディスク容量には system.filesystem.usage を使います。 無制限のリソースが消費された量を測定するものは、usage とは区別されます。 これは時間やデータ量などが該当します。
  • utilization - 使用率の 値の比率(パーセンテージのようなものですが、[0, 1] の範囲になります)を測定する計装器は、entity.utilization と呼ぶべきです。 たとえば、使用中のメモリの比率には system.memory.utilization を使います。
  • time - 経過時間を測定する計装器は、entity.time と呼ぶべきです。 たとえば、system.cpu.time は、idle、userなどのさまざまな値を取る state ラベルとともに使われます。
  • io - 双方向のデータフローを測定する計装器は、entity.io と呼ばれ、方向を表すラベルを持つべきです。 たとえば、system.network.io が該当します。
  • 上記の説明に当てはまらないその他の計装器は、より自由に命名してかまいません。 たとえば、system.swap.page_faultssystem.network.packets が該当します。 単位は計装器の作成時に含まれるため、名前の中で指定する必要はありませんが、曖昧さがある場合には追加してもかまいません。

内部の詳細

システム/ランタイムメトリクスを計装するライブラリでは、以下の標準的なメトリクス計装器を使用するべきです(以下の表をまとめたスプレッドシートはこちらです)。

以下の表において、単位が 1 であるものは、常に [0, 1] の範囲を取る比率の値を指します。 何かの整数カウントを測定する計装器は、packetserrorsfaults などのセマンティックな単位を使用します。

システム標準メトリクス - system.


system.cpu.

説明: システムレベルのプロセッサメトリクスです。

名前単位計装器の種類値の型ラベルキーラベル値
system.cpu.timesecondsSumObserverDoublestateidle, user, system, interrupt, etc.
CPU1 - #cores
system.cpu.utilization1UpDownSumObserverDoublestateidle, user, system, interrupt, etc.
CPU1 - #cores

system.memory.

説明: システムレベルのメモリメトリクスです。

名前単位計装器の種類値の型ラベルキーラベル値
system.memory.usagebytesUpDownSumObserverInt64stateused, free, cached, etc.
system.memory.utilization1UpDownSumObserverDoublestateused, free, cached, etc.

system.swap.

説明: システムレベルのスワップ/ページングメトリクスです。

名前単位計装器の種類値の型ラベルキーラベル値
system.swap.usagepagesUpDownSumObserverInt64stateused, free
system.swap.utilization1UpDownSumObserverDoublestateused, free
system.swap.page_faultsfaultsSumObserverInt64typemajor, minor
system.swap.page_operationsoperationsSumObserverInt64typemajor, minor
directionin, out

system.disk.

説明: システムレベルのディスクパフォーマンスメトリクスです。

名前単位計装器の種類値の型ラベルキーラベル値
system.disk.iobytesSumObserverInt64device(identifier)
directionread, write
system.disk.operationsoperationsSumObserverInt64device(identifier)
directionread, write
system.disk.timesecondsSumObserverDoubledevice(identifier)
directionread, write
system.disk.merged1SumObserverInt64device(identifier)
directionread, write

system.filesystem.

説明: システムレベルのファイルシステムメトリクスです。

名前単位計装器の種類値の型ラベルキーラベル値
system.filesystem.usagebytesUpDownSumObserverInt64device(identifier)
stateused, free, reserved
system.filesystem.utilization1UpDownSumObserverDoubledevice(identifier)
stateused, free, reserved

system.network.

説明: システムレベルのネットワークメトリクスです。

名前単位計装器の種類値の型ラベルキーラベル値
system.network.dropped_packetspacketsSumObserverInt64device(identifier)
directiontransmit, receive
system.network.packetspacketsSumObserverInt64device(identifier)
directiontransmit, receive
system.network.errorserrorsSumObserverInt64device(identifier)
directiontransmit, receive
system.network.iobytesSumObserverInt64device(identifier)
directiontransmit, receive
system.network.connectionsconnectionsUpDownSumObserverInt64device(identifier)
protocoltcp, udp, others
statee.g. for tcp

OS固有システムメトリクス - system.{os}.

特定のオペレーティングシステムに固有のシステムレベルメトリクスの計装器名には、system.{os}. というプレフィックスを付け、CPU、メモリ、ネットワークなどの各エンティティについて、上記に挙げた階層構造に従うべきです。 たとえば、Linuxのマージされたディスク操作の数をカウントする計装器(こちらこちらを参照)は、上で提案した disk という名前を再利用して、system.linux.disk.merged_operations と名付けることができます。

ランタイム標準メトリクス - runtime.


ランタイム環境は、用語、実装、そして特定のメトリクスに対する相対的な値において、大きく異なります。 たとえば、GoとPythonはどちらもガベージコレクションを行う言語ですが、2つのランタイム間でヒープ使用量を直接比較することには意味がありません。 このため、本OTEPは、トップレベルの標準ランタイムメトリクス計装器を一切提案しません。 追加の議論については、OTEP #108を参照してください。

ランタイム固有メトリクス - runtime.{environment}.

特定のランタイム環境に固有のランタイムレベルメトリクスには、runtime.{environment}. というプレフィックスを付け、セマンティック規約に概説されたセマンティック規約に従うべきです。 たとえば、Goのランタイムメトリクスは runtime.go. をプレフィックスとして使用します。

プログラミング言語の中には、実装が大きく異なる複数のランタイム環境を持つものがあります。 たとえば、Pythonには多くの実装があります。 このような言語では、曖昧さを避けるために、runtime.cpython.runtime.pypy. のような、特定の environment プレフィックスを使用することを検討してください。

未解決の疑問

  • 個々のランタイムは、仕様の中に独自の命名規約を持つべきでしょうか。
  • OS(またはOSファミリー)に固有の計装器を、曖昧さがない限りトップレベルのプレフィックスの下に含めてもよいのでしょうか。 たとえば、inode関連の計装器を命名する場合、以下のどれが好ましいでしょうか。
    1. トップレベル: system.filesystem.inodes.*
    2. UNIXファミリーレベル: system.unix.filesystem.inodes.*
    3. UNIX系OSごとに個別: system.linux.filesystem.inodes.*system.freebsd.filesystem.inodes.*system.netbsd.filesystem.inodes.* など