クエリの基本
Prometheusは、PromQL(Prometheus Query Language)と呼ばれる関数型クエリ言語を提供し、ユーザーは時系列データをリアルタイムで選択および集計できます。
Prometheusにクエリリクエストを送信する際、それは1つの時点のインスタントクエリ、または開始時間と終了時間の間の均等に配置されたステップでの範囲クエリである可能性があります。PromQLはどちらの場合でもまったく同じように機能します。範囲クエリは、異なるタイムスタンプで複数回実行されるインスタントクエリのようなものです。
Prometheus UIでは、「Table」タブはインスタントクエリ用、「Graph」タブは範囲クエリ用です。
他のプログラムは、HTTP API を介してPromQL式の結果を取得できます。
例
このドキュメントは、Prometheusの基本言語リファレンスです。学習のためには、いくつかの例から始めるのが簡単かもしれません。
式言語のデータ型
Prometheusの式言語では、式またはサブ式は4つのタイプのいずれかに評価されます。
- インスタントベクトル - 各時系列に1つのサンプルを含む時系列のセット。すべて同じタイムスタンプを共有します。
- 範囲ベクトル - 各時系列について、時間の経過に伴うデータポイントの範囲を含む時系列のセット。
- スカラー - 単純な数値浮動小数点値。
- 文字列 - 単純な文字列値。現在未使用。
ユースケース(例:式のグラフ化と出力の表示)に応じて、これらのタイプの一部のみがユーザー指定の式の結果として許可されます。 インスタントクエリでは、上記のデータタイプのいずれも式のルートとして許可されます。 範囲クエリは、スカラー型とインスタントベクトル型の式のみをサポートします。
実験的なネイティブヒストグラムに関する注記
- ネイティブヒストグラムの取り込みは、フィーチャーフラグを介して有効にする必要があります。
- TSDBにネイティブヒストグラムが取り込まれた後(フィーチャーフラグを無効にした後でも)、インスタントベクトルと範囲ベクトルの両方に、単純な浮動小数点数(floatサンプル)ではない、完全なヒストグラム(histogramサンプル)を含むサンプルが含まれるようになります。ベクトルには、floatサンプルとhistogramサンプルの混合が含まれる場合があります。PromQLドキュメントの「histogram sample」という用語は、常にネイティブヒストグラムを指すことに注意してください。古典的なヒストグラムは、多数のfloatサンプルのシリーズに分割されます。PromQLの観点からは、「classic histogram samples」はありません。
- floatサンプルと同様に、histogramサンプルは、それぞれカウンターヒストグラムまたはゲージヒストグラムとしてマークされたカウンターまたはゲージの「フレーバー」を持つことができます。floatサンプルとは対照的に、histogramサンプルはそのフレーバーを「認識」しており、互換性のない操作(例:ゲージヒストグラムの範囲ベクトルに
rate関数を適用する)に関する信頼性の高い警告を可能にします。 - ネイティブヒストグラムは異なるバケットレイアウトを持つことができますが、それらは一般的に互換性のあるバージョンに変換されて、バイナリおよび集計操作を適用できます。これはすべてのバケットスキームに当てはまるわけではありません。操作で互換性のないヒストグラムが検出された場合、結果から対応する出力ベクトル要素が削除され、警告レベルのアノテーションが付けられます。詳細については、ネイティブヒストグラム仕様を参照してください。
リテラル
文字列リテラル
文字列リテラルは、シングルクォート、ダブルクォート、またはバッククォートで指定されます。
PromQLは、Goのエスケープルールと同じに従います。シングルまたはダブルクォートの文字列リテラルでは、バックスラッシュがエスケープシーケンスを開始し、その後にa、b、f、n、r、t、v、または\が続く場合があります。特定の文字は、8進数(\nnn)または16進数(\xnn、\unnnn、および\Unnnnnnnn)表記を使用して指定できます。
逆に、バッククォートで指定された文字列リテラルではエスケープ文字は解析されません。Goとは異なり、Prometheusはバッククォート内の改行を破棄しないことに注意することが重要です。
例
"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`
浮動小数点数リテラルと時間間隔
スカラー浮動小数点値は、(読みやすさのためにのみ空白を含む)形式でリテラル整数または浮動小数点数として記述できます。
[-+]?(
[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
| 0[xX][0-9a-fA-F]+
| [nN][aA][nN]
| [iI][nN][fF]
)
例
23
-2.43
3.4e-9
0x8f
-Inf
NaN
さらに、アンダースコア(_)を10進数または16進数の桁の間で使用して、読みやすさを向上させることができます。
例
1_000_000
.123_456_789
0x_53_AB_F3_82
浮動小数点数リテラルは、秒単位の期間を指定するためにも使用されます。利便性のために、10進数の整数は次の時間単位と組み合わせることができます。
ms– ミリ秒s– 秒 – 1秒は1000ミリ秒に相当します。m– 分 – 1分は60秒に相当します(うるう秒は無視)。h– 時間 – 1時間=60分。d– 日 – 1日=24時間(いわゆる夏時間時差は無視)。w– 週 – 1週=7日。y– 年 – 1年=365日(うるう年は無視)。
上記のいずれかの単位を10進整数に付加することは、相当する秒数をベアフロートリテラルとして表現する別の方法です。
例
1s # Equivalent to 1.
2m # Equivalent to 120.
1ms # Equivalent to 0.001.
-2h # Equivalent to -7200.
以下の例は機能しません。
0xABm # No suffixing of hexadecimal numbers.
1.5h # Time units cannot be combined with a floating point.
+Infd # No suffixing of ±Inf or NaN.
複数の単位は、サフィックス付き整数を連結することで組み合わせることができます。単位は、最も長いものから最も短いものまで順序付けする必要があります。各単位は、1つの浮動小数点数リテラルにつき1回のみ出現する必要があります。
例
1h30m # Equivalent to 5400s and thus 5400.
12h34m56s # Equivalent to 45296s and thus 45296.
54s321ms # Equivalent to 54.321.
時系列セレクター
これらは、PromQLにどのデータを取得するかを指示する基本的な構成要素です。
インスタントベクトルセレクター
インスタントベクトルセレクターは、指定されたタイムスタンプ(時点)で各時系列の1つのサンプル値と時系列のセットを選択できます。最も単純な形式では、メトリック名のみが指定され、これはこのメトリック名を持つすべての時系列の要素を含むインスタントベクトルになります。
返される値は、クエリの評価タイムスタンプ(インスタントクエリの場合)またはクエリ内の現在のステップ(範囲クエリの場合)以前で最も新しいサンプル値になります。@修飾子を使用すると、選択が行われるタイムスタンプをオーバーライドできます。時系列は、その最新のサンプルがルックバック期間より前にある場合にのみ返されます。
この例では、http_requests_totalメトリック名を持つすべての時系列を選択し、各時系列の最新サンプルを返します。
http_requests_total
波括弧({})でラベルマッチャーのコンマ区切りリストを付加することで、これらの時系列をさらにフィルタリングできます。
この例では、http_requests_totalメトリック名を持ち、かつjobラベルがprometheusに設定され、groupラベルがcanaryに設定されている時系列のみを選択します。
http_requests_total{job="prometheus",group="canary"}
ラベル値を否定的に一致させること、または正規表現に対してラベル値を一致させることも可能です。次のラベルマッチング演算子が存在します。
=: 提供された文字列と完全に一致するラベルを選択します。!=: 提供された文字列と一致しないラベルを選択します。=~: 提供された文字列と正規表現で一致するラベルを選択します。!~: 提供された文字列と正規表現で一致しないラベルを選択します。
正規表現マッチは完全にアンカーされています。env=~"foo"のマッチはenv=~"^foo$"として扱われます。
たとえば、これはstaging、testing、およびdevelopment環境のすべてのhttp_requests_total時系列と、GET以外のHTTPメソッドを選択します。
http_requests_total{environment=~"staging|testing|development",method!="GET"}
空のラベル値に一致するラベルマッチャーは、特定のラベルが設定されていないすべての時系列も選択します。同じラベル名に対して複数のマッチャーを使用できます。
たとえば、次のデータセットが与えられた場合
http_requests_total
http_requests_total{replica="rep-a"}
http_requests_total{replica="rep-b"}
http_requests_total{environment="development"}
クエリhttp_requests_total{environment=""}は、次のように一致して返されます。
http_requests_total
http_requests_total{replica="rep-a"}
http_requests_total{replica="rep-b"}
そして、次を除外します。
http_requests_total{environment="development"}
同じラベル名に対して複数のマッチャーを使用できます。結果が返されるためには、すべてがパスする必要があります。
クエリ
http_requests_total{replica!="rep-a",replica=~"rep.*"}
そして、次のように一致します。
http_requests_total{replica="rep-b"}
ベクトルセレクターは、名前を指定するか、空でない文字列に一致しない少なくとも1つのラベルマッチャーを指定する必要があります。次の式は無効です。
{job=~".*"} # Bad!
対照的に、これらの式は有効です。なぜなら、どちらも空でないラベル値に一致するセレクターを持っているからです。
{job=~".+"} # Good!
{job=~".*",method="get"} # Good!
ラベルマッチャーは、内部の__name__ラベルに一致させることでメトリック名にも適用できます。たとえば、式http_requests_totalは{__name__="http_requests_total"}と同等です。=以外のマッチャー(!=、=~、!~)も使用できます。次の式は、名前がjob:で始まるすべてのメトリックを選択します。
{__name__=~"job:.*"}
メトリック名は、キーワードbool、on、ignoring、group_left、group_rightのいずれかであってはなりません。次の式は無効です。
on{} # Bad!
この制限の回避策は、__name__ラベルを使用することです。
{__name__="on"} # Good!
範囲ベクトルセレクター
範囲ベクトルリテラルはインスタントベクトルリテラルのように動作しますが、現在のインスタントからサンプル範囲を選択する点が異なります。構文的には、浮動小数点数リテラルをベクトルセレクターの末尾に角括弧([])で付加して、各範囲ベクトル要素について何秒前の値を取得するかを指定します。一般的に、浮動小数点数リテラルは1つ以上の時間単位を持つ構文を使用します。例:[5m]。範囲は左開右閉区間です。つまり、範囲の左端と一致するタイムスタンプを持つサンプルは選択から除外されますが、範囲の右端と一致するサンプルは選択に含まれます。
この例では、メトリック名http_requests_totalとjobラベルがprometheusに設定されているすべての時系列について、5分前までのすべての値を選択します。
http_requests_total{job="prometheus"}[5m]
オフセット修飾子
offset修飾子を使用すると、クエリ内の個々のインスタントベクトルと範囲ベクトルの時間オフセットを変更できます。
たとえば、次の式は、現在のクエリ評価時間から5分前のhttp_requests_totalの値を返します。
http_requests_total offset 5m
offset修飾子は常にセレクターの直後に続く必要があることに注意してください。つまり、次が正しいです。
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
一方、次が不正です。
sum(http_requests_total{method="GET"}) offset 5m // INVALID.
範囲ベクトルでも同様です。これは、1週間前のhttp_requests_totalの5分間のレートを返します。
rate(http_requests_total[5m] offset 1w)
過去のサンプルをクエリする場合、負のオフセットは将来の時点への時間的比較を有効にします。
rate(http_requests_total[5m] offset -1w)
これは、クエリが評価時間を先取りできることに注意してください。
@修飾子
@修飾子を使用すると、クエリ内の個々のインスタントベクトルと範囲ベクトルの評価時間を変更できます。@修飾子に供給される時間はUnixタイムスタンプであり、浮動小数点数リテラルで記述されます。
たとえば、次の式は2021-01-04T07:40:00+00:00時点のhttp_requests_totalの値を返します。
http_requests_total @ 1609746000
@修飾子は常にセレクターの直後に続く必要があることに注意してください。つまり、次が正しいです。
sum(http_requests_total{method="GET"} @ 1609746000) // GOOD.
一方、次が不正です。
sum(http_requests_total{method="GET"}) @ 1609746000 // INVALID.
範囲ベクトルでも同様です。これは、2021-01-04T07:40:00+00:00時点のhttp_requests_totalの5分間のレートを返します。
rate(http_requests_total[5m] @ 1609746000)
@修飾子は、上記の数値リテラルのすべての表現をサポートします。offset修飾子とも機能し、オフセットは@修飾子の時間に対して適用されます。結果は、修飾子の順序に関係なく同じです。
たとえば、次の2つのクエリは同じ結果を生成します。
# offset after @
http_requests_total @ 1609746000 offset 5m
# offset before @
http_requests_total offset 5m @ 1609746000
さらに、start()とend()も@修飾子の値として特殊値として使用できます。
範囲クエリの場合、これらは範囲クエリの開始と終了に解決され、すべてのステップで同じままです。
インスタントクエリの場合、start()とend()は両方とも評価時間に解決されます。
http_requests_total @ start()
rate(http_requests_total[5m] @ end())
@修飾子により、クエリが評価時間を先取りできることに注意してください。
サブクエリ
サブクエリを使用すると、指定された範囲と解像度でインスタントクエリを実行できます。サブクエリの結果は範囲ベクトルです。
構文:<instant_query> '[' <range> ':' [<resolution>] ']' [ @ <float_literal> ] [ offset <float_literal> ]
<resolution>はオプションです。デフォルトはグローバル評価間隔です。
演算子
Prometheusは多くのバイナリ演算子と集計演算子をサポートしています。これらは式言語演算子ページで詳細に説明されています。
関数
Prometheusは、データに操作を適用するためのいくつかの関数をサポートしています。これらは式言語関数ページで詳細に説明されています。
コメント
PromQLは#で始まる行コメントをサポートしています。例:
# This is a comment
正規表現
Prometheusのすべての正規表現は、RE2構文を使用します。
正規表現マッチは常に完全にアンカーされています。
注意点
陳腐化
クエリ中にデータサンプルを採取するタイムスタンプは、実際の現在の時系列データとは独立して選択されます。これは主に、複数の集計された時系列が正確に時間的に一致しない集計(sum、avgなど)の場合をサポートするためです。独立しているため、Prometheusはこれらのタイムスタンプで各関連時系列に値を割り当てる必要があります。これは、ルックバック期間より前の最新のサンプルを取得することで行われます。ルックバック期間はデフォルトで5分ですが、--query.lookback-deltaフラグで設定するか、lookback_deltaパラメータを介して個々のクエリでオーバーライドできます。
ターゲットのスクレイピングまたはルールの評価で、以前存在していた時系列のサンプルが返されなくなった場合、その時系列は古いものとしてマークされます。ターゲットが削除された場合、以前取得された時系列は削除後すぐに古いものとしてマークされます。
時系列が古いものとしてマークされた後のサンプリングタイムスタンプでクエリが評価された場合、その時系列の値は返されません。その後、その時系列に新しいサンプルが取り込まれた場合、それらは期待どおりに返されます。
時系列は、エクスポートされなくなった場合、またはターゲットが存在しなくなった場合に古くなります。そのような時系列は、最新のサンプルが収集された時点からグラフに表示されなくなり、古いものとしてマークされた後はクエリで返されなくなります。
独自のタイムスタンプをサンプルに付ける一部のエクスポーターは、異なる動作をします。エクスポートされなくなったシリーズは、消えるまでの(デフォルトで)5分間、最後の値を取り続けます。track_timestamps_staleness設定でこれを変更できます。
遅いクエリと過負荷の回避
クエリが大量のデータに対象とする必要がある場合、それをグラフ化するとタイムアウトしたり、サーバーやブラウザに過負荷がかかったりする可能性があります。したがって、未知のデータに対してクエリを構築する際は、まずPrometheusの式ブラウザの表形式ビューでクエリを構築し、結果セットが妥当(最大で数百、数千ではない)になるまで続けてください。データを十分にフィルタリングまたは集計した後でのみ、グラフモードに切り替えてください。式がまだアドホックでグラフ化するには時間がかかる場合は、記録ルールを介して事前に記録してください。
これは特にPrometheusのクエリ言語に関連しており、api_http_requests_totalのようなベアメトリック名セレクターは、異なるラベルを持つ数千の時系列に展開される可能性があります。また、多くの時系列を集計する式は、出力が少数の時系列であってもサーバーに負荷を生成することを考慮してください。これは、リレーショナルデータベースの列のすべての値の合計を計算するのが遅くなるのと似ており、出力値が単一の数値であっても同様です。