「@」修飾子のご紹介

何かの上位10個のタイムシリーズを選択したのに、10個ではなく100個の結果が返ってきたことはありませんか?もしあれば、これはあなたのための記事です。根本的な問題と、その解決方法を説明します。

現在、topk()クエリは、正確にk個の結果を得るインスタントクエリとしてのみ意味を持ちます。しかし、範囲クエリとして実行すると、各ステップが独立して評価されるため、k個をはるかに超える結果が得られる可能性があります。この「@」修飾子を使用すると、範囲クエリ内のすべてのステップのランキングを修正できます。

Prometheus v2.25.0では、新しいPromQL修飾子「@」が導入されました。offset修飾子がベクターセレクター、範囲ベクターセレクター、およびサブクエリの評価を評価時間に対して固定期間だけオフセットする方法と同様に、「@」修飾子を使用すると、クエリ評価時間に関わらず、これらのセレクターの評価を固定できます。この構文の考案者はBjörn Rabensteinです。

<vector-selector> @ <timestamp>
<range-vector-selector> @ <timestamp>
<subquery> @ <timestamp>

<timestamp>はUnixタイムスタンプであり、浮動小数点リテラルで記述されます。

たとえば、クエリhttp_requests_total @ 1609746000は、2021-01-04T07:40:00+00:00時点のhttp_requests_totalの値を返します。クエリrate(http_requests_total[5m] @ 1609746000)は、同じ時点でのhttp_requests_totalの5分間のレートを返します。

さらに、start()end()も「@」修飾子の値として特別な値として使用できます。範囲クエリの場合、それぞれ範囲クエリの開始と終了に解決され、すべてのステップで同じままになります。インスタントクエリの場合、start()end()はどちらも評価時間に解決されます。

topk()の修正に戻ると、次のクエリは、過去1時間のレートが上位5位以内だったシリーズのhttp_requests_totalの1分間のレートをプロットします。したがって、正確にk個の結果をプロットする範囲クエリとしても、topk()を意味のあるものにすることができます。

rate(http_requests_total[1m]) # This acts like the actual selector.
  and
topk(5, rate(http_requests_total[1h] @ end())) # This acts like a ranking function which filters the selector.

同様に、topk()ランキングは、現在インスタントクエリとしてのみ意味を持つhistogram_quantile()などの他の関数で置き換えることができます。rate()<aggregation>_over_time()などで置き換えることができます。この新しい修飾子の使用方法をお知らせください!

「@」修飾子はデフォルトで無効になっており、--enable-feature=promql-at-modifierフラグを使用して有効にできます。機能フラッグの詳細についてはこのブログ記事をご覧ください。「@」修飾子のドキュメントはこちらをご覧ください