Prometheusのクエリ言語は、基本的な論理演算子と算術演算子をサポートしています。2つのインスタントベクトル間の演算では、マッチングの動作を変更できます。
Prometheusには、以下の算術二項演算子があります
+
(加算)-
(減算)*
(乗算)/
(除算)%
(剰余)^
(べき乗)算術二項演算子は、スカラー/スカラー、ベクトル/スカラー、およびベクトル/ベクトルの値ペア間で定義されます。
2つのスカラー間では、動作は明白です。両方のスカラーオペランドに適用された演算の結果である別のスカラーに評価されます。
インスタントベクトルとスカラー間では、演算子はベクトル内のすべてのデータサンプルの値に適用されます。たとえば、時系列インスタントベクトルが2倍されると、結果は元のベクトルのすべてのサンプル値が2倍された別のベクトルになります。メトリック名は削除されます。
2つのインスタントベクトル間では、算術二項演算子は左側のベクトル内の各エントリとその右側のベクトル内の一致する要素に適用されます。結果は、グループ化ラベルが出力ラベルセットになる結果ベクトルに伝播されます。メトリック名は削除されます。右側のベクトルに一致するエントリが見つからないエントリは、結果の一部ではありません。
Prometheusには、ラジアンで動作する以下の三角二項演算子があります
atan2
(https://pkg.go.dev/math#Atan2に基づく)三角演算子を使用すると、通常の関数では利用できないベクトルマッチングを使用して2つのベクトルに対して三角関数を実行できます。それらは算術演算子と同じように動作します。
Prometheusには、以下の比較二項演算子があります
==
(等しい)!=
(等しくない)>
(より大きい)<
(より小さい)>=
(以上)<=
(以下)比較演算子は、スカラー/スカラー、ベクトル/スカラー、およびベクトル/ベクトルの値ペア間で定義されます。デフォルトでは、それらはフィルター処理します。それらの動作は、演算子の後にbool
を指定することで変更できます。これにより、フィルター処理するのではなく、値に対して0
または1
が返されます。
2つのスカラー間では、bool
修飾子を指定する必要があり、これらの演算子は比較結果に応じて0
(false
) または1
(true
) のいずれかである別のスカラーになります。
インスタントベクトルとスカラー間では、これらの演算子はベクトル内のすべてのデータサンプルの値に適用され、比較結果がfalse
になるベクトル要素は結果ベクトルから削除されます。bool
修飾子が指定されている場合、削除されるベクトル要素は代わりに値0
を持ち、保持されるベクトル要素は値1
を持ちます。bool
修飾子が指定されている場合、メトリック名は削除されます。
2つのインスタントベクトル間では、これらの演算子はデフォルトでフィルターとして動作し、一致するエントリに適用されます。式が真でないベクトル要素、または式の反対側で一致が見つからないベクトル要素は結果から削除されます。一方、他の要素はグループ化ラベルが出力ラベルセットになる結果ベクトルに伝播されます。bool
修飾子が指定されている場合、削除されるはずだったベクトル要素は代わりに値0
を持ち、保持されるはずだったベクトル要素は値1
を持ち、グループ化ラベルが再び出力ラベルセットになります。bool
修飾子が指定されている場合、メトリック名は削除されます。
これらの論理/集合二項演算子は、インスタントベクトル間でのみ定義されます
and
(交差)or
(和集合)unless
(補集合)vector1 and vector2
は、vector2
に完全に一致するラベルセットを持つ要素があるvector1
の要素で構成されるベクトルになります。他の要素は削除されます。メトリック名と値は、左側のベクトルから引き継がれます。
vector1 or vector2
は、vector1
のすべての元の要素 (ラベルセット+値) と、さらにvector1
に一致するラベルセットがないvector2
のすべての要素を含むベクトルになります。
vector1 unless vector2
は、vector2
に完全に一致するラベルセットを持つ要素がないvector1
の要素で構成されるベクトルになります。両方のベクトルのすべての一致する要素は削除されます。
ベクトル間の演算では、左側のベクトルの各エントリに対して右側のベクトル内の一致する要素を見つけようとします。マッチング動作には、一対一と多対一/一対多の2つの基本的なタイプがあります。
これらのベクトルマッチングキーワードを使用すると、異なるラベルセットを持つ系列間のマッチングが可能になります
on
ignoring
マッチングキーワードに提供されるラベルリストは、ベクトルの結合方法を決定します。例は、一対一のベクトルマッチングおよび多対一および一対多のベクトルマッチングにあります
これらのグループ修飾子は、多対一/一対多のベクトルマッチングを有効にします
group_left
group_right
ラベルリストは、結果メトリクスに含める「1」側のラベルを含むグループ修飾子に提供できます。
多対一および一対多のマッチングは、慎重に検討する必要がある高度なユースケースです。多くの場合、ignoring(<labels>)
を適切に使用すると、望ましい結果が得られます。
グループ修飾子は、比較および算術にのみ使用できます。and
、unless
、or
などの演算は、デフォルトで右側のベクトル内の可能なすべてのエントリと一致します。
一対一は、操作の両側から一意のエントリのペアを見つけます。デフォルトの場合、それはvector1 <演算子> vector2
形式に従う操作です。2つのエントリは、ラベルと対応する値が完全に同じセットを持っている場合、一致します。ignoring
キーワードを使用すると、マッチング時に特定のラベルを無視できますが、on
キーワードを使用すると、考慮されるラベルのセットを、指定されたリストに減らすことができます
<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>
入力例
method_code:http_errors:rate5m{method="get", code="500"} 24
method_code:http_errors:rate5m{method="get", code="404"} 30
method_code:http_errors:rate5m{method="put", code="501"} 3
method_code:http_errors:rate5m{method="post", code="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21
method:http_requests:rate5m{method="get"} 600
method:http_requests:rate5m{method="del"} 34
method:http_requests:rate5m{method="post"} 120
クエリ例
method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
これにより、過去5分間に測定された、各メソッドのステータスコード500のHTTPリクエストの割合を含む結果ベクトルが返されます。ignoring(code)
がない場合、メトリクスは同じラベルセットを共有しないため、一致はありませんでした。put
とdel
のメソッドを持つエントリは一致がなく、結果に表示されません
{method="get"} 0.04 // 24 / 600
{method="post"} 0.05 // 6 / 120
多対1および1対多のマッチングとは、「1」側の各ベクトル要素が「多」側の複数の要素とマッチできるケースを指します。これは、group_left
またはgroup_right
修飾子を使用して明示的に要求する必要があります。左/右はどちらのベクトルが高いカーディナリティを持つかを決定します。
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
グループ修飾子で提供されるラベルリストには、「1」側からの追加ラベルが含まれ、結果のメトリクスに含められます。on
の場合、ラベルはリストのいずれか一方にのみ表示できます。結果ベクトルのすべての時系列は一意に識別可能である必要があります。
クエリ例
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
この場合、左側のベクトルには、method
ラベル値ごとに複数のエントリが含まれています。したがって、group_left
を使用してこれを示します。右側の要素は、左側の同じmethod
ラベルを持つ複数の要素と照合されます。
{method="get", code="500"} 0.04 // 24 / 600
{method="get", code="404"} 0.05 // 30 / 600
{method="post", code="500"} 0.05 // 6 / 120
{method="post", code="404"} 0.175 // 21 / 120
Prometheusは、単一のインスタントベクトルの要素を集計するために使用できる、以下の組み込み集計演算子をサポートしており、集計された値を持つ要素数がより少ない新しいベクトルが得られます。
sum
(次元全体の合計を計算)min
(次元全体の最小値を選択)max
(次元全体の最大値を選択)avg
(次元全体の平均を計算)group
(結果ベクトルのすべての値は1)stddev
(次元全体の母集団標準偏差を計算)stdvar
(次元全体の母集団分散を計算)count
(ベクトル内の要素数をカウント)count_values
(同じ値を持つ要素数をカウント)bottomk
(サンプル値で最小のk個の要素)topk
(サンプル値で最大のk個の要素)quantile
(次元全体でφ-分位数(0 ≤ φ ≤ 1)を計算)limitk
(n個の要素をサンプリング)limit_ratio
(r > 0
の場合、ほぼrの比率で要素をサンプリングし、r = -(1.0 - r)
の場合、そのようなサンプルの補完をサンプリング)これらの演算子は、すべてのラベル次元に対して集計するために使用することも、without
またはby
句を含めることで個別の次元を保持することもできます。これらの句は、式の前または後に使用できます。
<aggr-op> [without|by (<label list>)] ([parameter,] <vector expression>)
または
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
label list
は、末尾にコンマを含めることができる引用符で囲まれていないラベルのリストです。つまり、(label1, label2)
と(label1, label2,)
の両方が有効な構文です。
without
は、リストされたラベルを結果ベクトルから削除しますが、他のすべてのラベルは出力で保持されます。by
は反対のことを行い、by
句にリストされていないラベルを、ベクトルのすべての要素間でラベル値が同一であっても削除します。
parameter
は、count_values
、quantile
、topk
、bottomk
、limitk
、およびlimit_ratio
でのみ必要です。
count_values
は、一意のサンプル値ごとに1つの時系列を出力します。各系列には追加のラベルがあります。そのラベルの名前は集計パラメータによって指定され、ラベル値は一意のサンプル値です。各時系列の値は、そのサンプル値が存在した回数です。
topk
とbottomk
は、入力サンプルのサブセット(元のラベルを含む)が結果ベクトルで返されるという点で、他の集計子とは異なります。by
とwithout
は、入力ベクトルのバケット化にのみ使用されます。
limitk
とlimit_ratio
も、結果ベクトルに元のラベルを含む入力サンプルのサブセットを返します。これらは、--enable-feature=promql-experimental-functions
で有効にする必要がある実験的な演算子です。
quantile
はφ-分位数を計算します。これは、集計された次元のN個のメトリック値の中で、φ*N番目にランク付けされる値です。φは集計パラメータとして提供されます。たとえば、quantile(0.5, ...)
は中央値を計算し、quantile(0.95, ...)
は95パーセンタイルを計算します。φ=NaN
の場合、NaN
が返されます。φ < 0の場合、-Inf
が返されます。φ > 1の場合、+Inf
が返されます。
例
メトリックhttp_requests_total
に、application
、instance
、およびgroup
ラベルで分岐する時系列がある場合、次のようにして、すべてのインスタンスを対象に、アプリケーションおよびグループごとのHTTPリクエストの合計数を計算できます。
sum without (instance) (http_requests_total)
これは次と同等です。
sum by (application, group) (http_requests_total)
すべてのアプリケーションで確認したHTTPリクエストの合計数のみに関心がある場合は、次のように記述できます。
sum(http_requests_total)
各ビルドバージョンを実行しているバイナリの数をカウントするには、次のように記述できます。
count_values("version", build_version)
すべてのインスタンスで上位5件のHTTPリクエストカウントを取得するには、次のように記述できます。
topk(5, http_requests_total)
たとえば、ラベルとその値を検査するために10個の時系列をサンプリングするには、次のように記述できます。
limitk(10, http_requests_total)
決定論的に約10%の時系列をサンプリングするには、次のように記述できます。
limit_ratio(0.1, http_requests_total)
limit_ratio()
は決定論的なサンプリングアルゴリズム(ラベルのハッシュに基づく)を実装しているため、上記のサンプルの補完、つまり約90%を、limit_ratio(0.1, ...)
で返されないものを正確に取得できます。
limit_ratio(-0.9, http_requests_total)
また、この機能を使用して、たとえば、2つのサンプルサブセットの平均化の差が標準偏差と比較して「小さい」ことを確認することで、avg()
がサンプルの値の代表的な集計であることを検証できます。
abs(
avg(limit_ratio(0.5, http_requests_total))
-
avg(limit_ratio(-0.5, http_requests_total))
) <= bool stddev(http_requests_total)
次のリストは、Prometheusにおける二項演算子の優先順位を高い順に示しています。
^
*
、/
、%
、atan2
+
, -
==
, !=
, <=
, <
, >=
, >
and
、unless
または
同じ優先順位レベルの演算子は左結合です。たとえば、2 * 3 % 2
は(2 * 3) % 2
と同等です。ただし、^
は右結合であるため、2 ^ 3 ^ 2
は2 ^ (3 ^ 2)
と同等です。
ネイティブヒストグラムは実験的な機能です。ネイティブヒストグラムの取り込みは、機能フラグを使用して有効にする必要があります。ネイティブヒストグラムが取り込まれると、機能フラグが再び無効になった後でも、クエリできます。ただし、ネイティブヒストグラムの演算子サポートはまだ非常に限られています。
ヒストグラムサンプルが含まれていても、論理/セット二項演算子は期待どおりに機能します。それらはベクター要素の存在のみをチェックし、要素のサンプルタイプ(浮動小数点またはヒストグラム)に応じて動作を変更しません。count
集計演算子も同様に機能します。
2つのネイティブヒストグラム間の二項+
および-
演算子と、ネイティブヒストグラムを集計するsum
およびavg
集計演算子は完全にサポートされています。関係するヒストグラムのバケットレイアウトが異なっていても、操作を実行できるようにバケットは自動的に適切に変換されます。(現在サポートされているバケットスキーマでは、常に可能です。)いずれかの演算子にヒストグラムサンプルと浮動小数点サンプルが混在して集計する必要がある場合、対応するベクトル要素は出力ベクトルから完全に削除されます。
二項演算子*
はネイティブヒストグラムと浮動小数点数間で任意の順序で機能し、二項演算子/
はネイティブヒストグラムと浮動小数点数間で正確な順序で使用できます。
他のすべての演算子(および上記の演算子の言及されていないケース)は、意味のある方法では動作しません。それらは、ヒストグラムサンプルを値0の浮動小数点サンプルであるかのように扱うか、(スカラーとベクトル間の算術演算の場合)ヒストグラムサンプルをそのままにします。この動作は、ネイティブヒストグラムが安定した機能になる前に、意味のあるものに変更されます。
このドキュメントはオープンソースです。問題の提出またはプルリクエストを通じて改善にご協力ください。