OpenMetrics 1.1

  • バージョン: 1.1
  • ステータス: ドラフト
  • 日付: 未定
  • 著者: Richard Hartmann, Ben Kochie, Brian Brazil, Rob Skillington

2012年に作成されたPrometheusは、2015年以降クラウドネイティブオブザーバビリティのデフォルトとなっています。Prometheusの設計の中心的な部分は、Prometheus exposition format 0.0.4と呼ばれるテキストメトリック公開フォーマットであり、2014年から安定しています。このフォーマットでは、生成、取り込み、人間による理解を容易にするために特別な配慮がなされています。2020年現在、700以上の公開されているエクスポーター、多数の未公開エクスポーター、そしてこのフォーマットを使用した何千ものネイティブライブラリ統合が存在します。さまざまなプロジェクトや企業からの多数の取り込みツールが、これを消費することをサポートしています。

OpenMetricsでは、IETFへの導入を目的として、仕様を整理・強化しています。広範かつ自発的な採用が進んでいるワーキングスタンダードを文書化しつつ、最小限の、主に後方互換性のある、よく考慮された変更を導入しています。2020年現在、多数のエクスポーター、統合、取り込みツールがOpenMetricsを使用しており、優先的にネゴシエートしています。

広範な採用とエコシステムにおける大幅な調整要件を考慮すると、Prometheus exposition format 0.0.4またはOpenMetrics 1.0への大幅な変更は範囲外と見なされます。

OpenMetrics 2.0 の開発が進行中です。Prometheus OM 2.0 ワークグループへの参加方法については、こちら を参照してください。

概要

メトリックは、テレメトリデータの特定の種類です。これらは、データのセットに対する現在の状態のスナップショットを表します。ログやイベントとは異なり、個々のイベントのレコードや情報に焦点を当てます。

OpenMetrics は主にワイヤフォーマットであり、そのフォーマットの特定のトランスポートに依存しません。このフォーマットは定期的に消費され、 successive expositions で意味を持つことが期待されます。

実装者は、指定されたプロセスまたはデバイスのドキュメント化された URL への単純な HTTP GET リクエストに応答して、メトリックを OpenMetrics テキストフォーマットで公開 **しなければなりません**。このエンドポイントは "/metrics" と呼ばれる **べき** です。実装者は、HTTP を介してオペレータが設定したエンドポイントにメトリックセットを定期的にプッシュするなど、他の方法で OpenMetrics フォーマットのメトリックを公開 **してもよい** です。

メトリックと時系列

この標準は、すべてのシステム状態を数値値として表現します。カウント、現在の値、列挙、およびブール状態が一般的な例です。メトリックとは対照的に、単一のイベントは特定の時間に発生します。メトリックは時間的にデータを集約する傾向があります。これにより情報が失われる可能性がありますが、オーバーヘッドの削減は多くの最新の監視システムで一般的に選択されるエンジニアリング上のトレードオフです。

時系列は、時間とともに変化する情報の記録です。時系列は任意の文字列またはバイナリデータをサポートできますが、この RFC の範囲内にあるのは数値データのみです。

メトリック時系列の一般的な例としては、ネットワークインターフェイスカウンター、デバイス温度、BGP 接続状態、アラート状態などがあります。

データモデル

このセクションは ABNF セクションと合わせて読む **必要があります**。両者の間に矛盾がある場合、ABNF の制限が優先 **されなければなりません**。これにより、テキストワイヤフォーマットがサポートされるため、繰り返しが削減されます。

データ型

OpenMetrics のメトリック値は、浮動小数点数または整数で **なければなりません**。取り込みツールは float64 のみサポートする **場合があります**。非実数値 NaN、+Inf、-Inf はサポート **されなければなりません**。NaN は欠損値と見なされては **なりませんが**、ゼロ除算の信号として使用 **してもよい** です。

ブール値

ブール値は 1==true0==false に従う **必要があります**。

タイムスタンプ

タイムスタンプは Unix エポック(秒単位)で **なければなりません**。負のタイムスタンプも使用 **してもよい** です。

文字列

文字列は有効な UTF-8 文字のみで構成 **されなければならず**、ゼロ長でも **よい** です。NULL (ASCII 0x0) はサポート **されなければなりません**。

ラベル

ラベルはキーと値のペアで、文字列で構成されます。

アンダースコアで始まるラベル名は **予約済み** であり、この標準で指定されていない限り使用しては **なりません**。ラベル名は ABNF セクションの制限に従う **必要があります**。

空のラベル値は、ラベルが存在しないかのように扱われる **べき** です。

LabelSet

LabelSet はラベルで構成 **されなければならず**、空でも **よい** です。ラベル名は LabelSet 内で一意で **なければなりません**。

MetricPoint

各 MetricPoint は、MetricFamily のタイプに応じて、値のセットで構成されます。

Exemplars

Exemplars は、MetricSet 外のデータへの参照です。一般的なユースケースは、プログラムトレースの ID です。

Exemplars は LabelSet と値で構成 **されなければならず**、タイムスタンプを **持ってもよい** です。これらは MetricPoints の LabelSet とタイムスタンプとそれぞれ異なる **場合があります**。

Exemplar の LabelSet のラベル名と値の合計長は、128 UTF-8 文字コードポイントを超えては **なりません**。",= のような、exemplar のテキストレンダリングにおけるその他の文字は、実装の簡便性とテキストフォーマットと proto フォーマット間の整合性のために、この制限に含まれません。

取り込みツールは Exemplars を破棄 **してもよい** です。

Metric

メトリックは、MetricFamily 内の一意の LabelSet によって定義されます。Metric は1つ以上の MetricPoints のリストを **含める必要があります**。MetricFamily ごとに同じ名前の Metric は、その LabelSet に同じラベル名のセットを持つ **べき** です。

MetricPoints に明示的なタイムスタンプを持つ **べきではありません**。

Metric に対して複数の MetricPoint が公開される場合、その MetricPoints は単調に増加するタイムスタンプを **持たなければなりません**。

MetricFamily

MetricFamily はゼロまたは複数の Metric を **持つことができます**。MetricFamily は、名前、HELP、TYPE、UNIT のメタデータを **持たなければなりません**。MetricFamily 内のすべての Metric は、一意の LabelSet を **持たなければなりません**。

名前

MetricFamily の名前は文字列で、MetricSet 内で一意で **なければなりません**。名前は snake_case である **べき** です。Metric 名は ABNF セクションの制限に従う **必要があります**。

MetricFamily 名のコロンは、MetricFamily が汎用監視システムの計算または集計の結果であることを示すために **予約済み** です。

アンダースコアで始まる MetricFamily 名は **予約済み** であり、この標準で指定されていない限り使用しては **なりません**。

接尾辞

MetricFamily の名前は、Text Format における MetricSet 内の他の MetricFamily のサンプルメトリック名と衝突する可能性がないようにする必要があります。例えば、"foo" というカウンターに対して "foo_created" というゲージがあると、テキストフォーマットでは "foo_created" が生成される可能性があります。

エクスポーターは、テキストフォーマットのサンプルメトリック名が使用する接尾辞と混同される可能性のある名前を避ける **べき** です。

  • 各タイプの接尾辞は次のとおりです。
  • カウンター: _total, _created
  • サマリー: _count, _sum, _created, `` (空)
  • ヒストグラム: _count, _sum, _bucket, _created
  • GaugeHistogram: _gcount_gsum_bucket
  • Info: _info
  • Gauge: `` (空)
  • StateSet: `` (空)
  • Unknown: `` (空)
Type

Type は MetricFamily のタイプを指定します。有効な値は "unknown"、"gauge"、"counter"、"stateset"、"info"、"histogram"、"gaugehistogram"、"summary" です。

Unit

Unit は MetricFamily の単位を指定します。空でない場合、MetricFamily 名のアンダースコアで区切られた接尾辞であるべきです。テキストフォーマットでは、さらに生成ルールによってインフィックスになる可能性があることに注意してください。

単位が MetricFamily 名の接尾辞でない場合に、エンドユーザーに直接メトリックを公開すると、メトリックの単位が何であるかについての混乱により、ユーザビリティが低下する可能性があることに注意してください。

Help

Help は文字列で、空でない **べき** です。MetricFamily の人間による消費のための簡単な説明を与えるために使用され、ツールチップとして使用できる程度に短く **すべき** です。

MetricSet

MetricSet は OpenMetrics によって公開される最上位のオブジェクトです。MetricFamilies で構成 **されなければならず**、空でも **よい** です。

各 MetricFamily 名は一意で **なければなりません**。同じラベル名と値が、MetricSet 内のすべての Metric に現れる **べきではありません**。

MetricSet 内の MetricFamily の順序に特定の要件はありません。エクスポーターは、パフォーマンスのトレードオフが理にかなっていれば、例えばアルファベット順にソートするなど、人間が読みやすいように公開 **してもよい** です。

存在する場合、「プッシュベースおよびプルベースの両方のシステムでターゲットメタデータをサポートする」セクションの「target」という名前の Info MetricFamily が最初に **べき** です。

メトリックタイプ

Gauge

ゲージは現在の測定値であり、例えば現在使用されているメモリのバイト数やキュー内のアイテム数などです。ゲージにとって、絶対値はユーザーにとって関心のあるものです。

ゲージタイプのメトリックの MetricPoint は、単一の値を持つ **必要があります**。

ゲージは時間とともに増加、減少、または一定のまま **となることがあります**。たとえ一方向にしか進まない場合でも、カウンターではなくゲージとして扱われる **ことがあります**。ログファイルのサイズは通常増加するだけで、リソースは減少する可能性があり、キューサイズの制限は一定である可能性があります。

ゲージは、多くの状態を持ち、時間とともに変化する列挙をエンコードするために使用 **してもよい** です。これは最も効率的ですが、最もユーザーフレンドリーではありません。

Counter

カウンターは離散イベントを測定します。一般的な例としては、受信した HTTP リクエストの数、CPU 秒数、送信されたバイト数などがあります。カウンターにとって、時間とともにどれだけ速く増加しているかがユーザーにとって関心のあることです。

カウンタータイプのメトリックの MetricPoint は、Total と呼ばれる1つの値を持つ **必要があります**。Total は非 NaN であり、時間とともに 0 から始まり、単調に非減少で **なければなりません**。

Counter 型の Metric における MetricPoint は、Created という Timestamp 値を持つべきです。これにより、インジェスターは新しいメトリックと、以前には見なかった長期間実行されているメトリックを区別するのに役立ちます。

Metric の Counter の Total における MetricPoint は 0 にリセットされる場合があります。その場合、対応する Created 時間もリセットのタイムスタンプに設定されなければなりません。

カウンターの Total の MetricPoint は Exemplar を持つ **ことができます**。

StateSet

StateSet は、ビットセットとも呼ばれる一連の関連するブール値を表します。ENUM をエンコードする必要がある場合、StateSet を介して行う **ことができます**。

StateSet メトリックのポイントは複数の状態を含む **ことができ**、各状態に対して1つのブール値を含む **必要があります**。状態には文字列である名前があります。

StateSet Metric の LabelSet は、MetricFamily の名前と同じ名前のラベルを持っては **なりません**。

StateSet としてエンコードされる場合、ENUM は MetricPoint 内で true のブール値が1つだけ **なければなりません**。

これは、列挙値が時間とともに変化し、状態の数が数個より多くない場合に適しています。

StateSet タイプの MetricFamily は、Unit 文字列が空で **なければなりません**。

Info

Info メトリックは、プロセスライフタイム中に変更されない **べき** テキスト情報を公開するために使用されます。一般的な例としては、アプリケーションのバージョン、リビジョン管理コミット、コンパイラのバージョンなどがあります。

Info Metric の MetricPoint は LabelSet を含みます。Info MetricPoint の LabelSet は、その Metric の LabelSet のラベル名と同じ名前のラベルを持っては **なりません**。

Info は、時間とともに変化しない ENUM をエンコードするために使用 **してもよい** です。例えば、ネットワークインターフェイスのタイプなどです。

Info タイプの MetricFamily は、Unit 文字列が空で **なければなりません**。

Histogram

ヒストグラムは離散イベントの分布を測定します。一般的な例としては、HTTP リクエストのレイテンシ、関数実行時間、または I/O リクエストサイズなどがあります。

Histogram MetricPoint は少なくとも 1 つのバケットを含まなければならず、Sum と Created の値を含むべきです。各バケットにはしきい値と値がなければなりません。

ヒストグラム MetricPoint は +Inf しきい値を持つ1つのバケットを **持たなければなりません**。バケットは累積 **しなければなりません**。例えば、秒単位のリクエストレイテンシを表すメトリックの場合、1、2、3、+Inf のしきい値を持つバケットの値は value_1 <= value_2 <= value_3 <= value_+Inf に従う **必要があります**。10 件のリクエストがそれぞれ1秒かかった場合、1、2、3、+Inf バケットの値は 10 に **ならなければなりません**。

+Inf バケットはすべてリクエストをカウントします。存在する場合、Sum 値は測定されたすべてのイベント値の合計に **等しくなければなりません**。MetricPoint 内のバケットしきい値は一意で **なければなりません**。

意味論的に、Sum およびバケットの値はカウンターであるため、NaN または負であってはなりません。負のしきい値バケットが使用される場合がありますが、その場合、Histogram MetricPoint は Sum 値を含んではなりません。なぜなら、意味論的にはもはやカウンターではなくなるからです。Bucket のしきい値は NaN であってはなりません。Count と bucket の値は整数でなければなりません。

Histogram MetricPoint は Created という Timestamp 値を持つべきです。これにより、インジェスターは新しいメトリックと、以前には見なかった長期間実行されているメトリックを区別するのに役立ちます。

ヒストグラム Metric の LabelSet は "le" ラベル名を持っては **なりません**。

バケット値は Exemplars を持つ **ことができます**。バケットは累積的であるため、監視システムはパフォーマンス/サービス拒否防止の理由で、粒度が失われるものの有効なヒストグラムである方法で +Inf 以外のバケットをドロップできます。

各バケットは、それ以下の値および/またはそれに等しい値をカバーし、Exemplar の値はこの範囲内にある **必要があります**。Exemplars は値が最も大きいバケットに入れる **べき** です。バケットは複数の Exemplar を持っては **なりません**。

GaugeHistogram

GaugeHistogram は現在の分布を測定します。一般的な例としては、キューで待機しているアイテムの数や、キュー内のリクエストのサイズなどがあります。

GaugeHistogram MetricPoint は +Inf しきい値を持つ1つのバケットを **持たなければなりません**。Gsum 値を含む **べき** です。すべてのバケットはしきい値と値を持つ **必要があります**。

GaugeHistogram のバケットは、ヒストグラムのバケットと同じルールに従います。

GaugeHistogram のバケットと Gsum は概念的にはゲージですが、バケット値は負または NaN であっては **なりません**。負のしきい値バケットが存在する場合、sum は負でも **よい** です。Gsum は NaN であっては **なりません**。バケット値は整数で **なければなりません**。

GaugeHistogram Metric の LabelSet は "le" ラベル名を持っては **なりません**。

バケット値は Exemplars を持つ **ことができます**。

各バケットは、それ以下の値および/またはそれに等しい値をカバーし、Exemplar の値はこの範囲内にある **必要があります**。Exemplars は値が最も大きいバケットに入れる **べき** です。バケットは複数の Exemplar を持っては **なりません**。

概要

Summary も離散イベントの分布を測定し、ヒストグラムが高価すぎる場合や、平均イベントサイズで十分な場合に **使用できます**。

また、一部の既存のインストルメンテーションライブラリが事前計算された分位数を公開し、ヒストグラムをサポートしていないため、後方互換性のために使用 **することもできます**。事前計算された分位数は、分位数は集計可能ではなく、ユーザーがどの期間をカバーしているかを推測できないことが多いため、使用 **すべきではありません**。

Summary MetricPoint は、Count、Sum、Created、および一連のクォンタイルで構成される場合があります。

意味論的には、Count と Sum の値はカウンターであるため、NaN または負であっては **なりません**。Count は整数で **なければなりません**。

Count または Sum 値を含む Summary 型の Metric の MetricPoint は、Created という Timestamp 値を持つべきです。これにより、インジェスターは新しいメトリックと、以前には見なかった長期間実行されているメトリックを区別するのに役立ちます。Created はクォンタイル値のコレクション期間とは関係があってはなりません。

分位数は、分位数から値へのマップです。例として、`myapp_http_request_duration_seconds` という名前のメトリックで 0.95 の分位数と値 0.2 がありますが、これは 95 パーセンタイルのレイテンシが不明な期間にわたって 200ms であることを意味します。関連期間にイベントがない場合、分位数の値は NaN で **なければなりません**。Quantile の Metric の LabelSet は "quantile" ラベル名を持っては **なりません**。Quantile は 0 から 1 の間(包括)である **必要があります**。Quantile 値は負であっては **なりません**。Quantile 値は最近の値を示す **べき** です。一般的には過去 5〜10 分間です。

Unknown

Unknown は使用 **すべきではありません**。サードパーティシステムから個々のメトリックのタイプを判別できない場合に **使用できます**。

未知のタイプのメトリックのポイントは、単一の値を持つ **必要があります**。

データ転送 & ワイヤフォーマット

テキストワイヤフォーマットはサポート **されなければならず**、デフォルトです。protobuf ワイヤフォーマットはサポート **されてもよい** ですが、ネゴシエーション後でのみ使用 **されなければなりません**。

OpenMetrics フォーマットは正規チョムスキー文法であり、高速で小さなパーサーの作成を可能にします。テキストフォーマットはよく圧縮され、protobuf はすでにバイナリで効率的にエンコードされています。

部分的または無効な公開は、全体としてエラーと見なされる **必要があります**。

プロトコルネゴシエーション

すべてのインジェスター実装は、TLS 1.2以降で保護されたデータをインジェストできる必要があります。すべてのエクスポーザーは、TLS 1.2以降で保護されたデータをエミットできる必要があります。インジェスター実装は、TLSなしでHTTPからデータをインジェストできる必要があります。すべての実装は、データを送信するためにTLSを使用する必要があります。

使用するOpenMetricsフォーマットのバージョンネゴシエーションは、帯域外で行われます。たとえば、HTTP経由のプルベースのエクスポージャーの場合、標準のHTTPコンテンツネゴシエーションが使用され、新しいバージョンが要求されない場合は、古いバージョンの標準(つまり1.0.0)にデフォルト設定する必要があります。

プッシュベースのネゴシエーションは、エクスポーザーが通常接続を開始するため、本質的に複雑です。プロデューサーは、インジェスターによって別途要求されない限り、古いバージョンの標準(つまり1.0.0)を使用する必要があります。

テキストフォーマット

ABNF

ABNF は RFC 5234 に準拠

「exposition」はABNFのトップレベルトークンです。

exposition = metricset HASH SP eof [ LF ]

metricset = *metricfamily

metricfamily = *metric-descriptor *metric

metric-descriptor = HASH SP type SP metricname SP metric-type LF
metric-descriptor =/ HASH SP help SP metricname SP escaped-string LF
metric-descriptor =/ HASH SP unit SP metricname SP *metricname-char LF

metric = *sample

metric-type = counter / gauge / histogram / gaugehistogram / stateset
metric-type =/ info / summary / unknown

sample = metricname [labels] SP number [SP timestamp] [exemplar] LF

exemplar = SP HASH SP labels SP number [SP timestamp]

labels = "{" [label *(COMMA label)] "}"

label = label-name EQ DQUOTE escaped-string DQUOTE

number = realnumber
; Case insensitive
number =/ [SIGN] ("inf" / "infinity")
number =/ "nan"

timestamp = realnumber

; Not 100% sure this captures all float corner cases.
; Leading 0s explicitly okay
realnumber = [SIGN] 1*DIGIT
realnumber =/ [SIGN] 1*DIGIT ["." *DIGIT] [ "e" [SIGN] 1*DIGIT ]
realnumber =/ [SIGN] *DIGIT "." 1*DIGIT [ "e" [SIGN] 1*DIGIT ]


; RFC 5234 is case insensitive.
; Uppercase
eof = %d69.79.70
type = %d84.89.80.69
help = %d72.69.76.80
unit = %d85.78.73.84
; Lowercase
counter = %d99.111.117.110.116.101.114
gauge = %d103.97.117.103.101
histogram = %d104.105.115.116.111.103.114.97.109
gaugehistogram = gauge histogram
stateset = %d115.116.97.116.101.115.101.116
info = %d105.110.102.111
summary = %d115.117.109.109.97.114.121
unknown = %d117.110.107.110.111.119.110

BS = "\"
EQ = "="
COMMA = ","
HASH = "#"
SIGN = "-" / "+"

metricname = metricname-initial-char 0*metricname-char

metricname-char = metricname-initial-char / DIGIT
metricname-initial-char = ALPHA / "_" / ":"

label-name = label-name-initial-char *label-name-char

label-name-char = label-name-initial-char / DIGIT
label-name-initial-char = ALPHA / "_"

escaped-string = *escaped-char

escaped-char = normal-char
escaped-char =/ BS ("n" / DQUOTE / BS)
escaped-char =/ BS normal-char

; Any unicode character, except newline, double quote, and backslash
normal-char = %x00-09 / %x0B-21 / %x23-5B / %x5D-D7FF / %xE000-10FFFF

全体構造

UTF-8を使用する必要があります。バイトオーダーマーク(BOM)は使用してはいけません。実装者への重要な注意として、バイト0は有効なUTF-8ですが、たとえばバイト255はそうではありません。

コンテンツタイプは次のとおりである必要があります

application/openmetrics-text; version=1.0.0; charset=utf-8

行末はラインフィード(\n)で示す必要があり、キャリッジリターン(\r)を含んではいけません。エクスポージャーはEOFで終了する必要があり、EOF\nで終了することが推奨されます。

完全なエクスポージャーの例

# TYPE acme_http_router_request_seconds summary
# UNIT acme_http_router_request_seconds seconds
# HELP acme_http_router_request_seconds Latency though all of ACME's HTTP request router.
acme_http_router_request_seconds_sum{path="/api/v1",method="GET"} 9036.32
acme_http_router_request_seconds_count{path="/api/v1",method="GET"} 807283.0
acme_http_router_request_seconds_created{path="/api/v1",method="GET"} 1605281325.0
acme_http_router_request_seconds_sum{path="/api/v2",method="POST"} 479.3
acme_http_router_request_seconds_count{path="/api/v2",method="POST"} 34.0
acme_http_router_request_seconds_created{path="/api/v2",method="POST"} 1605281325.0
# TYPE go_goroutines gauge
# HELP go_goroutines Number of goroutines that currently exist.
go_goroutines 69
# TYPE process_cpu_seconds counter
# UNIT process_cpu_seconds seconds
# HELP process_cpu_seconds Total user and system CPU time spent in seconds.
process_cpu_seconds_total 4.20072246e+06
# EOF
エスケープ

ABNFがエスケープを注記している場所では、次のエスケープを適用する必要があります。ラインフィード、\n(0x0A)->リテラル\\n(バイトコード0x5c 0x6e)、二重引用符->\\"(バイトコード0x5c 0x22)、バックスラッシュ->\\\\(バイトコード0x5c 0x5c)。

バックスラッシュ文字を表すために二重バックスラッシュを使用することが推奨されます。未定義のエスケープシーケンスには単一バックスラッシュを使用しないでください。例として、\\\\a\\aと同等であり、好ましいです。

数値

整数は小数点を持ってはいけません。例は2300421341298465647914です。

浮動小数点数は、小数点を持つか、科学表記法を使用して表す必要があります。例は8903.123421および1.89e-7です。浮動小数点数は、IEEE 754で定義された64ビット浮動小数点値の範囲に収まる必要がありますが、マンティサに多くのビットが必要なため、精度が失われる可能性があります。これはナノ秒解像度のタイムスタンプをエンコードするために使用される場合があります。

「quantile」および「le」ラベル値(「Canonical Numbers」セクション参照)では、任意整数および浮動小数点数のレンダリングを使用することはできません。数値が使用される他の場所ではすべて使用できます。

考慮事項:標準的な数値

ヒストグラムの「le」ラベル値およびサマリーメトリックの「quantile」ラベル値の数値は、それらがラベル値であり、ラベル値は不透明であることを意図しているため、特別です。エンドユーザーはこれらの文字列値と直接やり取りする可能性が高く、多くの監視システムはそれらをファーストクラスの数値として扱う能力が欠けているため、特定の数値が正確に同じテキスト表現を持つと有益です。

一貫性は非常に望ましいですが、現実世界の言語とランタイムの実装では、これを強制することは非現実的です。最も重要な共通のクォンタイルは0.5、0.95、0.9、0.99、0.999であり、バケット値はミリ秒から10.0秒までの値を表します。これは、典型的なWebサービスのレイテンシSLAやApdexなどのケースをカバーするためです。10の累乗は、ランタイムによって異なる固定小数点と指数表記のレンダリング間の切り替えが整合していることを確認するためにカバーされます。ターゲットレンダリングは、float64値のデフォルトのGoレンダリング(つまり%g)と同等であり、小数点または指数がない場合は.0が追加され、浮動小数点であることが明確になります。

エクスポーザーは、正の無限大を+Infとして出力する必要があります。

エクスポーザーは、0.0から10.0までの値を0.001刻みで、次の例に従って出力することが推奨されます:0.0 0.001 0.002 0.01 0.1 0.9 0.95 0.99 0.999 1.0 1.7 10.0

エクスポーザーは、1e-10から1e+10までの値を10の累乗で、次の例に従って出力することが推奨されます:1e-10 1e-09 1e-05 0.0001 0.1 1.0 100000.0 1e+06 1e+10

パーサーは、標準値から外れた入力を、標準値と一致しないという理由だけで拒否してはいけません。たとえば、1.1e-4は0.00011の一貫したレンダリングではないにもかかわらず、拒否してはいけません。

エクスポーザーは、標準外の数値に対してこれらのパターンに従うことが推奨されており、レンダリングアルゴリズムをこれらの値に対して一貫性のあるものに調整することで、他のほとんどの値も一貫したレンダリングになるという意図があります。少数の特定のle/quantile値のみを使用するエクスポーザーは、ハードコーディングすることもできます。Grisu3のような最小の浮動小数点レンダリングアルゴリズムが容易に利用できないCのような言語では、エクスポーザーは異なるレンダリングを使用してもかまいません。

Cやprintf実装を共有する他の言語の実装者への警告:%f、%e、%gの標準精度は6桁のみです。完全な精度には17桁が必要です。例:printf("%.17g", d)

タイムスタンプ

ナノ秒精度が必要な場合、タイムスタンプで指数浮動小数点レンダリングを使用しないでください。float64のレンダリングには十分な精度がありません。例:1604676851.123456789

MetricFamily

MetricFamilyの間に明示的な区切り文字があってはいけません。次のMetricFamilyは、メタデータまたは前のMetricFamilyの一部ではない新しいサンプルメトリック名で示す必要があります。

MetricFamiliesをインターリーブしてはいけません。

MetricFamilyメタデータ

メタデータには4つの要素があります:MetricFamily名、TYPE、UNIT、およびHELP。fooという名前のカウンターMetricのメタデータの例は次のとおりです。

# TYPE foo counter

TYPEが公開されていない場合、MetricFamilyはUnknownタイプである必要があります。

単位が指定されている場合、UNIT メタデータ行で提供されなければなりません。さらに、アンダースコアと単位は MetricFamily 名の接尾辞であるべきです。

単位が「seconds」であるfoo_secondsメトリックの有効な例

# TYPE foo_seconds counter
# UNIT foo_seconds seconds

単位が名前に接尾辞としてない、有効だが非推奨の例

# TYPE foo counter
# UNIT foo seconds

次のような場合も有効です。

# TYPE foo_seconds counter

単位がわかっている場合は、提供する必要があります。

UNITまたはHELP行の値は空にすることができます。これは、MetricFamilyのメタデータ行が存在しないかのように扱われます。

# TYPE foo_seconds counter
# UNIT foo_seconds seconds
# HELP foo_seconds Some text and \n some \" escaping

MetricFamilyごとに、各タイプのメタデータ行は1つだけ存在する必要があります。順序はTYPE、UNIT、HELPであることが推奨されます。

このメタデータとメッセージ末尾のEOF行を除き、#で始まる行を公開してはいけません。

Metric

Metricをインターリーブしてはいけません。

「Text format -> MetricPoint」の例を参照してください。ラベルがない、またはタイムスタンプがないサンプルの値が0の場合、次のようにレンダリングする必要があります。

bar_seconds_count 0

または次のように

bar_seconds_count{} 0

ラベル値は有効なUTF-8値であれば何でもかまいません。そのため、ABNFに従ってエスケープを適用する必要があります。2つのラベルを持つ有効な例

bar_seconds_count{a="x",b="escaping\" example \n "} 0

MetricPointの値のレンダリングには、追加のラベル(例:Histogramタイプの「le」ラベル)を含めることができます。これは、Metric自体のLabelSetと同じ方法でレンダリングする必要があります。

MetricPoint

MetricPointsをインターリーブしてはいけません。

MetricFamily内に複数のMetricPointsとSamplesがあった場合の正しい例

# TYPE foo_seconds summary
# UNIT foo_seconds seconds
foo_seconds_count{a="bb"} 0 123
foo_seconds_sum{a="bb"} 0 123
foo_seconds_count{a="bb"} 0 456
foo_seconds_sum{a="bb"} 0 456
foo_seconds_count{a="ccc"} 0 123
foo_seconds_sum{a="ccc"} 0 123
foo_seconds_count{a="ccc"} 0 456
foo_seconds_sum{a="ccc"} 0 456

Metricがインターリーブされている無効な例

# TYPE foo_seconds summary
# UNIT foo_seconds seconds
foo_seconds_count{a="bb"} 0 123
foo_seconds_count{a="ccc"} 0 123
foo_seconds_count{a="bb"} 0 456
foo_seconds_count{a="ccc"} 0 456

MetricPointsがインターリーブされている無効な例

# TYPE foo_seconds summary
# UNIT foo_seconds seconds
foo_seconds_count{a="bb"} 0 123
foo_seconds_count{a="bb"} 0 456
foo_seconds_sum{a="bb"} 0 123
foo_seconds_sum{a="bb"} 0 456

Metricタイプ

Gauge

GaugeタイプのMetricFamilyのMetricPointの値のSample MetricNameには、接尾辞があってはいけません。

ラベルのないMetricとタイムスタンプのないMetricPointを持つMetricFamilyの例

# TYPE foo gauge
foo 17.0

ラベルを持つ2つのMetricとタイムスタンプのないMetricPointを持つMetricFamilyの例

# TYPE foo gauge
foo{a="bb"} 17.0
foo{a="ccc"} 17.0

MetricのないMetricFamilyの例

# TYPE foo gauge

ラベルを持つMetricとタイムスタンプのあるMetricPointの例

# TYPE foo gauge
foo{a="b"} 17.0 1520879607.789

ラベルのないMetricとタイムスタンプのあるMetricPointの例

# TYPE foo gauge
foo 17.0 1520879607.789

ラベルのないMetricとタイムスタンプのある2つのMetricPointの例

# TYPE foo gauge
foo 17.0 123
foo 18.0 456
Counter

MetricPoint の Total Value Sample MetricName は _total という接尾辞を持つべきです。存在する場合、MetricPoint の Created Value Sample MetricName は _created という接尾辞を持たなければなりません。

_total が MetricFamily 名の接尾辞でない場合に、メトリックをエンドユーザーに直接公開すると、メトリックのタイプについての混乱により、ユーザビリティが低下する可能性があることに注意してください。

ラベルのないメトリックと、タイムスタンプも作成も持たない MetricPoint の例

# TYPE foo counter
foo_total 17.0

ラベルのないメトリックと、タイムスタンプはあり作成がない MetricPoint の例

# TYPE foo counter
foo_total 17.0 1520879607.789

ラベルのないメトリックと、タイムスタンプはなく作成がある MetricPoint の例

# TYPE foo counter
foo_total 17.0
foo_created 1520430000.123

ラベルのないメトリックと、タイムスタンプと作成がある MetricPoint の例

# TYPE foo counter
foo_total 17.0 1520879607.789
foo_created 1520430000.123 1520879607.789

ラベルのないメトリックと、_total 接尾辞がなく、タイムスタンプと作成がある MetricPoint の例

# TYPE foo counter
foo 17.0 1520879607.789
foo_created 1520430000.123 1520879607.789

ExemplarsはMetricPointのTotalサンプルに添付される場合があります。

StateSet

StateSetタイプのMetricFamilyのMetricPointの値のSample MetricNameには、接尾辞があってはいけません。

StateSetsは、MetricPointごとに1つのサンプルを持つ必要があります。各Stateのサンプルには、MetricFamily名をラベル名とし、State名をラベル値とするラベルが必要です。Stateサンプルの値は、Stateがtrueの場合は1、falseの場合は0である必要があります。

状態「a」、「bb」、「ccc」があり、そのうちbbのみが有効で、メトリック名はfooである例

# TYPE foo stateset
foo{foo="a"} 0
foo{foo="bb"} 1
foo{foo="ccc"} 0

Metric上の「entity」ラベルの例

# TYPE foo stateset
foo{entity="controller",foo="a"} 1.0
foo{entity="controller",foo="bb"} 0.0
foo{entity="controller",foo="ccc"} 0.0
foo{entity="replica",foo="a"} 1.0
foo{entity="replica",foo="bb"} 0.0
foo{entity="replica",foo="ccc"} 1.0
Info

InfoタイプのMetricFamilyのMetricPointの値のSample MetricNameには_infoという接尾辞が必要です。Sample値は常に1である必要があります。

ラベルのないMetricと、「name」および「version」ラベルを持つMetricPoint値を持つMetricの例

# TYPE foo info
foo_info{name="pretty name",version="8.2.7"} 1

ラベル「entity」を持つMetricと、「name」および「version」ラベルを持つMetricPoint値を持つMetricの例

# TYPE foo info
foo_info{entity="controller",name="pretty name",version="8.2.7"} 1.0
foo_info{entity="replica",name="prettier name",version="8.1.9"} 1.0

MetricラベルとMetricPoint値ラベルは任意の順序でかまいません。

概要

存在する場合、MetricPoint の Sum Value Sample MetricName は _sum という接尾辞を持たなければなりません。存在する場合、MetricPoint の Count Value Sample MetricName は _count という接尾辞を持たなければなりません。存在する場合、MetricPoint の Created Value Sample MetricName は _created という接尾辞を持たなければなりません。存在する場合、MetricPoint の Quantile Values は、"quantile" というラベル名と、測定されたクォンタイルの値を持つラベルを使用して、測定されたクォンタイルを指定しなければなりません。

ラベルのないメトリックと、Sum、Count、Created 値を持つ MetricPoint の例

# TYPE foo summary
foo_count 17.0
foo_sum 324789.3
foo_created 1520430000.123

ラベルのないメトリックと、2 つのクォンタイルを持つ MetricPoint の例

# TYPE foo summary
foo{quantile="0.95"} 123.7
foo{quantile="0.99"} 150.0

クォンタイルは任意の順序でかまいません。

Histogram

MetricPoint の Bucket Values Sample MetricNames は _bucket という接尾辞を持つべきです。存在する場合、MetricPoint の Sum Value Sample MetricName は _sum という接尾辞を持たなければなりません。存在する場合、MetricPoint の Created Value Sample MetricName は _created という接尾辞を持たなければなりません。Sum Value が MetricPoint に存在する場合にのみ、MetricPoint の +Inf Bucket 値は "_count" という接尾辞を持つ MetricName の Sample で表示されなければなりません。

Bucketsは「le」の数値増加順にソートする必要があり、「le」ラベルの値はCanonical Numbersのルールに従う必要があります。

ラベルのないメトリックと、Sum、Count、Created 値、および 12 個のバケットを持つ MetricPoint の例。意図的に、広範囲で非典型的な、しかし有効な "le" 値のバリエーションを示しています。

# TYPE foo histogram
foo_bucket{le="0.0"} 0
foo_bucket{le="1e-05"} 0
foo_bucket{le="0.0001"} 5
foo_bucket{le="0.1"} 8
foo_bucket{le="1.0"} 10
foo_bucket{le="10.0"} 11
foo_bucket{le="100000.0"} 11
foo_bucket{le="1e+06"} 15
foo_bucket{le="1e+23"} 16
foo_bucket{le="1.1e+23"} 17
foo_bucket{le="+Inf"} 17
foo_count 17
foo_sum 324789.3
foo_created 1520430000.123
Exemplars

ラベルのないExemplarsは、空のLabelSetを{}として表す必要があります。

いくつかの有効なケースを示すExemplarsの例:0.01バケットにはExemplarがありません。0.1バケットにはラベルのないExemplarがあります。1バケットには1つのラベルを持つExemplarがあります。10バケットにはラベルとタイムスタンプを持つExemplarがあります。実際には、すべてのバケットは同じスタイルのExemplarsを持つべきです。

# TYPE foo histogram
foo_bucket{le="0.01"} 0
foo_bucket{le="0.1"} 8 # {} 0.054
foo_bucket{le="1"} 11 # {trace_id="KOO5S4vxi0o"} 0.67
foo_bucket{le="10"} 17 # {trace_id="oHg5SJYRHA0"} 9.8 1520879607.789
foo_bucket{le="+Inf"} 17
foo_count 17
foo_sum 324789.3
foo_created 1520430000.123
GaugeHistogram

MetricPointのBucket Values Sample MetricNamesには_bucketという接尾辞が必要です。存在する場合、MetricPointのSum Value Sample MetricNameには_gsumという接尾辞が必要です。MetricPointにSum Valueが存在する場合のみ、MetricPointの+Inf Bucket値は、接尾辞_gcountを持つMetricNameのサンプルとしても出現する必要があります。

Bucketsは「le」の数値増加順にソートする必要があり、「le」ラベルの値はCanonical Numbersのルールに従う必要があります。

ラベルのないMetricと、ExemplarのないMetricPoint値を持つMetricの例(バケットにExemplarなし)

# TYPE foo gaugehistogram
foo_bucket{le="0.01"} 20.0
foo_bucket{le="0.1"} 25.0
foo_bucket{le="1"} 34.0
foo_bucket{le="10"} 34.0
foo_bucket{le="+Inf"} 42.0
foo_gcount 42.0
foo_gsum 3289.3
Unknown

UnknownタイプのMetricFamilyのMetricPointの値のSample MetricNameには、接尾辞があってはいけません。

ラベルのないMetricとタイムスタンプのないMetricPointの例

# TYPE foo unknown
foo 42.23

Protobufフォーマット

全体構造

Protobufメッセージはバイナリでエンコードする必要があり、コンテンツタイプはapplication/openmetrics-protobuf; version=1.0.0である必要があります。

すべてのペイロードは、OpenMetrics protobufスキーマで定義された単一のバイナリエンコードされたMetricSetメッセージである必要があります。

バージョン

protobufフォーマットは、protocol buffer言語のproto3バージョンに従う必要があります。

文字列

すべての文字列フィールドはUTF-8でエンコードする必要があります。

タイムスタンプ

OpenMetrics protobufスキーマのタイムスタンプ表現は、公開されているgoogle.protobuf.Timestamp [timestamp]メッセージに従う必要があります。タイムスタンプメッセージは、int64としてのUnixエポック秒と、secondsタイムスタンプコンポーネントからの非負の秒の小数部分(int32、ナノ秒解像度)である必要があります。これは0から999,999,999までを含む必要があります。

Protobufスキーマ

Protobufスキーマは、こちらから入手できます。

Prometheus およびエコシステムは OpenMetrics protobuf スキーマをサポートしていません。代わりに、類似の io.prometheus.client フォーマット を使用しています。OpenMetrics 2.0 の protobuf スキーマの将来に関する議論は進行中です

設計上の考慮事項

スコープ

OpenMetricsは、オンラインシステムのテレメトリを提供することを目的としています。リアルタイムの保証を提供しないプロトコル上で実行されるため、それ自体はリアルタイムの保証を提供できません。OpenMetricsのレイテンシとジッターの特性は、基盤となるネットワーク、オペレーティングシステム、CPUなどの不正確さと同じくらい不正確です。意思決定の基礎として集計に使用するには十分正確ですが、個々のイベントを反映するには不十分です。

あらゆるサイズのシステムをサポートする必要があります。1時間に数回の要求しか受信しないアプリケーションから、400Gbネットワークポートの監視帯域幅使用量まで。転送されたテレメトリの集計と分析は、任意の期間で可能である必要があります。

データ転送時の状態のスナップショットを定期的に転送することを意図しています。

範囲外

インジェスターがエクスポーザーの存在をどのように検出し、その逆も同様かは、この標準では範囲外であり、定義されていません。

拡張機能と改善

OpenMetricsのこの最初のバージョンは、確立された事実上の標準であるPrometheusテキストフォーマット0.0.4に基づいており、主要な構文的または意味論的な拡張や最適化を追加していません。たとえば、Histogramバケットのテキスト表現をよりコンパクトにする試みは行われておらず、その繰り返し性を処理するために基盤となるスタックの圧縮に依存しています。

これは意図的な選択であり、標準が既存のユーザーベースの採用と勢いから恩恵を受けられるようにするためです。これにより、Prometheusテキストフォーマット0.0.4からの比較的簡単な移行が保証されます。

また、実装が容易な基本的な標準が存在することも保証されます。これは、将来の標準バージョンで構築される可能性があります。将来の標準バージョンは、構文的および意味論的に、常にこの1.0バージョンをサポートする必要があるという意図があります。

監視システムが過度の負担なしに、OpenMetricsエクスポージャーから有用な情報を取得できるようにしたいと考えています。メタデータと構造をすべて剥ぎ取り、単にサンプルを順序付けされていないセットとして見ると、それ自体で有用であるべきです。そのため、カスタム解析と処理が必要になるスケッチやt-digestのような不透明なバイナリ型もありません。

この原則は、標準全体に一貫して適用されています。たとえば、MetricFamilyの単位は名前に複製されているため、単位メタファイルを理解しないシステムでも単位を利用できます。「le」ラベルは特別な構文ではなく、通常のラベル値です。これにより、インジェスターはそれらをインジェストするために特別なヒストグラム処理コードを追加する必要がなくなります。さらに例として、複合データ型はありません。たとえば、緯度/経度のジオロケーションタイプはありません。これは、個別のゲージメトリックで実行できます。

単位と基本単位

システム全体の一貫性を保ち、混乱を避けるために、単位は主にSI基本単位に基づいています。基本単位には、秒、バイト、ジュール、グラム、メートル、比率、ボルト、アンペア、摂氏が含まれます。適用可能な場合は、単位を提供する必要があります。

たとえば、すべての期間メトリックを秒単位にすると、指定されたメトリックがナノ秒、マイクロ秒、ミリ秒、秒、分、時間、日、または週のいずれであるかを推測する必要がなくなり、混合単位を処理する必要もなくなります。プレフィックスのない単位を選択することで、キロミリ秒が複雑なシステムの出現的振る舞いの結果であったような状況を回避できます。

値は浮動小数点数である可能性があるため、基本単位未満の精度が標準に組み込まれています。

同様に、ビットとバイトの混在は混乱を招くため、バイトが基本単位として選択されています。ケルビンは理論的にはより良い基本単位ですが、実際にはほとんどの既存のハードウェアは摂氏を公開しています。キログラムはSI基本単位ですが、キロプレフィックスは問題があるため、グラムが基本単位として選択されています。

基本単位は可能な限りすべて使用されるべきですが、ケルビンは、色や黒体温度などの用途では摂氏の代わりに、摂氏とケルビンのメトリックの比較が可能性が低い場合に、確立された単位です。

比率が基本単位であり、パーセンテージではありません。可能な場合は、指定された分子と分母のゲージまたはカウンターの形式で生のデータが公開されるべきです。これにより、インジェスターでの分析と集計のための数学的プロパティが向上します。

デシベルは基本単位ではありません。第一に、デシはSIプレフィックスであり、第二に、ベルは対数的です。信号/エネルギー/電力比を公開する場合、比率を直接公開する方が良いでしょう。可能であれば、生の電力/エネルギーを公開する方がさらに良いでしょう。浮動小数点指数は、極端な科学的使用でも十分です。電子ボルト(約1e-19 J)から超新星の放出エネルギー(約1e44 J)まで、63桁のオーダーであり、64ビット浮動小数点数は2000桁以上のオーダーをカバーできます。

非基本単位が避けられず、変換が不可能な場合は、単位はメトリック名に含める必要があります。たとえば、ジュールはエネルギーと電力の両方の基本単位であり、ワットはジュール単位のカウンターとして表現できます。実際には、特定のサードパーティシステムはワットしか公開しない場合があるため、その場合、ワットで表されるゲージが唯一の現実的な選択肢となります。

すべてのMetricFamilyに単位があるわけではありません。たとえば、HTTP要求のカウントには単位がありません。技術的には、単位はHTTP要求になりますが、その意味ではMetricFamily名全体が単位です。そこまで極端にすることは有用ではありません。下流システムでグラフに良い軸を持つ可能性を常に念頭に置くべきです。

ステートレス性

OpenMetricsで定義されたワイヤーフォーマットは、エクスポージャー間でステートレスです。以前に公開された情報は、将来のエクスポージャーに影響を与えない必要があります。各エクスポージャーは、エクスポーザーの現在の状態の自己完結型スナップショットです。

同じ自己完結型エクスポージャーが、既存および新規のインジェスターに提供される必要があります。

エクスポーザーが最近変更または観測されなかったという理由だけでメトリックを排除してはいけない、というのがコア設計上の選択です。エクスポーザーは、インジェスターがエクスポージャーをどのくらいの頻度で消費するかについて、いかなる仮定もしてはいけません。

時間とメトリックの進化をまたぐエクスポージャー

メトリックの時間の経過に伴う進化を分析できる場合に最も有用であるため、エクスポージャーは時間の経過とともに意味をなす必要があります。したがって、単一のエクスポージャーだけでは有用で有効であることは十分ではありません。メトリックの意味論への一部の変更は、下流のユーザーを壊す可能性もあります。

パーサーは通常、以前の結果をキャッシュすることで最適化します。したがって、エクスポージャー間でラベルの公開順序を変更することは、技術的には壊れていないとしても避けるべきです。これはまた、エクスポージャーの単体テストを容易にする傾向があります。

メトリックとサンプルは、エクスポージャーからエクスポージャーへ出現したり消えたりしてはいけません。たとえば、カウンターは履歴がないと有用ではありません。原則として、特定のメトリックはプロセスが開始してから終了するまでエクスポージャーに存在する必要があります。特定のプロセスのライフタイム中にMetricFamilyがどのようなメトリックを持つかを事前に知ることはしばしば不可能ですが(たとえば、レイテンシヒストグラムのラベル値はHTTPパスであり、実行時にエンドユーザーによって提供されます)、カウンターのようなメトリックが公開されると、プロセスが終了するまで公開され続ける必要があります。カウンターが増加していないことは、現在の値がないことを無効にするものではありません。特定のメトリックの公開を停止することが理にかなっている場合があります。欠損データセクションを参照してください。

一般的に、MetricFamilyのタイプを変更したり、Metricにラベルを追加または削除したりすると、インジェスターに問題が発生します。

例外として、Info MetricPointsの値にラベルを追加することは壊れるものではありません。これは、追加のラベル値を持つ新しいinfomertricを作成することを強制されるのではなく、既存のInfo MetricFamilyに追加情報を含めることができるためです。インジェスターシステムは、そのような追加に対して回復力があることを保証する必要があります。

MetricFamilyのHelpを変更しても壊れることはありません。値が可能な場合、floatとintの間で切り替えても壊れることはありません。statesetに新しい状態を追加しても壊れることはありません。メトリック名に影響しない単位メタデータを追加しても壊れることはありません。

Histogramバケットはエクスポージャーからエクスポージャーへ変更しないようにすべきです。これはパフォーマンスの問題を引き起こし、インジェスターを壊す可能性が高いためです。同様に、アプリケーションの一貫したバイナリと環境からのすべてのエクスポージャーは、特定のHistogram MetricFamilyに対して同じバケットを持つべきです。これにより、インジェスターが異種バケットのマージロジックを実装する必要なしに、すべてのインジェスターによって集計できます。例外は、壊れると見なされる可能性のあるバケットの偶発的な手動変更ですが、新しいソフトウェアリリースによるパフォーマンス特性の変化に対しては妥当なトレードオフになる場合があります。

変更が技術的に壊れていない場合でも、コストがかかります。たとえば、頻繁な変更はインジェスターにパフォーマンスの問題を引き起こす可能性があります。エクスポージャーごとに異なるHelp文字列は、各Help値の保存を必要とする可能性があります。intとfloat値の頻繁な切り替えは、効率的な圧縮を妨げる可能性があります。

NaN

NaNはOpenMetricsの他の数値と同じように扱われ、通常はゼロ除算の結果として発生します(たとえば、最近観測がない場合のSummaryクォンタイル)。NaNはOpenMetricsでは特別な意味を持たず、特に欠損データやその他の不正なデータをマークするために使用してはいけません。

欠損データ

データが存在しなくなる正当なケースがあります。たとえば、ファイルシステムがアンマウントされると、空きディスク容量のGauge Metricは存在しなくなります。この状況に対する特別なマーカーやシグナルはありません。後続のエクスポージャーでは、このMetricは単に含まれなくなります。

エクスポージャーパフォーマンス

メトリックは、合理的な時間枠で収集できない場合、有用ではありません。数分かかるエクスポージャーは有用とは見なされません。

経験則として、エクスポージャーは1秒を超えないようにする必要があります。

レガシーシステムからのメトリックをOpenMetrics経由でシリアル化すると、時間がかかる場合があります。このため、ハードなパフォーマンスの仮定はできません。

エクスポージャーは最新の状態であるべきです。たとえば、エクスポージャーリクエストを処理するスレッドは、キャッシュをバイパスできる限り、キャッシュされた値に依存すべきではありません。

並行性

高可用性とアドホックアクセスには、複数のインジェスターを持つことが一般的です。これをサポートするには、同時エクスポージャーをサポートする必要があります。すべてのBCP(ベストプラクティス)は、同時システムに適用されるべきです。一般的な落とし穴には、デッドロック、競合状態、およびエクスポージャーの同時進行を妨げる過度に粗い粒度のロックなどがあります。

メトリック命名と名前空間

理解しやすさ、衝突の回避、およびメトリック名とラベル名の簡潔さのバランスを目指します。名前はアンダースコアで区切られるため、メトリック名は「snake_case」になります。

例として、「http_request_seconds」は簡潔ですが、多数のアプリケーション間で衝突し、このメトリックが正確に何を測定しているのかも不明瞭です。たとえば、複雑なシステムでは認証ミドルウェアの前か後かです。

メトリック名は、どのコード片から来ているかを示す必要があります。たとえば、「A Company Manufacturing Everything」という会社は、コード内のすべてのメトリックに「acme_」をプレフィックスとして付け、HTTPルーターライブラリがレイテンシを測定している場合、「acme_http_router_request_seconds」のようなメトリックと、それが全体的なレイテンシであることを示すHelp文字列を持つ可能性があります。

すべてのアプリケーション全体での衝突をすべて防ぐことは目的ではありません。それは、グローバルなメトリック名前空間レジストリやDNSベースの非常に長い名前空間のような、厳格な解決策を必要とするためです。むしろ、軽量な非公式なアプローチに留めることが目的であり、特定のアプリケーションでは、その構成ライブラリ間で衝突が発生する可能性は非常に低いものです。

監視システムの全体的なデプロイメント全体では、同じメトリック名が異なる意味を持つ衝突はまれであることが目的です。たとえば、acme_http_router_request_secondsは、A Company Manufacturing Everythingによって開発された数百の異なるアプリケーションに含まれる可能性があります。これは正常です。Another Corporation Making EntitiesもHTTPルーターでacme_http_router_request_secondsメトリック名を使用したとしても、それは問題ありません。両社のアプリケーションが同じ監視システムで監視されている場合、衝突は望ましくありませんが、どちらのアプリケーションも両方の名前を公開しようとしておらず、単一のターゲットが同じメトリック名を(誤って)2回公開しようとしていないため、許容されます。アプリケーションがMy Example CompanyのHTTPルーターライブラリとMega Exciting CompanyのHTTPルーターライブラリの両方を含めたい場合、それは問題であり、メトリック名のいずれかを変更する必要があります。

したがって、ライブラリが公開されるほど、そのメトリック名は、そのようなシナリオが発生するリスクを減らすために、より適切に名前空間化されるべきです。acme_は、会社内での内部使用には悪い選択ではありませんが、これらの会社はたとえば、社外で共有されるコードにacmeverything_またはacorpme_というプレフィックスを選択するかもしれません。

会社または組織による名前空間化の後、ライブラリ/サブシステム/アプリケーションごとに必要に応じて名前空間化と命名をフラクタルに進めることができます(上記のhttp_routerライブラリなど)。目標は、コードベースの全体構造に精通している場合、メトリック名から特定のメトリックのインストルメンテーションがどこにあるかを推測できることです。

一般的に非常に有名な既存のソフトウェアの場合、ソフトウェア自体の名前が十分に識別可能である場合があります。たとえば、bind_はDNSソフトウェアには十分ですが、isc_bind_がより一般的な命名法になるでしょう。

scrape_で始まるメトリック名は、インジェスターが個々のエクスポージャーに関連する情報をアタッチするために使用するため、アプリケーションが直接公開すべきではありません。すでに消費され、汎用監視システムを通過したメトリックは、後続のエクスポージャーでそのようなメトリック名を含む場合があります。エクスポーザーが個々のエクスポージャーに関する情報を提供したい場合、myexposer_scrape_のようなメトリックプレフィックスを使用できます。一般的な例は、エクスポージャーの観点からそのエクスポージャーにかかった時間を示すゲージmyexposer_scrape_duration_secondsです。

Prometheusエコシステム内では、process_で始まるプロセスごとのメトリックのセットが、すべての実装で一貫して出現しています。たとえば、開いているファイルulimitの場合、MetricFamilies process_open_fdsとprocess_max_fdsゲージは、現在の値と最大値の両方を提供します。(これらの名前はレガシーであり、今日そのようなメトリックが定義された場合、process_fds_openとprocess_fds_limitと呼ばれる可能性が高いでしょう)。一般的に、同様のセマンティクスを持つ名前を取得するのは非常に困難です。そのため、異なるインストルメンテーションは異なる名前を使用すべきです。

メトリック名における冗長性を避けてください。「metric」、「timer」、「stats」、「counter」、「total」、「float64」などのサブ文字列を避けてください。OpenMetrics経由で公開される指定されたタイプ(および場合によっては単位)を持つメトリックであるという事実により、これらの情報はすでに暗示されているため、明示的に含めるべきではありません。同じ理由で、メトリックのラベル名をメトリック名に含めるべきではありません。さらに、監視システムによる後続の集計は、そのような情報を不正確にする可能性があります。

監視システムの他のレイヤーの実装詳細をメトリック名に含めないでください。たとえば、MetricFamily名に「openmetrics」という文字列を含めないでください。それは現在OpenMetrics経由でどこかで公開されているからという理由だけで、または現在の監視システムがPrometheusであるという理由だけで「prometheus」という文字列を含めないでください。

ラベル名前空間

ラベル名については、会社またはライブラリによる明示的な名前空間化は推奨されません。メトリック名からの名前空間化は、ラベル名の長さの増加を考慮すると十分です。ただし、一般的な衝突を避けるために、最小限の注意を払うことが推奨されます。

region、zone、cluster、availability_zone、az、datacenter、dc、owner、customer、stage、service、team、job、instance、environment、envなどのラベル名は、汎用監視システムが追加する可能性のあるターゲットを識別するために使用されるラベルと衝突する可能性が非常に高いです。それらを避けるようにし、これらのケースでは最小限の名前空間化を追加することが適切かもしれません。

ラベル名「type」は非常に一般的であり、避けるべきです。たとえば、HTTP関連のメトリックの場合、GET、POST、PUTリクエストを区別する場合、「method」の方が良いラベル名になります。

メトリック名に関するメタデータ(HELP、TYPE、UNITなど)はありますが、ラベル名に関するメタデータはありません。これは、ほとんど利益がないのにフォーマットを肥大化させるためです。帯域外ドキュメントは、エクスポーザーがインジェスターに提示できる方法の1つです。

メトリック名とラベル

複数のMetricをMetricFamily内で使用する場合や、複数のMetricFamilyを使用する場合の両方が意味をなす状況があります。MetricFamilyの合計または平均は、常に有用ではないとしても、意味をなすはずです。たとえば、電圧とファン速度を混在させることは意味がありません。

リマインダーとして、OpenMetricsはインジェスターがデータから処理および集計を実行できるという仮定に基づいて構築されています。

合計総数を他のメトリックとともに公開するのは誤りです。これは、下流のインジェスターでの集計時に二重カウントにつながるためです。

wrong_metric{label="a"} 1
wrong_metric{label="b"} 6
wrong_metric{label="total"} 7

Metricのラベルは、一意性を保証するために必要な最小限のものであるべきです。なぜなら、追加のラベルごとに、ユーザーが下流で作業する際に考慮する必要があるラベルが1つ増えるからです。多くのMetricFamilyに適用できるラベルは、データベース{{normalization}}と同様に_infoメトリックに移動する候補となります。ほとんどのMetricのユーザーが追加のラベルを期待できる場合、すべてのMetricFamilyに追加する方が良いトレードオフになる可能性があります。たとえば、SQLステートメントのハッシュを含むラベルによって一意性が提供されるさまざまなSQLステートメントに関連するMetricFamilyがある場合、人間が読みやすいようにSQLステートメントの最初の500文字を含む別のラベルを持つことは許容されます。

経験上、下流のインジェスターは、1つのMetricFamily内での{result="success"}および{result="failure"}ラベルの使用よりも、別々の合計と失敗のMetricFamilesを使用する方が作業しやすいことが示されています。また、全二重システムが一般的であり、下流のインジェスターがそれらをまとめて気にする可能性が高い場合、個別の送受信および送信/受信MetricFamilesを公開する方が通常良いです。

これらすべては、聞くほど簡単ではありません。これは、エクスポージャーとエクスポーズされたシステムのドメイン固有の専門家による経験とエンジニアリングのトレードオフが必要な領域であり、良いバランスを見つける必要があります。メトリック名とラベル名

OpenMetricsは、既存の広く採用されているPrometheusテキストエクスポージャーフォーマットとその周りに形成されたエコシステムの上に構築されています。後方互換性はコア設計目標です。Prometheusテキストフォーマットでサポートされる文字セットの拡張または縮小は、その目標に反します。後方互換性を壊すことは、ワイヤーフォーマットだけでなく、より広範な影響を及ぼします。特に、Prometheusエコシステム内で送信されるデータと連携するために作成または採用されたクエリ言語は、これらの正確な文字セットに依存しています。ラベル値は完全なUTF-8をサポートしているため、フォーマットは多言語メトリックを表すことができます。

メタデータの種類

メタデータはさまざまなソースから来ることができます。長年にわたり、2つの主なソースが現れました。それらは機能的に同じであることが多いですが、概念的な違いについて話すことは理解に役立ちます。

「ターゲットメタデータ」は、エクスポーザーの外部で一般的に使用されるメタデータです。一般的な例としては、サービスディスカバリ、CMDB、または同様のものからのデータ、たとえばデータセンターリージョンに関する情報、サービスが特定のデプロイメントの一部であるかどうか、または本番環境またはテスト環境であるかどうかなどがあります。これは、エクスポーザーまたはインジェスターが、これらのメタデータをキャプチャするすべてのメトリックにラベルを追加することによって達成できます。インジェスターを介してこれを行う方が、より柔軟でオーバーヘッドが少ないため推奨されます。柔軟性に関して言えば、ハードウェア保守チームはマシンのサーバーラックの場所に関心があるかもしれませんが、同じマシンを使用するデータベースチームは、本番データベースのレプリカ番号2が含まれていることを気にするかもしれません。オーバーヘッドに関して言えば、この情報をハードコーディングまたは構成するには、追加の配布パスが必要です。

「エクスポーザーメタデータ」は、エクスポーザーの内部から来ています。一般的な例としては、ソフトウェアバージョン、コンパイラバージョン、またはGitコミットSHAなどがあります。

プッシュベースとプルベースの両方のシステムでのターゲットメタデータのサポート

プッシュベースの消費では、エクスポーザーが関連するターゲットメタデータをインジェスターに提供するのが一般的です。プルベースの消費では、プッシュベースのアプローチを取ることもできますが、より一般的には、インジェスターはすでにマシデータベースやサービスディスカバリシステムなどからターゲットのメタデータを事前に知っており、エクスポージャーを消費する際にメトリックにそれを関連付けます。

OpenMetricsはステートレスであり、すべてのインジェスターに同じエクスポージャーを提供しますが、これはプッシュスタイルのアプローチと矛盾します。さらに、プッシュスタイルのアプローチは、不要なメタデータが公開されるため、プルスタイルのインジェスターを壊します。

1つのアプローチは、プッシュスタイルのインジェスターが、たとえばHTTPヘッダーとして、オペレーター構成に基づいてターゲットメタデータを提供することです。これはプッシュスタイルのインジェスターにターゲットメタデータを転送しますが、この標準で除外されていませんが、プルスタイルのインジェスターは独自のターゲットメタデータを使用するべきですが、エクスポーザー自体が認識しているメタデータにアクセスできると便利であることがよくあります。

推奨される解決策は、このターゲットメタデータをエクスポージャーの一部として提供することですが、エクスポージャー全体に影響を与えない方法で提供することです。Info MetricFamiliesはこれのために設計されています。エクスポージャーは、「target」という名前のInfo MetricFamilyを含めることができます。これは、ラベルのない単一のMetricを持ち、メタデータが付いています。テキストフォーマットでの例は次のようになります。

# TYPE target info
# HELP target Target metadata
target_info{env="prod",hostname="myhost",datacenter="sdc",region="europe",owner="frontend"} 1

エクスポーザーがこの目的でこのメトリックを提供する場合、エクスポージャーの最初に配置する必要があります。これは効率のためであり、ターゲットメタデータに依存するインジェスターが、その内容に基づいたビジネスロジックを適用する前に、エクスポージャーの残りをバッファリングする必要がないようにするためです。

エクスポーザーは、明示的に設定されていない限り、エクスポージャーのすべてのMetricにターゲットメタデータラベルを追加してはいけません。エクスポーザーは、ターゲットメタデータに基づいてMetricFamily名をプレフィックスしたり、MetricFamily名を変更したりしてはいけません。一般的に、同じラベルがエクスポージャーのすべてのMetricに表示されるべきではありませんが、まれにこれが創発的行動の結果である場合があります。同様に、エクスポーザーからのすべてのMetricFamily名は、非常に小さなエクスポージャーではプレフィックスを共有することがあります。たとえば、A Company Manufacturing EverythingによってGo言語で書かれたアプリケーションは、acme_、go_、process_、および使用中のサードパーティライブラリのメトリックプレフィックスを含むメトリックを含む可能性があります。

エクスポーザーは、Info MetricFamiliesとしてエクスポージャーメタデータを公開できます。

上記の議論は、個々のエクスポーザーの文脈で行われます。汎用監視システムからのエクスポージャーは、多数の個々のターゲットからのメトリックを含む可能性があり、したがって複数のターゲット情報Metricを公開する可能性があります。メトリックは、取り込みの一部としてラベルとしてターゲットメタデータが追加されている可能性があります。メトリック名は、ターゲットメタデータに基づいて変更してはいけません。たとえば、すべてのメトリックがステージング環境のターゲットから発生した場合でも、staging_で始まることは誤りです。

クライアント計算と派生メトリック

エクスポーザーは、すべての数学的計算または計算をインジェスターに任せるべきです。例外として、Summaryクォンタイルがありますが、これは後方互換性のために残念ながら必要です。エクスポージャーは、任意の期間で有用な生の値を公開する必要があります。

たとえば、過去5分間のカウンターの増加率の平均を示すゲージを公開すべきではありません。インジェスターがエクスポージャー間で消費したデータポイントの増加を計算させることは、より良い数学的プロパティを持ち、スクレイプの失敗に対してより回復力があります。

別の例は、ヒストグラム/サマリーの平均イベントサイズです。アプリケーションが開始して以来、またはメトリックが作成されて以来のカウンターの増加率を公開することは、前の例の問題があり、集計も妨げます。

標準偏差もこのカテゴリに分類されます。二乗和をカウンターとして公開することが正しいアプローチでしょう。これは、64ビット浮動小数点精度では実用上機能しないため、Histogramの値としては含まれていません。二乗のため、精度に関しては53ビットマンティサの半分しか利用できません。たとえば、毎秒10kイベントを観測するヒストグラムは、2時間以内に精度を失います。64ビット整数を使用しても、浮動小数点数の損失のため、イベントの長さを追跡するナノ秒解像度の整数は19回の観測後にオーバーフローするため、状況は改善しません。128ビット浮動小数点数が一般的になったときに、この設計上の決定は再検討される可能性があります。

別の例は、要求失敗率を公開するのではなく、失敗した要求と合計要求の個別のカウンターを公開することです。

数値タイプ

毎秒100万回インクリメントされるカウンターの場合、float64の53ビットマンティサにより、精度を失うには1世紀以上かかります。それでも、100 Gbpsネットワークインターフェイスのオクテットスループット精度は、約20時間以内にfloat64で失われ始める可能性があります。100Gbpsネットワークインターフェイスの場合、数年間にわたる1KBの精度低下は実際には問題にならない可能性が高いですが、int64は高スループットの整数データにオプションです。

Summaryクォンタイルはfloat64である必要があります。それらは推定値であり、本質的に不正確であるためです。

タイムスタンプの公開

OpenMetricsのコア仮定の1つは、エクスポーザーが公開するものの最新のスナップショットを公開することです。

公開されたデータにタイムスタンプを添付する限定的なユースケースはありますが、これらは非常にまれです。以前にタイムスタンプが添付されたデータ、特に汎用監視システムに取り込まれたデータは、タイムスタンプを運ぶ場合があります。ライブまたは生のデータにはタイムスタンプを付けるべきではありません。同じタイムスタンプを持つ同じメトリックMetricPoint値をエクスポージャー間で公開することは有効ですが、基盤となるメトリックがなくなった場合にそうすることは無効です。

時間同期は難しい問題であり、データは各システム内で内部的に一貫している必要があります。そのため、インジェスターは、エクスポーザーデバイスのシステム時間ではなく、データにそれ自体の現在のタイムスタンプを添付できるはずです。

タイムスタンプ付きメトリックでは、エクスポージャー間でメトリックがいつ欠落したかを検出することは一般的にできません。しかし、タイムスタンプなしのメトリックでは、インジェスターはメトリックが存在しなくなったエクスポージャーからそれ自体のタイムスタンプを使用できます。

これらすべては、一般的に、MetricPointタイムスタンプは公開されるべきではないということです。それはインジェスターが取り込むサンプルにそれ自体のタイムスタンプを適用することに任されているべきです。

メトリックが最後に変更された時期の追跡

my_counterというカウンターが初期化され、その後時間123に1だけインクリメントされたと仮定します。これは、テキストフォーマットでそれを公開する正しい方法です。

# HELP my_counter Good increment example
# TYPE my_counter counter
my_counter_total 1

親セクションの指示どおり、インジェスターは独自のタイムスタンプを添付できるはずなので、これは不正解です。

# HELP my_counter Bad increment example
# TYPE my_counter counter
my_counter_total 1 123

カウンターの最後の変更時刻が重要な場合は、これが正しい方法です。

# HELP my_counter Good increment example
# TYPE my_counter counter
my_counter_total 1
# HELP my_counter_last_increment_timestamp_seconds When my_counter was last incremented
# TYPE my_counter_last_increment_timestamp_seconds gauge
# UNIT my_counter_last_increment_timestamp_seconds seconds
my_counter_last_increment_timestamp_seconds 123

最後に変更された時刻を独自のGaugeの値として入れることで、インジェスターは両方のMetricに独自のタイムスタンプを自由に添付できます。

経験上、絶対タイムスタンプ(ここではエポックが絶対と見なされます)を公開することは、経過時間、経過秒数、またはそれに類するものよりも堅牢であることが示されています。いずれの場合も、それらはゲージになります。たとえば、

# TYPE my_boot_time_seconds gauge
# HELP my_boot_time_seconds Boot time of the machine
# UNIT my_boot_time_seconds seconds
my_boot_time_seconds 1256060124

よりも優れています。

# TYPE my_time_since_boot_seconds gauge
# HELP my_time_since_boot_seconds Time elapsed since machine booted
# UNIT my_time_since_boot_seconds seconds
my_time_since_boot_seconds 123

逆に、エクサンンプルのタイムスタンプに対するベストプラクティス上の制約はありません。レースコンディションや、デバイス間の時間の同期が完璧ではないために、エクサンンプルのタイムスタンプがインジェスターのシステムクロックや同じエクスポージャーからの他のメトリックと比較してわずかに未来にあるように見える可能性があることに留意してください。同様に、同じ MetricPoint の "_created" が、その MetricPoint のエクサンンプルまたはサンプルタイムスタンプよりわずかに後に表示される可能性もあります。

一般的に使用されている監視システムには、ナノ秒から秒までの解像度をサポートするものがあることに注意してください。そのため、秒解像度に切り捨てられたときに同じタイムスタンプを持つ2つのMetricPointは、インジェスターで重複して表示される可能性があります。この場合、最も早いタイムスタンプを持つMetricPointが使用されなければなりません。

しきい値

システムの望ましい境界を公開することは理にかなっていますが、適切な注意が必要です。普遍的に真実である値については、それらのしきい値のためのGaugeメトリックを発行することが理にかなっています。たとえば、データセンターHVACシステムは、現在の測定値、設定値、およびアラート設定値を認識しています。それは、望ましいシステム状態のグローバルに有効で正しいビューを持っています。対照的な例として、一部のしきい値は、スケール、デプロイメントモデル、または時間とともに変化する可能性があります。ある程度のCPU使用率は、ある設定では許容できるが、別の設定では望ましくない場合があります。値の集計は、許容値をさらに変更する可能性があります。このようなシステムでは、境界を公開することは逆効果になる可能性があります。

たとえば、キューの最大サイズは、キュー内の現在のアイテム数とともに次のように公開される場合があります。

# HELP acme_notifications_queue_capacity The capacity of the notifications queue.
# TYPE acme_notifications_queue_capacity gauge
acme_notifications_queue_capacity 10000
# HELP acme_notifications_queue_length The number of notifications in the queue.
# TYPE acme_notifications_queue_length gauge
acme_notifications_queue_length 42

サイズ制限

この標準では、単一のエクスポージャーによって公開されるサンプル数、存在しうるラベル数、statesetが持つことができる状態数、infovalueのラベル数、またはメトリック名/ラベル名/ラベル値/help文字数に特定の制限を規定していません。

特定の制限は、妥当なユースケースを妨げるリスクがあります。たとえば、汎用監視システムを通過した後のエクスポージャーには適切な数のラベルがあるかもしれませんが、制限を超える可能性のあるターゲットラベルがいくつか追加されている可能性があります。これらの数値に対する特定の制限は、汎用監視システムの実際のコストがかかる場所を捉えていないでしょう。したがって、これらのガイドラインは、エクスポーザーとインジェスターの両方が合理的なものを理解するのに役立ちます。

一方、ある次元で大きすぎるエクスポージャーは、公開されたメトリックの利点と比較して、重大なパフォーマンス問題を引き起こす可能性があります。したがって、単一のエクスポージャーのサイズに関するガイドラインは有用でしょう。

インジェスターは、特に攻撃や障害を防ぐために、それ自身で制限を課すことを選択する場合があります。それでも、インジェスターは妥当なユースケースを考慮し、それらを不当に影響しないようにする必要があります。単一の値/メトリック/エクスポージャーがこれらの制限を超える場合、エクスポージャー全体を拒否する必要があります。

一般的に、汎用監視システムの取り込み時間系列データに影響を与える3つの要因があります。一意の時間系列の数、それらの系列における時間経過に伴うサンプルの数、およびメトリック名、ラベル名、ラベル値、HELPのような一意の文字列の数です。インジェスターは取り込み頻度を制御できるため、その側面はさらに考慮する必要はありません。

一意の時間系列の数は、テキストフォーマットのコメント以外の行の数にほぼ相当します。2020年現在、合計1000万の時間系列は多いと見なされており、単一インスタンスのインジェスターの上限として一般的にオーダーです。単一のエクスポージャーは、十分な注意なしに10kの時間系列を超えるべきではありません。一般的な考慮事項は、水平スケーリングです。インスタンス数を1〜2桁増加させた場合、どうなりますか?単一のデプロイメントに千個のトップオブラックスイッチがあることは、30年前には想像できなかったでしょう。ターゲットがシングルトン(たとえば、クラスター全体に関連するメトリックを公開する)であった場合、数十万の時間系列が合理的かもしれません。問題となるのは、一意のMetricFamilyの数や、個々のラベル/バケット/statesetのカーディナリティではなく、時間系列の全体的なオーダーです。1つのMetricを持つ1,000のゲージは、1,000のMetricを持つ1つのゲージと同じコストです。

特定のタイプのすべてのターゲットが同じ時間系列セットを公開している場合、各追加ターゲットの文字列は、ほとんどの合理的に最新の監視システムに増分コストをかけません。しかし、各ターゲットに固有の文字列がある場合、コストが発生します。極端な例として、多くのターゲットによって使用される単一の10k文字メトリック名は、文字列を保存するという点では、最新のアプローチを仮定すると、単一の10k文字メトリック名よりも3倍以上高価になります。さらに、これらの文字列が時間とともに変化する場合、古い文字列は少なくともしばらくの間保存する必要があり、追加のコストが発生します。前の段落の1000万の時間系列を仮定すると、1時間あたり100MBの一意の文字列は、イベントロギングのようなユースケースを示している可能性があります。メトリック時間系列ではありません。

exemplarの長さには、ハードな128 UTF-8文字制限があります。これは、トレーススパンデータやその他のイベントロギングのために機能が悪用されるのを防ぐためです。

セキュリティ

実装者は、認証、認可、アカウンティングを提供することを選択できます。選択した場合、これは OpenMetrics の外部で処理されるべきです。

すべてのエクスポーザー実装は、TLS 1.2 以降で HTTP トラフィックを保護できるべきです。エクスポーザー実装が暗号化をサポートしていない場合、運用者は可能な限りリバースプロキシ、ファイアウォール、および/または ACL を使用すべきです。

メトリクスの公開は、エンドユーザーに公開される本番サービスとは独立しているべきです。そのため、OpenMetrics を使用する公開サービスで TCP/80、TCP/443、TCP/8080、TCP/8443 のようなポートに /metrics エンドポイントを持つことは、一般的に推奨されません。

IANA

現在、Prometheus 公開フォーマットの実装のほとんどは、{{PrometheusPorts}} の非公式レジストリにある IANA 非登録ポートを使用していますが、OpenMetrics は明確に定義されたポートで見つけることができます。

データを公開するクライアントのために IANA によって割り当てられたポートは、歴史的な整合性のために <9099 が要求されました>。

共通の IP アドレスとポートで複数のメトリクスエンドポイントに到達する必要がある場合、運用者は、localhost アドレス経由でエクスポーザーと通信するリバースプロキシの使用を検討することがあります。多重化を容易にするために、エンドポイントはパスにそれ自体の名前を含めるべきです。つまり、/node_exporter/metrics です。「プッシュベースとプルベースの両方のシステムでターゲットメタデータをサポートする」で説明されている理由により、および単一障害点なしで独立した取り込みを可能にするために、公開を 1 つの公開に結合すべきではありません。

OpenMetrics は、2 つの MIME タイプ、application/openmetrics-text および application/openmetrics-proto を登録したいと考えています。

このページの内容