Prometheus Prometheus

PromQL をはじめる:選択、レート、集約

単純なメトリクスのセレクターから、実際のクエリまで段階的に組み立てます。パスごとのエラー率を、ライブで計算します。

12 min learn.level.中級

PromQL は、Prometheus のデータを読み取るあらゆる部分、つまりダッシュボード、アラートルール、アドホックなデバッグの基盤となるクエリ言語です。このガイドでは、実際のクエリを段階的に組み立てます。パス、メソッド、ステータスで分けられたリクエストの counter があるとき、エラー率が 5% を超えるすべてのパスを見つけます。

時系列を選択する

最もシンプルな PromQL の式は、メトリクス名だけで、その名前を持つすべての時系列の現在の値を返します。

http_requests_total

波括弧内にラベルのマッチャーを追加して、特定のサブセットに絞り込みます。

http_requests_total{status="500"}

これは、パスやメソッドに関係なく、status ラベルがちょうど "500" である、http_requests_total という名前のすべての系列を返します。マッチャーは、正規表現によるマッチング(任意の 5xx ステータスには status=~"5..")や否定(status!="200")なども行えます。

counter からレートへ

http_requests_total は counter で、増える一方なので、その生の値(プロセスが起動してから積み重なった大きな数)は、実際に見たいものではありません。見たいのは、どれくらいの速さで増えているかで、それを計算するのが rate() 関数です。指定した時間枠での、1 秒あたりの平均増加率です。

rate(http_requests_total{status="500"}[5m])

これは、一致する各系列について、直近 5 分間の 500 エラーの 1 秒あたりの平均レートを返します。関連する関数 irate() は、範囲全体を平均するのではなく、範囲内の最後の 2 つのデータポイントだけを使って瞬間的なレートを計算します。irate() は突然のスパイクにより素早く反応しますが、ノイズも多く、1 回の異常なスクレイプに敏感です。ダッシュボード、特にアラートには rate() がデフォルトとして推奨されます。そこでは通常、より滑らかで、スパイクの影響を受けにくいシグナルが求められるからです。短い時間スケールで、速く動く counter を見て、平滑化されたトレンドではなく瞬間的な変化を見たい場合に、特に irate() を使ってください。

気にしないラベルを集約で取り除く

rate() は、元の時系列ごとに 1 つの結果を返し続けます。パス、メソッド、ステータスの一意の組み合わせごとに 1 行です。存在するメソッドとステータスにわたって合計した、パスごとに 1 つの数値を得るには、集約演算子を使います。

sum by (path) (rate(http_requests_total{status="500"}[5m]))

sum by (path) (...) は、レートを合計し、path ラベルでグルーピングし、結果から他のすべてのラベルを捨てます。これが PromQL の集約の一般的な形です。演算子(sum、avg、max、min、count など)を選び、結果に残すラベルを指定する by (...) 句を付けます。

二項演算子でクエリを組み合わせる

エラー率をパーセンテージで計算するには、2 つの集約クエリ、つまりエラーのリクエストと全リクエストを、互いに割る必要があります。

sum by (path) (rate(http_requests_total{status="500"}[5m]))
/
sum by (path) (rate(http_requests_total[5m]))
* 100

PromQL は、二項演算の両辺を、残りのラベル(この場合は path)で対応付け、手動で揃える必要なく、一致する各ペアについて割り算を計算します。100 を掛けると、結果の比率がパーセンテージになります。

結果そのものをフィルタリングする

式全体を囲んで、実際にしきい値を超えている結果だけを残します。

(
  sum by (path) (rate(http_requests_total{status="500"}[5m]))
  /
  sum by (path) (rate(http_requests_total[5m]))
  * 100
) > 5

これは、計算されたエラーのパーセンテージが現在 5 を超えているパスだけを返します。これはまさに、条件が成立したときに誰かを呼び出すために、アラートルールに包みたくなる形のクエリです。

クエリをアラートに変える

アラートルールは、PromQL の式と、それが何かに評価されたときに何をするかを記述するメタデータです。

groups:
  - name: example-alerts
    rules:
      - alert: HighErrorRatePerPath
        expr: |
          (
            sum by (path) (rate(http_requests_total{status="500"}[5m]))
            /
            sum by (path) (rate(http_requests_total[5m]))
            * 100
          ) > 5
        for: 10m
        labels:
          severity: page
        annotations:
          summary: "Error rate above 5% on {{ $labels.path }}"

for: 10m は、アラートが実際に発火する前に、条件が 10 分間続くことを要求します。これにより、自然に解消する短い一時的な乱れで呼び出されるのを避けられます。Prometheus はこのようなルールを継続的に評価し、現在発火しているものを Alertmanager に渡します。これは、Grafana のパネルに直接入れるのと同じ PromQL に、名前、期間、ルーティングのメタデータを付けただけのものです。

ここから先へ

ここでは、インスタントベクトル、レートの計算、集約、二項演算子を説明しました。既存のダッシュボードやアラートで出会うクエリの大部分を読み書きするのに十分です。PromQL にはこれ以上のもの(rate 以外のレンジベクトル関数、サブクエリ、より多くの集約演算子)があり、Prometheus 自身のクエリリファレンスに十分に文書化されています。最初のいくつかの実際のクエリを書くときは、開いておく価値があります。

人気のガイド