標準出力を捨てて標準エラーだけパイプで渡すには ​

目的

​ 例えば、以下のようなプログラムがあったとして、"error"だけリダイレクトしたい ​

bin/stdouterr.rb

STDOUT.puts "data"
STDERR.puts "error"

方法

  • サブシェルで標準出力を/dev/nullに捨てる
  • サブシェルの標準エラーをリダイレクトする ​
(ruby bin/stdouterr.rb > /dev/null) 2>&1 | less

​ ​

jobの分け方ベストプラクティス - Prometheusドキュメント

このページはPrometheus公式ドキュメント和訳+αの一部です。

jobラベルは何のためにあるか?

jobラベルはターゲットに必ず付いているラベルの1つである。どうこれを使うことができるか?

jobラベルは、ターゲットのリラベルの後でjobラベルがなければ設定項目job_nameが利用されるので、特別である。 このようにしてターゲットは必ずjobラベルを持つことになる。

では、どうやってこれを最大限に活用するべきか? オススメは、同じことをするアプリケーション(これはほぼ常に、同じバイナリを完全に同じ設定で動かしているプロセスのことを意味している)を整理するためにjobラベルを使うことである。 例えば、job="frontend"でwebのフロントエンドがあり、job="redis"でキャッシュとして利用されるRedisがあるとする。 このようなラベルを利用すると、jobに渡って集約することが容易になる。 例えば、jobあたりのCPU利用率はsum by (job)(rate(process_cpu_seconds_total[5m]))となるだろう。 これに対して、Kubernetes上で動くプロセス全てにjob="kubernetes"を付けても特に役に立たない。もっと意味のあるjobラベルを目指すべきである。

もし、異なる目的に対して異なるRedisサーバー群を稼働させているなら、それぞれのサーバー群に対して異なるjobラベルを付けるのが理にかなっているだろう。 それぞれのサーバー群は結局、異なるパフォーマンス特性を持つ可能性が高く、それらを一緒くたに集約して役に立つことは恐らくないだろう。 もし、サーバー群に下位区分(シャーディングなど)があるなら、shardや類似のラベルを追加してジョブを区分するのが多くの場合理に適っている。

避けるべきなのは、プロセスのバイナリと設定のようなもの以上の情報をjobラベルで表現することである。 例えば、本番環境を開発・ステージング環境から区別するには、job="redis_production"とするのではなく、別にenv="production"を付ける方が良いだろう。 これによって、ラベル値に対する正規表現に頼る必要なしに、環境を跨いだ計算が簡単になる。

参考リンク

おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

和訳活動の支援

Prometheusドキュメント和訳が役に立った方は、以下QRコードからPayPayで活動を支援して頂けるとありがたいです。

PayPayによる支援用QRコード
上のQRコードからPayPayによる支援

テンプレートの例 - Prometheusドキュメント

このページはPrometheus公式ドキュメント和訳+αの一部です。

TEMPLATE EXAMPLES

Prometheusは、コンソールページと同様に、アラートのアノテーションとラベルでテンプレートをサポートしている。 テンプレートで、ローカルのデータベースに対してクエリを実行したり、繰り返し処理、条件分岐、フォーマットなどをすることが出来る。 Prometheusのテンプレート言語はGoのテンプレートシステムに基づいている。

Simple alert field templates

alert: InstanceDown
expr: up == 0
for: 5m
labels:
  severity: page
annotations:
  summary: "Instance {{$labels.instance}} down"
  description: "{{$labels.instance}} of job {{$labels.job}} has been down for more than 5 minutes."

アラートのフィールドのテンプレートは、起きたアラートそれぞれに対して各ルールに対する反復処理の中で実行されるので、どのクエリも軽量に保つこと。 アラートのためにより込み入ったテンプレート必要な場合、代わりにコンソールへリンクすることを推奨する。

単純な繰り返し

インスタンスのリストとそれがupかどうかのリストを表示する。

{{ range query "up" }}
  {{ .Labels.instance }} {{ .Value }}
{{ end }}

特殊変数.は、各ループでのサンプル値が含まれる。

値の表示

{{ with query "some_metric{instance='someinstance'}" }}
  {{ . | first | value | humanize }}
{{ end }}

GoおよびGoのテンプレート言語はどちらも強く型付けされているので、実行エラーを避けるためにサンプルが返されたことをチェックしなければならない。 例えば、スクレイプやルールの評価がまだ実行されていないあるいはホストがダウンしている場合にこうしたことが起きる。

インクルードされたテンプレートprom_query_drilldownはこの処理をし、結果をフォーマットし、expressionブラウザにリンクする。

コンソールURLパラメーターの利用

{{ with printf "node_memory_MemTotal{job='node',instance='%s'}" .Params.instance | query }}
  {{ . | first | value | humanize1024}}B
{{ end }}

console.html?instance=hostnameとしてアクセスされると、.Params.instanceは、hostnameになる。

高度な繰り返し

<table>
{{ range printf "node_network_receive_bytes{job='node',instance='%s',device!='lo'}" .Params.instance | query | sortByLabel "device"}}
  <tr><th colspan=2>{{ .Labels.device }}</th></tr>
  <tr>
    <td>Received</td>
    <td>{{ with printf "rate(node_network_receive_bytes{job='node',instance='%s',device='%s'}[5m])" .Labels.instance .Labels.device | query }}{{ . | first | value | humanize }}B/s{{end}}</td>
  </tr>
  <tr>
    <td>Transmitted</td>
    <td>{{ with printf "rate(node_network_transmit_bytes{job='node',instance='%s',device='%s'}[5m])" .Labels.instance .Labels.device | query }}{{ . | first | value | humanize }}B/s{{end}}</td>
  </tr>{{ end }}
<table>

ここでは、全ネットワークデバイスについて繰り返し処理をして、それぞれのネットワークトラフィックを表示している。

rangeアクションが変数を指定していないので、.がループ変数となり、ループ内では.Params.instanceは利用できない。

再利用可能なテンプレートの定義

Prometheusは、再利用可能なテンプレートの定義をサポートしている。 これはコンソールライブラリと組み合わせると特に強力で、複数のコンソールにまたがってテンプレートを共有出来るようになる。

{{/* Define the template */}}
{{define "myTemplate"}}
  do something
{{end}}

{{/* Use the template */}}
{{template "myTemplate"}}

テンプレートは、引数が1つに制限されている。複数の引数をまとめるために、関数argsを利用することが出来る。

{{define "myMultiArgTemplate"}}
  First argument: {{.arg0}}
  Second argument: {{.arg1}}
{{end}}
{{template "myMultiArgTemplate" (args 1 2)}}

参考リンク

おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

和訳活動の支援

Prometheusドキュメント和訳が役に立った方は、以下QRコードからPayPayで活動を支援して頂けるとありがたいです。

PayPayによる支援用QRコード
上のQRコードからPayPayによる支援

コンソールテンプレート - Prometheusドキュメント

このページはPrometheus公式ドキュメント和訳+αの一部です。

コンソールテンプレート

コンソールテンプレートによって、Go templating languageで書かれた任意のコンソールを作成することができる。

コンソールテンプレートは、簡単にバージョン管理できるテンプレートを作成する最も強力な方法である。ただ、学習コストは高いので、このスタイルの監視に慣れていないユーザーは、まずGrafanaを試すのが良い。

Getting started

Prometheusには、コンソールのサンプルセットがある。これらは稼働しているPrometheusの/consoles/index.html.exampleで見ることができ、 Node Exporterがjob="node"というラベルでscrapeしているなら、Node Exporterのコンソールを表示する。

このサンプルコンソールは、5つの部分からなる

  • 上部のナビゲーションバー
  • 左側のメニュー
  • 下部の時間コントロール
  • 中央のメインコンテンツ(普通はグラフ)
  • 右側の表

ナビゲーションバーは、他のPrometheusなどの他システム、ドキュメントなどへのリンクである。メニューは、そのPrometheusサーバー自体の中のナビゲーションに用い、コンソールを新しいタブで開いて情報の相互関連性を見るために便利である。どちらもconsole_libraries/menu.libで設定することが出来る。

時間コントロールによって、グラフの間隔と幅を変更することが出来る。コンソールのURLは共有することが出来て、他の人にも同じグラフを表示する。

メインコンテンツは、普通はグラフである。設定可能なJavaScriptのグラフライブラリが提供されていて、PrometheusからのデータのリクエストとRickshawを通した描画が出来る。

最後に、右側の表は、グラフよりコンパクトに統計情報を表示するために利用できる。

サンプルコンソール

これは、基本的なコンソールで、右側の表にタスクの数、いくつのタスクがupか、平均メモリ使用量を表示し、メインコンテンツとして毎秒のクエリ数のグラフを表示する。

{{template "head" .}}

{{template "prom_right_table_head"}}
<tr>
  <th>MyJob</th>
  <th>{{ template "prom_query_drilldown" (args "sum(up{job='myjob'})") }}
      / {{ template "prom_query_drilldown" (args "count(up{job='myjob'})") }}
  </th>
</tr>
<tr>
  <td>CPU</td>
  <td>{{ template "prom_query_drilldown" (args
      "avg by(job)(rate(process_cpu_seconds_total{job='myjob'}[5m]))"
      "s/s" "humanizeNoSmallPrefix") }}
  </td>
</tr>
<tr>
  <td>Memory</td>
  <td>{{ template "prom_query_drilldown" (args
       "avg by(job)(process_resident_memory_bytes{job='myjob'})"
       "B" "humanize1024") }}
  </td>
</tr>
{{template "prom_right_table_tail"}}


{{template "prom_content_head" .}}
<h1>MyJob</h1>

<h3>Queries</h3>
<div id="queryGraph"></div>
<script>
new PromConsole.Graph({
  node: document.querySelector("#queryGraph"),
  expr: "sum(rate(http_query_count{job='myjob'}[5m]))",
  name: "Queries",
  yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
  yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
  yUnits: "/s",
  yTitle: "Queries"
})
</script>

{{template "prom_content_tail" .}}

{{template "tail"}}

prom_right_table_headprom_right_table_tailテンプレートは、右側の表を含んでいる。これは必須ではない。

prom_query_drilldownは、渡された式を評価し、フォーマットし、expression browserの式へリンクするテンプレートである。 第1引数が式で、第2引数は単位、第3引数は出力のフォーマット方法である。第1引数のみ必須である。

prom_query_drilldownの第3引数の正当な出力フォーマットは以下の通り。

  • Not specified: Default Go display output.
  • humanize: 結果をSI接頭辞を用いて表示
  • humanizeNoSmallPrefix: 1より大きな値はSI接頭辞を用いて表示、1より小さな値は3桁表示。これは、humanizeで生成されるmilliqueries per secondのような単位を避けるために便利である
  • humanize1024: 1000ではなく1024を底としたhumanize同様の表示をする。これは、KiBMiBのような単位を生成するために、Bを第2引数にしたときによく利用される。
  • printf.3g: 3桁表示

カスタムのフォーマットも定義できる。サンプルは、prom.libを参照のこと。

グラフライブラリ

グラフライブラリは次のように呼び出す。

<div id="queryGraph"></div>
<script>
new PromConsole.Graph({
  node: document.querySelector("#queryGraph"),
  expr: "sum(rate(http_query_count{job='myjob'}[5m]))"
})
</script>

headテンプレートが必要なJavaScriptCSSをロードする。

グラフライブラリのパラメーター

  • expr
    • Required.
    • グラフにする式。リストも可
  • node
    • Required.
    • 描画するためのDOMノード
  • duration
    • Optional.
    • グラフの期間。デフォルトは1時間
  • endTime
    • Optional.
    • グラフの最後のunixtime。デフォルトは現在
  • width
    • Optional.
    • グラフの幅(タイトルを除く)。デフォルトは、自動検出
  • height
    • Optional.
    • グラフの高さ(タイトルと凡例を除く)。デフォルトは200ピクセル
  • min
    • Optional.
    • X軸最小値。デフォルトは、データの最低値。
  • max
    • Optional.
    • Y軸最大値。デフォルトは、データの最高値。
  • renderer
    • Optional.
    • グラフの種類。lineまたはarea。デフォルトは、line
  • name
    • Optional.
    • 凡例とhover detailで使われるプロットのタイトル。文字列が渡された場合、[[ label ]]はラベルの値で置換される。関数が渡された場合、ラベルのマップが渡されるので、文字列として名前を返すこと。リストも可
  • xTitle
    • Optional.
    • X軸のタイトル。デフォルトはTime
  • yUnits
    • Optional.
    • Y軸の単位。デフォルトは、空。
  • yTitle
    • Optional.
    • Y軸のタイトル。デフォルトは、空。
  • yAxisFormatter
    • Optional.
    • Y軸の数値のフォーマッター。デフォルトは、PromConsole.NumberFormatter.humanize
  • yHoverFormatter
    • Optional.
    • hover detailの数値のフォーマッター。デフォルトは、PromConsole.NumberFormatter.humanizeExact
  • colorScheme
    • Optional.
    • プロットで利用されるカラースキーム。hex color codeのリストまたはRickshawでサポートされているカラースキーム名。デフォルトは、'colorwheel'

exprnameの両方がリストの場合、両者は同じ長さでなければならない。nameは、対応する式のプロットに適用される。

yAxisFormatteryHoverFormatterの正当なオプションは以下の通り。

  • PromConsole.NumberFormatter.humanize: SI接頭辞を用いたフォーマット
  • PromConsole.NumberFormatter.humanizeNoSmallPrefix: 1より大きな値はSI接頭辞を用いてフォーマット、1より小さな値は3桁を用いたフォーマット。これは、humanizeで生成されるmilliqueries per secondのような単位を避けるために便利である
  • PromConsole.NumberFormatter.humanize1024: 1000ではなく1024を底としたhumanize同様のフォーマット

参考リンク

おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

和訳活動の支援

Prometheusドキュメント和訳が役に立った方は、以下QRコードからPayPayで活動を支援して頂けるとありがたいです。

PayPayによる支援用QRコード
上のQRコードからPayPayによる支援

HTTP API - Prometheusドキュメント

このページはPrometheus公式ドキュメント和訳+αの一部です。

HTTP API

現状の安定版HTTP APIは、Prometheusサーバーの/api/v1でアクセスできる。 非破壊的な追加がこのエンドポイントに追加されることがある。

フォーマット概要

成功したAPIリクエストはステータスコード2xxを返す。

APIハンドラに届いた不正なリクエストは、JSONエラーオブジェクトと以下のHTTPレスポンスコードの1つを返す。

  • 400 Bad Request パラメーターが欠けていたり間違っている場合
  • 422 Unprocessable Entity 式が実行できない場合(RFC4918)
  • 503 Service Unavailable クエリがタイムアウトしたりアボートした場合

APIエンドポイントに到達する前に起きたエラーに対しては、2xxでない他のコードが返される場合もある。

リクエストの実行を妨げなかったエラーがあると、警告の配列が返される場合もある。 収集に成功した全てのデータは、データフィールド入れて返される。

JSONレスポンスのフォーマットは以下の通りである。

{
  "status": "success" | "error",
  "data": <data>,

  // statusがerrorの場合のみセットされる。
  // その場合でも、dataフィールドは追加のデータを保持している場合がある。
  "errorType": "<string>",
  "error": "<string>",

  // リクエスト実行中に警告があった場合のみセットされる。
  // その場合でも、dataフィールドは追加のデータを保持している場合がある。
  "warnings": ["<string>"]
}

入力のタイムスタンプは、RFC3339のフォーマットまたは秒で表したUnixタイムスタンプ(オプションで秒未満の精度のために少数をつける)として与えることができる。 出力のタイムスタンプは、常に、秒で表されたUnixタイムスタンプである。

繰り返される可能性があるクエリパラメーターの名前は[]で終わる。

プレースホルダ<series_selector>は、http_requests_totalhttp_requests_total{method=~"(GET|POST)"}のような時系列セレクターを表し、URLエンコードされてなければいけない。

プレースホルダ<duration>は、[0-9]+[smhdwy]という形式の時間幅の文字列を表す。 例えば、5mは5分の時間幅を表す。

プレースホルダ<bool>は、ブール値(文字列でtruefalse)を表す。

Expression queries

クエリ言語の式は、時間のある一点で評価されるかもしれないし、時間幅に渡って評価されるかもしれない。 以下のセクションでは、それぞれのタイプのクエリのためのAPIエンドポイントについて説明する。

Instant queries

以下のエンドポイントは、時間の一点でのinstantクエリを評価する。

GET /api/v1/query

URLクエリパラメーターは以下の通り。

  • query=<string>: Prometheusのexpressionのクエリの文字列
  • time=<rfc3339 | unix_timestamp>: 評価時間(オプション)
  • timeout=<duration>: 評価のタイムアウト(オプション)。-query.timeoutフラグの値がデフォルトであり、かつ上限となる。

timeパラメーターが省略されると、現在のサーバー時間が利用される。

結果のdataセクションは以下のフォーマットである。

{
  "resultType": "matrix" | "vector" | "scalar" | "string",
  "result": <value>
}

<value>は、クエリの結果のデータを表しており、resultTypeに応じて、様々なフォーマットになる。 後述の「結果フォーマット」を参照すること。

以下の例は、式upを2015-07-01T20:10:51.781Zの時点で評価している。

$ curl 'http://localhost:9090/api/v1/query?query=up&time=2015-07-01T20:10:51.781Z'
{
   "status" : "success",
   "data" : {
      "resultType" : "vector",
      "result" : [
         {
            "metric" : {
               "__name__" : "up",
               "job" : "prometheus",
               "instance" : "localhost:9090"
            },
            "value": [ 1435781451.781, "1" ]
         },
         {
            "metric" : {
               "__name__" : "up",
               "job" : "node",
               "instance" : "localhost:9100"
            },
            "value" : [ 1435781451.781, "0" ]
         }
      ]
   }
}

Range queries

以下のエンドポイントは、ある時間幅に渡ってクエリの式を評価する。

GET /api/v1/query_range

URLクエリパラメーターは以下の通り。

  • query=<string>: Prometheusのexpressionのクエリの文字列
  • start=<rfc3339 | unix_timestamp>: 開始時刻のタイムスタンプ
  • end=<rfc3339 | unix_timestamp>: 終了時刻のタイムスタンプ
  • step=<duration | float>: クエリ解像度のステップ幅(durationフォーマットまたは秒数の少数)
  • timeout=<duration>: 評価のタイムアウト(オプション)。-query.timeoutフラグの値がデフォルトであり、かつ上限となる。

結果のdataセクションは以下のフォーマットである。

{
  "resultType": "matrix",
  "result": <value>
}

プレイスホルダー<value>のフォーマットについては、range-vector結果フォーマットを参照すること。

以下の例は、式upを30秒の時間幅にかけて15秒の解像度で評価している。

$ curl 'http://localhost:9090/api/v1/query_range?query=up&start=2015-07-01T20:10:30.781Z&end=2015-07-01T20:11:00.781Z&step=15s'
{
   "status" : "success",
   "data" : {
      "resultType" : "matrix",
      "result" : [
         {
            "metric" : {
               "__name__" : "up",
               "job" : "prometheus",
               "instance" : "localhost:9090"
            },
            "values" : [
               [ 1435781430.781, "1" ],
               [ 1435781445.781, "1" ],
               [ 1435781460.781, "1" ]
            ]
         },
         {
            "metric" : {
               "__name__" : "up",
               "job" : "node",
               "instance" : "localhost:9091"
            },
            "values" : [
               [ 1435781430.781, "0" ],
               [ 1435781445.781, "0" ],
               [ 1435781460.781, "1" ]
            ]
         }
      ]
   }
}

メタデータのクエリ

ラベルマッチャーによる時系列の検索

以下のエンドポイントはラベル集合にマッチする時系列のリストを返す。

GET /api/v1/series

URLクエリパラメーターは以下の通り。

  • atch[]=<series_selector>: 時系列を選択するためのセレクター引数。少なくとも1つのmatch[]を指定する必要がある
  • start=<rfc3339 | unix_timestamp>: 開始時刻のタイムスタンプ
  • end=<rfc3339 | unix_timestamp>: 終了時刻のタイムスタンプ

結果のdataセクションは、各時系列を特定するラベル名/値を含むオブジェクトのリストである。

以下の例は、セレクタupまたはprocess_start_time_seconds{job="prometheus"}にマッチする全ての時系列を返す。

$ curl -g 'http://localhost:9090/api/v1/series?match[]=up&match[]=process_start_time_seconds{job="prometheus"}'
{
   "status" : "success",
   "data" : [
      {
         "__name__" : "up",
         "job" : "prometheus",
         "instance" : "localhost:9090"
      },
      {
         "__name__" : "up",
         "job" : "node",
         "instance" : "localhost:9091"
      },
      {
         "__name__" : "process_start_time_seconds",
         "job" : "prometheus",
         "instance" : "localhost:9090"
      }
   ]
}

ラベル名の取得

以下のエンドポイントはラベル名のリストを返す。

GET /api/v1/labels
POST /api/v1/labels

JSONレスポンスのdataセクションは、ラベル名の文字列のリストである。

以下に例を示す。

$ curl 'localhost:9090/api/v1/labels'
{
    "status": "success",
    "data": [
        "__name__",
        "call",
        "code",
        "config",
        "dialer_name",
        "endpoint",
        "event",
        "goversion",
        "handler",
        "instance",
        "interval",
        "job",
        "le",
        "listener_name",
        "name",
        "quantile",
        "reason",
        "role",
        "scrape_job",
        "slice",
        "version"
    ]
}

ラベル値のクエリ

以下のエンドポイントは、与えられたラベル名に対するラベル値のリストを返す。

GET /api/v1/label/<label_name>/values

JSONレスポンスのdataセクションは、ラベル値の文字列のリストである。

この例は、ラベルjobに対する全てのラベル値を取得している。

$ curl http://localhost:9090/api/v1/label/job/values
{
   "status" : "success",
   "data" : [
      "node",
      "prometheus"
   ]
}

式のクエリの結果フォーマット

式のクエリは、dataセクションのresultプロパティに以下のレスポンスを入れて返す。 プレースホルダ<sample_value>は、数値のサンプル値である。 JSONは、NaNInf-Infといった特別な値をサポートしないので、生の数値の代わりに、クオートされたJSON文字列として送信される。

Range vectors

Range vectorは、結果タイプmatrixとして返される。 対応するresultプロパティは、以下のフォーマットとなる。

[
  {
    "metric": { "<label_name>": "<label_value>", ... },
    "values": [ [ <unix_time>, "<sample_value>" ], ... ]
  },
  ...
]

Instant vectors

Instant vectorは、結果タイプvectorとして返される。 対応するresultプロパティは、以下のフォーマットとなる。

[
  {
    "metric": { "<label_name>": "<label_value>", ... },
    "value": [ <unix_time>, "<sample_value>" ]
  },
  ...
]

スカラー

スカラーは、結果タイプscalarとして返される。 対応するresultプロパティは、以下のフォーマットとなる。

[ <unix_time>, "<scalar_value>" ]

文字列

文字列は、結果タイプstringとして返される。 対応するresultプロパティは、以下のフォーマットとなる。

[ <unix_time>, "<string_value>" ]

監視対象

以下のエンドポイントは、監視対象の検出の現在の状態の概要を返す。

GET /api/v1/targets

activeなターゲットとdropされたターゲットのどちらも含まれる。 labelsは、リラベルが起きた後のラベル集合を表す。 discoveredLabelsは、サービスディスカバリーで取得したリラベリングされる前の修正されていないラベルを表す。

$ curl http://localhost:9090/api/v1/targets
{
  "status": "success",
  "data": {
    "activeTargets": [
      {
        "discoveredLabels": {
          "__address__": "127.0.0.1:9090",
          "__metrics_path__": "/metrics",
          "__scheme__": "http",
          "job": "prometheus"
        },
        "labels": {
          "instance": "127.0.0.1:9090",
          "job": "prometheus"
        },
        "scrapeUrl": "http://127.0.0.1:9090/metrics",
        "lastError": "",
        "lastScrape": "2017-01-17T15:07:44.723715405+01:00",
        "health": "up"
      }
    ],
    "droppedTargets": [
      {
        "discoveredLabels": {
          "__address__": "127.0.0.1:9100",
          "__metrics_path__": "/metrics",
          "__scheme__": "http",
          "job": "node"
        },
      }
    ]
  }
}

ルール

APIエンドポイント/rulesは、現在読み込まれているアラーティングルールとレコーディングルールのリストを返す。 Prometheusが起こした各アラーティングルールの現在activeなアラートも返す。

エンドポイント/rulesは、かなり新しいので、API v1と同じ安定性の保証はない。

GET /api/v1/rules
$ curl http://localhost:9090/api/v1/rules

{
    "data": {
        "groups": [
            {
                "rules": [
                    {
                        "alerts": [
                            {
                                "activeAt": "2018-07-04T20:27:12.60602144+02:00",
                                "annotations": {
                                    "summary": "High request latency"
                                },
                                "labels": {
                                    "alertname": "HighRequestLatency",
                                    "severity": "page"
                                },
                                "state": "firing",
                                "value": 1
                            }
                        ],
                        "annotations": {
                            "summary": "High request latency"
                        },
                        "duration": 600,
                        "health": "ok",
                        "labels": {
                            "severity": "page"
                        },
                        "name": "HighRequestLatency",
                        "query": "job:request_latency_seconds:mean5m{job=\"myjob\"} > 0.5",
                        "type": "alerting"
                    },
                    {
                        "health": "ok",
                        "name": "job:http_inprogress_requests:sum",
                        "query": "sum(http_inprogress_requests) by (job)",
                        "type": "recording"
                    }
                ],
                "file": "/rules.yaml",
                "interval": 60,
                "name": "example"
            }
        ]
    },
    "status": "success"
}

アラート

エンドポイント/alertsは、全てのactiveなアラートのリストを返す。

エンドポイント/alertsはかなり新しいので、API v1と同じ安定性の保証はない。

GET /api/v1/alerts
$ curl http://localhost:9090/api/v1/alerts

{
    "data": {
        "alerts": [
            {
                "activeAt": "2018-07-04T20:27:12.60602144+02:00",
                "annotations": {},
                "labels": {
                    "alertname": "my-alert"
                },
                "state": "firing",
                "value": 1
            }
        ]
    },
    "status": "success"
}

Querying target metadata

下記のエンドポイントは、現在取得ずみのメトリクスに関するメタデータを返す。 これは、実験的であり、将来的には変更される可能性がある。

GET /api/v1/targets/metadata

URLクエリパラメーターは以下の通り。

  • match_target=<label_selectors>: ラベル集合でターゲットとマッチングをするラベルセレクター。空にすると全てのターゲットが選択される
  • metric=<string>: メタデータを取得する対象のメトリック名。空にすると全てのメトリックのメタデータが選択される
  • limit=<number>: マッチングするターゲットの最大数

クエリの結果のdata部分は、メトリックのメタデータとターゲットのラベル集合を含むオブジェクトのリストから成る。

以下の例は、最初の2つのターゲットのメトリックgo_goroutinesでラベルjob="prometheus"を持つものに対する全てのメタデータを返す。

curl -G http://localhost:9091/api/v1/targets/metadata \
    --data-urlencode 'metric=go_goroutines' \
    --data-urlencode 'match_target={job="prometheus"}' \
    --data-urlencode 'limit=2'
{
  "status": "success",
  "data": [
    {
      "target": {
        "instance": "127.0.0.1:9090",
        "job": "prometheus"
      },
      "type": "gauge",
      "help": "Number of goroutines that currently exist.",
      "unit": ""
    },
    {
      "target": {
        "instance": "127.0.0.1:9091",
        "job": "prometheus"
      },
      "type": "gauge",
      "help": "Number of goroutines that currently exist.",
      "unit": ""
    }
  ]
}

以下の例は、ラベルinstance="127.0.0.1:9090"を持つ全てのターゲットの全てのメトリックに対するメタデータを返す。

curl -G http://localhost:9091/api/v1/targets/metadata \
    --data-urlencode 'match_target={instance="127.0.0.1:9090"}'
{
  "status": "success",
  "data": [
    // ...
    {
      "target": {
        "instance": "127.0.0.1:9090",
        "job": "prometheus"
      },
      "metric": "prometheus_treecache_zookeeper_failures_total",
      "type": "counter",
      "help": "The total number of ZooKeeper failures.",
      "unit": ""
    },
    {
      "target": {
        "instance": "127.0.0.1:9090",
        "job": "prometheus"
      },
      "metric": "prometheus_tsdb_reloads_total",
      "type": "counter",
      "help": "Number of times the database reloaded block data from disk.",
      "unit": ""
    },
    // ...
  ]
}

Alertmanagers

以下のエンドポイントは、Alertmanager検出の現在の状況の概要を返す。

GET /api/v1/alertmanagers

activeなAlertmanagerとdropされたAlertmanagerのどちらも結果に含まれる。

$ curl http://localhost:9090/api/v1/alertmanagers
{
  "status"593
  "success",
  "data": {
    "activeAlertmanagers": [
      {
        "url": "http://127.0.0.1:9090/api/v1/alerts"
      }
    ],
    "droppedAlertmanagers": [
      {
        "url": "http://127.0.0.1:9093/api/v1/alerts"
      }
    ]
  }
}

Status

以下のstatusエンドポイントは、Prometheusの設定を出力する。

Config

以下のエンドポイントは、現在読み込まれている設定ファイルを返す。

GET /api/v1/status/config

設定は、YAMLファイルのダンプとして返される。YAMLライブラリの制限で、YAMLコメントは含まれない。

$ curl http://localhost:9090/api/v1/status/config
{
  "status": "success",
  "data": {
    "yaml": "<content of the loaded config file in YAML>",
  }
}

Flags

以下のエンドポイントは、Prometheusに与えられたフラグの値を返す。

GET /api/v1/status/flags

全ての値は文字列である。

$ curl http://localhost:9090/api/v1/status/flags
{
  "status": "success",
  "data": {
    "alertmanager.notification-queue-capacity": "10000",
    "alertmanager.timeout": "10s",
    "log.level": "info",
    "query.lookback-delta": "5m",
    "query.max-concurrency": "20",
    ...
  }
}

New in v2.2

TSDB Admin APIs

これらは、上級ユーザーのためにデータベースの機能を出力するAPIである。 --web.enable-admin-apiがセットされていなければ有効ではない。

gRPC APIも公開しており、ここに定義がある。 これは、実験的なものであり、将来的には変更される可能性がある。

スナップショット

スナップショットは、TSDBのデータディレクトリの下のsnapshots/<datetime>-<rand>に全ての現在のデータのスナップショットを作成し、そのディレクトリを返す。 オプションで、ヘッドブロックだけにありまだディスクにコンパクト化されていないデータのスナップショットをスキップする。

POST /api/v1/admin/tsdb/snapshot?skip_head=<bool>
$ curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot
{
  "status": "success",
  "data": {
    "name": "20171210T211224Z-2be650b6d019eb54"
  }
}

このスナップショットは<data-dir>/snapshots/20171210T211224Z-2be650b6d019eb54にある。

New in v2.1

時系列の削除

DeleteSeriesは、ある時間幅にある選択された時系列のデータを削除する。 実際のデータはディスクに存在し続けて、その後のコンパクションで片付けられるか、Clean Tombstonesエンドポイントを叩くことで片付けられる。

成功すると204が返される。

POST /api/v1/admin/tsdb/delete_series

URLクエリパラメーターは以下の通り。

  • match[]=<series_selector>: 時系列を選択するためのセレクター引数。少なくとも1つのmatch[]を指定する必要がある
  • start=<rfc3339 | unix_timestamp>: 開始時刻のタイムスタンプ。オプションでデフォルトは可能な限り最小の時刻
  • end=<rfc3339 | unix_timestamp>: 終了時刻のタイムスタンプ。オプションでデフォルトは可能な限り最大の時刻

開始時刻と終了時刻を指定しないと、データベース中のマッチした時系列の全てのデータが削除される。

$ curl -X POST \
  -g 'http://localhost:9090/api/v1/admin/tsdb/delete_series?match[]=up&match[]=process_start_time_seconds{job="prometheus"}'

New in v2.1

Clean Tombstones

CleanTombstonesは、削除済みのデータをディスクから削除し、存在するtombstonesを一掃する。 これは、時系列を削除した後に、ディスクスペースを空けるために利用される。

成功すると204が返される。

POST /api/v1/admin/tsdb/clean_tombstones

パラメーターやレスポンスボディはない。

$ curl -XPOST http://localhost:9090/api/v1/admin/tsdb/clean_tombstones

New in v2.1

参考リンク

おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

和訳活動の支援

Prometheusドキュメント和訳が役に立った方は、以下QRコードからPayPayで活動を支援して頂けるとありがたいです。

PayPayによる支援用QRコード
上のQRコードからPayPayによる支援

recording rule ベストプラクティス - Prometheusドキュメント

このページはPrometheus公式ドキュメント和訳+αの一部です。

recording rule

レコーディングルールの一貫した命名体系によって、ルールの意味を一目で理解することが簡単になる。 また、不正確だったり意味のない計算が目立つようになり、間違いを避けることができる。

このページは、集約を正しく行うにはどうすればいいかを記し、また命名規約を提示する。

命名と集約

レコーディングルールは、一般的な形式level:metric:operationsになっているべきである。 levelは、集約レベルおよび出力されるラベルを表す。 metricは、メトリック名で、rate()irate()を利用した時に_totalを削除する以外は、変更するべきではない。 operationsは、メトリックに適用された演算のリストで、もっとも新しい演算が一番先頭に来る。

メトリック名を変更せずにしておくことで、メトリックが何か知ることが簡単になり、コードベースでの検索も簡単になる。

operationsを綺麗に保つために、sum()以外の演算がある場合は_sumを省略する。 結合性のある演算はまとめて良い(例えば、min_minminと同じである)。

利用すべき明らかな演算がない場合、sumを使う。 割り算をして比を取る場合、メトリクス名を_per_で区切り、演算はratioとする。

比を集約する場合、分母と分子を別々に集約した後、割り算をすること。 統計的に妥当ではないので、比の平均を取ったり、平均の平均をとったりしないように。

観測値の平均を計算するために、サマリーの_count_sumを集約し、割り算をする際に、それを比として扱うのは不恰好であろう。 代わりに、_count_sumという接尾辞をなくして、ratemeanで置き換えること。 これで、その時間幅の平均的な観測値を表している。

集約後に消したいラベルをwithoutで常に指定すること。 これは、jobなどの他の全てのラベルを保持することになり、コンフリクトを回避し、より有益なメトリクスやアラートが得られる。

ラベルpathを持つ秒間リクエストを集約する

- record: instance_path:requests:rate5m
  expr: rate(requests_total{job="myjob"}[5m])

- record: path:requests:rate5m
  expr: sum without (instance)(instance_path:requests:rate5m{job="myjob"})

リクエストと失敗の比を計算し、jobレベルの失敗の比に集約する。

- record: instance_path:request_failures:rate5m
  expr: rate(request_failures_total{job="myjob"}[5m])

- record: instance_path:request_failures_per_requests:ratio_rate5m
  expr: |
    (
        instance_path:request_failures:rate5m{job="myjob"}
      /
        instance_path:requests:rate5m{job="myjob"}
    )

# 分母と分子を集約し、pathレベルの比を得るために割り算する
- record: path:request_failures_per_requests:ratio_rate5m
  expr: |
    (
        sum without (instance)(instance_path:request_failures:rate5m{job="myjob"})
      /
        sum without (instance)(instance_path:requests:rate5m{job="myjob"})
    )

# メトリクス実装によって付与されたりインスタンス識別のためのラベルは残っていないので、
# レベルとして`job`を使う
- record: job:request_failures_per_requests:ratio_rate5m
  expr: |
    (
        sum without (instance, path)(instance_path:request_failures:rate5m{job="myjob"})
      /
        sum without (instance, path)(instance_path:requests:rate5m{job="myjob"})
    )

ある時間間隔の平均レイテンシーをサマリーから計算する

- record: instance_path:request_latency_seconds_count:rate5m
  expr: rate(request_latency_seconds_count{job="myjob"}[5m])

- record: instance_path:request_latency_seconds_sum:rate5m
  expr: rate(request_latency_seconds_sum{job="myjob"}[5m])

- record: instance_path:request_latency_seconds:mean5m
  expr: |
    (
        instance_path:request_latency_seconds_sum:rate5m{job="myjob"}
      /
        instance_path:request_latency_seconds_count:rate5m{job="myjob"}
    )

# 分母と分子を集約した後、割り算する
- record: path:request_latency_seconds:mean5m
  expr: |
    (
        sum without (instance)(instance_path:request_latency_seconds_sum:rate5m{job="myjob"})
      /
        sum without (instance)(instance_path:request_latency_seconds_count:rate5m{job="myjob"})
    )

関数avg()を使って、instanceとpathにまたがって平均クエリーレートが計算される

- record: job:request_latency_seconds_count:avg_rate5m
  expr: avg without (instance, path)(instance:request_latency_seconds_count:rate5m{job="myjob"})

入力されるメトリック名と比べると、withoutで指定されたラベルが出力されるメトリック名のレベルから消えていることに注意。 集約がない場合は、レベルが必ず同じになる。 そうでない場合は、ルールの中に間違いがある可能性が高い。

参考リンク

おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

和訳活動の支援

Prometheusドキュメント和訳が役に立った方は、以下QRコードからPayPayで活動を支援して頂けるとありがたいです。

PayPayによる支援用QRコード
上のQRコードからPayPayによる支援

セキュリティモデル - Prometheusドキュメント

このページはPrometheus公式ドキュメント和訳+αの一部です。

SECURITY MODEL

Prometheusは、たくさんのコンポーネントとたくさんの他システムとの連携のある複雑なシステムである。 多種多様な、信頼性のある環境と信頼性のない環境にデプロイされる可能性がある。

このページは、Prometheusの一般的なセキュリティ上の仮定と、いくつかの設定で有効になる攻撃経路について記述する。

複雑なシステムであれば何であれ、バグがないという保証することは不可能である。 もし、セキュリティのバグを見つけたら、関係するリポジトリのMAINTAINERS.mdに挙げられているメンテナー個人にレポートし、prometheus-team@googlegroups.comにCCして下さい。 私たちは、その問題を修正し、リリース日をあなたと調整し、あなたが望むなら個人名を挙げてあなたの努力に謝意を示します。

Prometheus

PrometheusのHTTPエンドポイントとログに信頼性のないユーザーからのアクセスがあることが仮定されている。 データベースに含まれる全ての時系列に加えて各種の操作/デバッグ情報にアクセスできる。

また、信頼性のあるユーザーのみが、コマンドライン、設定ファイル、Prometheusとその他のコンポーネントの実行環境に関わるその他の側面を変更する力があることが仮定されている。

どの対象を、どれぐらいの頻度で、どのような設定でスクレイプするかは、完全に設定ファイルを通して決まる。 管理者は、サービスディスカバリーからの情報を使うこともできる。 サービスディスカバリーのデータを変更することができる人なら誰にでも、その情報をリラベリングと組み合わせることで、この制御を許してしまう可能性がある。

スクレイプの対象は、信頼性のないユーザーによって実行されている可能性がある。 あるターゲットが他のターゲットのふりをするデータを出力するのがデフォルトで可能であってはいけない。 honor_labelsは、この保護を取り除いてしまう。特定のリラベルの設定も同じことが起きてしまう可能性がある。

Prometheus 2.0以降では、フラグ--web.enable-admin-apiが、時系列削除などの機能を含む管理用のHTTP APIへのアクセスを制御する。 これはデフォルトで無効にされている。 有効化されると、管理用で変更を伴う機能が、パス/api/*/admin/以下でアクセス可能になる。 フラグ--web.enable-lifecycleは、Prometheusの再読み込みと停止を制御する。 これもデフォルトでは無効になっている。 有効になっている場合、パス/-/reload/-/quitでアクセス可能になる。

Prometheus 1.xでは、/-/reloadおよび/api/v1/seriesのDELETEの利用は、HTTP APIにアクセスできる人なら誰でもアクセス可能である。 エンドポイント/-/quitはデフォルトで無効になっているが、フラグ-web.enable-remote-shutdownで有効にできる。

remote read機能によって、HTTPアクセスできる人なら誰でもremote readエンドポイントにクエリを送信できるようになる。 例えば、もし、PromQLクエリが最終的にリレーショナルDBに対して直接実行されるならば、Prometheusに(Grafanaなどを通して)クエリを送信できる人なら誰でも任意のSQLをそのDBに対して出来ることになる。

Alertmanager

AlertmanagerのHTTPエンドポイントにアクセスできる人なら誰でもそのデータにアクセスできる。 アラートを作成したり解消できる。 サイレンスを作成したり、修正したり、削除できる。

どこに通知を送るかは、設定ファイルによって決まる。 テンプレートの設定次第で、通知の宛先がアラートによって決まってしまう。 例えば、宛先emailアドレスとしてアラートのラベルを使っていると、Alertmanagerにアラートを送信できる人なら誰でも、どんなemailアドレスにも通知を送ることが可能である。 もし、アラートで決まる宛先がテンプレート可能な秘密のフィールドならば、PrometheusまたはAlertmanagerにアクセスできる人なら誰でもその秘密を見ることが可能になるだろう。

テンプレート可能な秘密のフィールドは、通知をルーティングするための利用を意図している。 テンプレートファイルの機能を利用して秘密を設定ファイルから分離するための方法としては意図されていない。 例えば、大規模な設定の中では、各チームが自分で完全に制御できるAlertmanager設定ファイルの断片を持っていて、それらが結合されて、最終的な完全な設定ファイルになる。

Pushgateway

PushgatewayのHTTPエンドポイントにアクセスできる人なら誰でも、その中に含まれるメトリクスを作成、変更、削除することができる。 Pushgatewayは通常はhonor_labelsを有効にしてスクレイプされるので、これは、Pushgatewayにアクセスできる人は誰でもPrometheusの中に時系列を作成できるということを意味する。

Exporters

exporterは、一般的には、設定されたインスタンスとだけ、事前に決められたコマンド/リクエストの集合を用いて、通信する。

SNMPBlackbox exporterのような、URLパラメーターから監視対象を得るexporterも存在する。 したがって、それらのexporterにHTTPでアクセスできる人なら誰でも、任意のエンドポイントにリクエストを送信することが可能である。 それらはクライアント側での認証をサポートしているので、HTTP Basic認証のパスワードやSNMP community stringsのような秘密の漏洩に繋がる可能性がある。 TLSのようなチャレンジ/レスポンス認証はこの影響を受けない。

クライアントライブラリ

クライアントライブラリは、ユーザーアプリケーションに含まれることが意図されている。

クライアントライブラリが提供するHTTPハンドラを利用しているなら、そのハンドラに到達する悪意のあるリクエストが、付加的な負荷やスクレイプの失敗の問題以外の問題を起こすことが可能であってはならない。

認証、認可、暗号化

Prometheusおよびそのコンポートは、サーバーサイドで認証も認可も暗号化も提供しない。 もしそれらが必要なら、リバースプロキシの利用が推奨されている。

管理用エンドポイントと変更が起きるエンドポイントは、cURLなどの簡単なツールを通してアクセスされることを意図している。 そのような使い方ができなくなってしまうので、CSRFの防御は組み込まれていない。 したがって、リバースプロキシを使う際には、CSRFを防ぐためにそういうパスをブロックした方が良いだろう

変更が起きないエンドポイントに対しては、XSSを防ぐために、Access-Control-Allow-OriginのようなCORSヘッダをリバースプロキシに設定した方が良いだろう。

任意のPromQLを実行できるようにするつもりがない信頼性のないユーザーからの入力(コンソールテンプレートや自分で作った何かへのURLパラメーター)を含むPromQLクエリを構築している場合、信頼性のない入力の全てが適切にエスケープされるようにし、インジェクション攻撃を防ぐこと。 例えば、up{job="<user_input>"}は、仮に<user_input>"} or some_metric{zzz="だったとすると、up{job=""} or some_metric{zzz=""}るだろう。

Grafanaを使っている人は、ダッシュボードのパーミッションはデータソースのパーミッションではない、したがって、プロキシモードでユーザーが任意のクエリを実行する力を制限しないこと。

Prometheusの各種コンポーネントはクライアント側の認証と暗号化をサポートしている。 TLSクライアントが提供されている場合、SSLの検証をスキップするinsecure_skip_verifyという設定項目もしばしばある。

Secrets

秘密でない情報やフィールドは、HTTP APIやログを通じて利用可能な可能性がある。

Prometheusでは、サービスディスカバリーで取得したメタデータは秘密とは考えられていない。 Prometheusシステム全体で、メトリクスは秘密とは考えられていない。

設定ファイルの秘密を含むフィールド(ドキュメントにそう明示されている)は、ログやHTTP APIを通じて出力されることはない。 コンポーネントが自分の設定をHTTPエンドポイントから出力するのは普通なので、秘密を他の設定フィールドに入れてはいけない。

依存しているものに利用される他の情報源から来る秘密(例えば、EC2サービスディスカバリーで利用されるAWS_SECRET_KEY環境変数)は、Prometheusで制御できる範囲外のコードのせい、または、それが保存されている場所に出力する機能のせいで結局出力されてしまうかもしれない。

Denial of Service

過剰な負荷や高価なクエリに対する緩和策がいくつか講じられている。しかし、多すぎる、または効果すぎるクエリー/メトリクスが与えられると、コンポーネントは落ちてしまうだろう。 悪意のある行動よりも信頼しているユーザーによってたまたま破壊される可能性の方が高い。

CPU、RAM、ディスク容量、IOPS、ファイル記述子、通信帯域を含む十分なリソースをコンポーネントに与えるのはユーザーの責任である。

全てのコンポーネントのエラーを監視し、エラー時に自動的に再起動させることが推奨される。

ライブラリ

このドキュメントは、ソースコードからビルドされた普通のバイナリについて考える。 自分でソースコードを修正した場合や、Prometheusの内部を自分のコードから(公式クライアントライブラリAPIを超えて)利用した場合には、ここで記されている情報は適用できない。

ビルドプロセス

Prometheusのビルドパイプラインは、サードパーティーのプロバイダー上で動き、Prometheus開発チームのメンバーとそのプロバイダーのスタッフがパイプラインにアクセスできる。 もし、自分のバイナリの正確な出どころについて心配なら、プロジェクトによって事前にビルドされたバイナリに頼るのではなく、自分自身でビルドすることを推奨する。

外部監査

CNCFは、2018年4月から2018年6月に渡るcure53による外部のセキュリティ監査を支援した。

さらなる詳細は、監査の最終報告書を呼んで下さい。

参考リンク

おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 監視 ―モダンなモニタリングのためのデザインパターン

入門 監視 ―モダンなモニタリングのためのデザインパターン

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

和訳活動の支援

Prometheusドキュメント和訳が役に立った方は、以下QRコードからPayPayで活動を支援して頂けるとありがたいです。

PayPayによる支援用QRコード
上のQRコードからPayPayによる支援