Prometheusの共同作成者Julius Volzの記事

前書き

プロメテウスは、オープンソースの監視システムおよび時系列データベースです。 リンク:/ community / tutorials / how-to-query-prometheus-on-ubuntu-14-04-part-1 [Ubuntu 14.04パート1でPrometheusをクエリする方法]では、合成メトリックを公開する3つのデモサービスインスタンスを設定します。 Prometheusサーバー。 次に、これらのメトリックを使用して、Prometheusクエリ言語を使用して時系列を選択およびフィルタリングする方法、ディメンション全体を集計する方法、およびレートと導関数を計算する方法を学びました。

このチュートリアルの第2部では、第1部のセットアップに基づいて、より高度なクエリ技術とパターンを学習します。 このチュートリアルの後、値ベースのフィルタリング、セット操作、ヒストグラムなどを適用する方法を学びます。

前提条件

このチュートリアルは、リンク:/ community / tutorials / how-to-query-prometheus-on-ubuntu-14-04-part-1 [Ubuntu 14.04パート1でPrometheusを照会する方法]で説明されているセットアップに基づいています。 少なくとも、そのチュートリアルのステップ1とステップ2に従って、Prometheusサーバーと3つの監視対象デモサービスインスタンスをセットアップする必要があります。 ただし、第1部で説明したクエリ言語のテクニックを基に構築するため、完全に作業することをお勧めします。

ステップ1-値によるフィルタリングとしきい値の使用

このセクションでは、返された時系列を値に基づいてフィルタリングする方法を学習します。

値ベースのフィルタリングの最も一般的な用途は、単純な数値のアラートしきい値です。 たとえば、過去15分間の平均で、毎秒0.2よりも高い合計「500」ステータスリクエストレートを持つHTTPパスを見つけることができます。 これを行うには、すべての「500」ステータスリクエストレートを照会し、式の最後に「> 0.2」フィルター演算子を追加します。

rate(demo_api_request_duration_seconds_count{status="500",job="demo"}[15m]) > 0.2
  • Console *ビューでは、結果は次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/filter_rates_scalar.png [スカラー番号によるリクエストレートのフィルタリング]

ただし、2進算術の場合と同様に、Prometheusは単一のスカラー数によるフィルタリングのみをサポートしていません。 時系列の別のセットに基づいて、時系列の1つのセットをフィルター処理することもできます。 繰り返しますが、要素はラベルセットで照合され、一致する要素間にフィルター演算子が適用されます。 フィルターを通過する右側の要素と一致する左側の要素のみが出力の一部になります。 + on(<labels>)++ group_left(<labels>)+、 `+ group_right(<labels>)+`句は、算術演算子と同じように機能します。

たとえば、「+ 200+」ステータスレートである「+ job 」、「 instance 」、「 method 」、および「 path 」の組み合わせに対して、「 500+」ステータスレートを選択できます。次のように、「+ 500+」ステータスレートの少なくとも50倍ではありません。

   rate(demo_api_request_duration_seconds_count{status="500",job="demo"}[5m]) * 50
> on(job, instance, method, path)
   rate(demo_api_request_duration_seconds_count{status="200",job="demo"}[5m])

これは次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/series.png [シリーズの他のセットによるリクエストレートのフィルタリング]

+> +`の他に、Prometheusは通常の `+> = ++ ⇐ ++ <++!= +、および `+ == +`比較演算子もサポートしています。フィルタリングで。

これで、単一の数値またはラベルが一致する別の時系列値のセットに基づいて、時系列のセットをフィルター処理する方法がわかりました。

ステップ2-セット演算子の使用

このセクションでは、プロメテウスの集合演算子を使用して時系列のセットを相互に関連付ける方法を学習します。

多くの場合、1つの時系列セットを別のセットに基づいてフィルタリングする必要があります。 このために、Prometheusは `+ and +`セット演算子を提供します。 演算子の左側にあるすべてのシリーズについて、同じラベルを持つ右側のシリーズを見つけようとします。 一致が見つかった場合、左側のシリーズが出力の一部になります。 右側に一致するシリーズが存在しない場合、そのシリーズは出力から省略されます。

たとえば、90パーセンタイルのレイテンシが50ミリ秒(0.05秒)を超えるHTTPエンドポイントを選択したい場合がありますが、これは1秒間に複数のリクエストを受信するディメンションの組み合わせに対してのみです。 ここでは、パーセンタイルの計算に `+ histogram_quantile()+`関数を使用します。 次のセクションでこの機能が正確に機能することを説明します。 今のところ、各サブディメンションの90パーセンタイルレイテンシを計算することだけが重要です。 結果の悪いレイテンシーをフィルタリングし、1秒に複数のリクエストを受信するレイテンシーのみを保持するために、次のクエリを実行できます。

   histogram_quantile(0.9, rate(demo_api_request_duration_seconds_bucket{job="demo"}[5m])) > 0.05
and
   rate(demo_api_request_duration_seconds_count{job="demo"}[5m]) > 1

image:https://assets.digitalocean.com/articles/prometheus_querying/intersection.png [交差点によるリクエスト率のフィルタリング]

交差点をとる代わりに、時系列の2つのセットから結合を構築したい場合があります。 プロメテウスはこれのために `+ or +`集合演算子を提供します。 その結果、操作の左側のシリーズと、左側に一致するラベルセットがない右側のシリーズが作成されます。 たとえば、10未満または30を超えるすべてのリクエストレートをリストするには、次のクエリを実行します。

   rate(demo_api_request_duration_seconds_count{job="demo"}[5m]) < 10
or
   rate(demo_api_request_duration_seconds_count{job="demo"}[5m]) > 30

結果はグラフで次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/union.png [2組のリクエストレートから組合を作成する]

ご覧のとおり、グラフで値フィルターとセット操作を使用すると、グラフに沿った任意のタイムステップでフィルターに一致するかどうかによって、同じグラフ内で時系列が表示または非表示になります。 通常、この種類のフィルターロジックの使用は、アラートルールに対してのみ推奨されます。

これで、ラベル付き時系列から交差点と結合を作成する方法がわかりました。

ステップ3-ヒストグラムの操作

このセクションでは、ヒストグラムメトリックの解釈方法と、それらからの分位数(パーセンタイルの一般化形式)の計算方法を学習します。

Prometheusはヒストグラムメトリックをサポートしています。これにより、サービスは一連の値の分布を記録できます。 ヒストグラムは通常、リクエストのレイテンシや応答サイズなどの測定値を追跡しますが、何らかの分布に応じて大きさが変動する値を基本的に追跡できます。 プロメテウスヒストグラムは、クライアント側で_sample_データをヒストグラム化します。つまり、多くの構成可能な(たとえば、 レイテンシ)バケットを作成し、それらのバケットを個々の時系列として公開します。

内部的に、ヒストグラムは時系列のグループとして実装され、それぞれが特定のバケットのカウントを表します(例: 「10ms未満のリクエスト」、「25ms未満のリクエスト」、「50ms未満のリクエスト」など)。 バケットカウンターは累積的です。つまり、大きい値のバケットには、低い値のすべてのバケットのカウントが含まれます。 ヒストグラムの一部である各時系列では、対応するバケットは特別な「+ le +」(より小か等しい)ラベルで示されます。 これにより、既に追跡している既存のディメンションに追加のディメンションが追加されます。

たとえば、デモサービスは、APIリクエストの継続時間の分布を追跡するヒストグラム「+ demo_api_request_duration_seconds_bucket +」をエクスポートします。 このヒストグラムは、追跡されたサブディメンションごとに26バケットをエクスポートするため、このメトリックには多くの時系列があります。 最初に、1つのインスタンスからの1種類のリクエストのみの生のヒストグラムを見てみましょう。

demo_api_request_duration_seconds_bucket{instance="localhost:8080",method="POST",path="/api/bar",status="200",job="demo"}

`+ le +`ラベルで識別される1つの観測バケットを表す26のシリーズが表示されます。

image:https://assets.digitalocean.com/articles/prometheus_querying/histogram.png [生のヒストグラムシリーズ]

ヒストグラムを使用すると、「リクエストの完了に100ミリ秒以上かかるリクエストの数」などの質問に答えるのに役立ちます(100ミリ秒の境界を持つバケットが構成されている場合)。 一方、「クエリの99%が完了するレイテンシーはどれくらいですか?」などの関連する質問に答えたいと思うことがよくあります。 ヒストグラムバケットが十分にきめ細かい場合、 `+ histogram_quantile()`関数を使用してこれを計算できます。 この関数は、入力としてヒストグラムメトリック( ` le `バケットラベルを持つシリーズのグループ)を期待し、対応する分位を出力します。 0から100パーセンタイルの範囲のパーセンタイルとは対照的に、 ` histogram_quantile()`関数が入力として期待するターゲット変位値の仕様は、 ` 0 `から ` 1 `の範囲です(したがって90パーセンタイルは、「 0.9+」の分位に対応します)。

たとえば、次のようにすべてのディメンションについて、すべての時間で90パーセンタイルのAPIレイテンシを計算できます。

# BAD!
histogram_quantile(0.9, demo_api_request_duration_seconds_bucket{job="demo"})

これはあまり有用でも信頼性もありません。 個々のサービスインスタンスが再起動されると、バケットカウンターがリセットされます。通常、メトリック全体ではなく、「現在」の遅延(たとえば、過去5分間の測定値)を確認する必要があります。 これを実現するには、基礎となるヒストグラムバケットカウンターに「+ rate()+」関数を適用します。これは、カウンターのリセットを処理し、指定された時間枠での各バケットの増加率のみを考慮します。

次のように、過去5分間の90パーセンタイルAPIレイテンシを計算します。

# GOOD!
histogram_quantile(0.9, rate(demo_api_request_duration_seconds_bucket{job="demo"}[5m]))

これははるかに優れており、次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/quantiles_all.png [すべてのリクエストディメンションの計算された変位値]

ただし、これは、_eveeey_サブディメンションの90パーセンタイル( + job ++ instance、` + path`、 + method n、および` + status + `)を示しています。 繰り返しますが、これらのディメンションのすべてに興味があるわけではなく、それらの一部を集約したい場合があります。 幸いなことに、Prometheusの「+ sum 」集計演算子を「 histogram_quantile()+」関数と組み合わせて、クエリ時にディメンション全体を集計できます。

次のクエリは90パーセンタイルのレイテンシを計算しますが、結果を分割するのは「+ job 」、「 instance 」、および「 path +」ディメンションのみです。

histogram_quantile(
 0.9,
 sum without(status, method) (
   rate(demo_api_request_duration_seconds_bucket{job="demo"}[5m])
 )
)

グラフは次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/quantiles_some.png [一部のリクエストディメンションの計算された変位値]

ヒストグラムから分位値を計算すると、常にある程度の統計誤差が生じます。 このエラーは、バケットサイズ、観測値の分布、および計算する目標変位値に依存します。 これについて詳しくは、Prometheusのドキュメントのhttp://prometheus.io/docs/practices/histograms/#errors-of-quantile-estimation [変位値推定のエラー]をご覧ください。

これで、ヒストグラムメトリックの解釈方法と、さまざまな時間範囲のヒストグラムメトリックから変位値を計算する方法と、いくつかのディメンションをオンザフライで集約する方法がわかりました。

ステップ4-タイムスタンプメトリックの使用

このセクションでは、タイムスタンプを含むメトリックを利用する方法を学びます。

Prometheusエコシステムのコンポーネントは、タイムスタンプを頻繁に公開します。 たとえば、これは、バッチジョブが正常に完了した最後の時間、構成ファイルが正常に再ロードされた最後の時間、またはマシンが起動された時間です。 慣例により、時刻は、1970年1月1日UTCからの秒数でhttps://en.wikipedia.org/wiki/Unix_time[Unixタイムスタンプ]として表されます。

たとえば、デモサービスは、シミュレートされたバッチジョブが成功した最後の時間を公開します。

demo_batch_last_success_timestamp_seconds{job="demo"}

このバッチジョブは1分に1回実行されるようにシミュレートされていますが、すべての試行の25%で失敗します。 失敗した場合、 `+ demo_batch_last_success_timestamp_seconds +`メトリックは、別の実行が成功するまで最後の値を保持します。

生のタイムスタンプをグラフ化すると、次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/raw_timestamp_data.png [生のタイムスタンプグラフ]

ご覧のとおり、通常、生のタイムスタンプ値はそれ自体ではあまり役に立ちません。 代わりに、タイムスタンプ値の古さを知りたいことがよくあります。 一般的なパターンは、 `+ time()+`関数によって提供されるように、現在の時刻からメトリックのタイムスタンプを減算することです:

time() - demo_batch_last_success_timestamp_seconds{job="demo"}

これにより、最後に成功したバッチジョブが実行されてからの秒数が得られます。

image:https://assets.digitalocean.com/articles/prometheus_querying/timestamp_age_graph.jpg [タイムスタンプ年齢グラフ]

この経過時間を秒から時間に変換する場合、結果を「3600」で除算できます。

(time() - demo_batch_last_success_timestamp_seconds{job="demo"}) / 3600

このような式は、グラフ化と警告の両方に役立ちます。 上記のようにタイムスタンプの経過時間を視覚化すると、バッチジョブが正常に完了すると、直線的に増加する線と「0」への定期的なリセットを含む鋸歯状グラフが表示されます。 ノコギリ波のスパイクが大きくなりすぎる場合、これはバッチジョブが長時間完了していないことを示します。 また、式に「+> +」しきい値フィルターを追加し、結果の時系列でアラートを出すことでこれについてアラートを出すこともできます(ただし、このチュートリアルではアラートルールについては説明しません)。

過去1.5分間にバッチジョブが完了しなかったインスタンスを単純にリストするには、次のクエリを実行できます。

time() - demo_batch_last_success_timestamp_seconds{job="demo"} > 1.5 * 60

image:https://assets.digitalocean.com/articles/prometheus_querying/batch_jobs.png [背後にあるバッチジョブの表示]

これで、生のタイムスタンプメトリックを相対的な年齢に変換する方法がわかりました。これは、グラフ化とアラートの両方に役立ちます。

ステップ5-topk / bottomk関数のソートと使用

この手順では、クエリ出力を並べ替えるか、一連のシリーズの最大値または最小値のみを選択する方法を学習します。

表形式の* Console *ビューでは、出力シリーズを値でソートすると便利な場合があります。 これを実現するには、 + sort()+(昇順ソート)および + sort_desc()+(降順ソート)関数を使用します。 たとえば、パスごとのリクエストレートを値の高い順に並べて表示するには、次のクエリを実行できます。

sort_desc(sum by(path) (rate(demo_api_request_duration_seconds_count{job="demo"}[5m])))

ソートされた出力は次のようになります。

image:https://assets.digitalocean.com/articles/prometheus_querying/sorted_request_rates.png [ソートされたリクエスト率]

または、すべてのシリーズを表示するのではなく、Kの最大シリーズまたは最小シリーズのみを表示することにも興味があります。 このために、Prometheusは `+ topk()`および ` bottomk()+`関数を提供します。 これらはそれぞれ、K値(選択するシリーズの数)と、フィルター処理する必要がある時系列のセットを返す任意の式を取ります。 たとえば、パスとメソッドごとに上位3つのリクエストレートのみを表示するには、次のクエリを実行できます。

topk(3, sum by(path, method) (rate(demo_api_request_duration_seconds_count{job="demo"}[5m])))

image:https://assets.digitalocean.com/articles/prometheus_querying/top_3_request_rates.png [上位3つのリクエスト率]

  • Console *ビューでは並べ替えが_唯一_便利ですが、グラフでは `+ topk()`と ` bottomk()+`も便利です。 出力は、グラフの時間範囲全体にわたって平均された上位または下位のKシリーズを表示しないことに注意してください-代わりに、出力はグラフに沿ったすべての解像度ステップに対して上位または下位のK出力シリーズを再計算します。 したがって、実際にはグラフの範囲で上位または下位のKシリーズが変化する可能性があり、グラフには合計でKシリーズ以上が表示される場合があります。

ここで、K個の最大または最小シリーズをソートする方法または選択する方法のみを学習しました。

ステップ6-スクレイピングされたインスタンスの状態を検査する

このステップでは、時間の経過とともにインスタンスのスクレイプ状態を検査する方法を学習します。

セクションをさらに面白くするために、3つのバックグラウンドデモサービスインスタンス(ポート8080でリッスンしているインスタンス)の最初を終了しましょう。

pkill -f -- -listen-address=:8080

Prometheusはターゲットをスクレイプするたびに、メトリック名「+ up 」、スクレイプされたインスタンスの「 job 」および「 instance 」ラベルを持つ合成サンプルを保存します。 スクレイプが成功した場合、サンプルの値は「+1」に設定されます。 スクレイプが失敗すると、「+ 0+」に設定されます。 したがって、どのインスタンスが現在「アップ」または「ダウン」しているかを簡単に照会できます。

up{job="demo"}

これにより、1つのインスタンスがダウンとして表示されます。

image:https://assets.digitalocean.com/articles/prometheus_querying/instance_health.png [インスタンスの状態を表示]

only downインスタンスを表示するには、値「0」でフィルタリングできます。

up{job="demo"} == 0

終了したインスタンスのみが表示されるはずです。

image:https://assets.digitalocean.com/articles/prometheus_querying/down_instances.png [インスタンスの表示]

または、ダウンしたインスタンスの合計数を取得するには:

count by(job) (up{job="demo"} == 0)

これにより、 `+ 1 +`のカウントが表示されます。

image:https://assets.digitalocean.com/articles/prometheus_querying/down_instance_count.png [インスタンス数の表示]

これらの種類のクエリは、基本的なスクレイプヘルスアラートに役立ちます。

これで、インスタンスのヘルス状態を照会する方法がわかりました。

結論

このチュートリアルでは、リンクの進捗状況に基づいて構築しました:/ community / tutorials / how-to-query-prometheus-on-ubuntu-14-04-part-1 [Ubuntu 14.04パート1でPrometheusをクエリする方法]高度なクエリ技術とパターン。 値に基づいてシリーズをフィルタリングする方法、ヒストグラムから分位数を計算する方法、タイムスタンプベースのメトリックを扱う方法などを学びました。

これらのチュートリアルでは、可能なすべてのクエリユースケースをカバーすることはできませんが、Prometheusを使用して実際のクエリ、ダッシュボード、およびアラートを作成するときに、サンプルクエリが役立つことを願っています。 Prometheusのクエリ言語の詳細については、http://prometheus.io/docs/querying/basics/ [Prometheusクエリ言語のドキュメント]をご覧ください。