TT Lab
はじめる
学ぶ 学習パス コース

Grafana — ダッシュボードは問いだ

六つのパネルがそれぞれ別の問いに答えていた

TT Labで続きを見る

目標

欠陥が入ったダッシュボードを1つ受け取って、計算値・null値の扱い・スタック・系列数・タイトルと説明を直し、同じ欠陥を次のダッシュボードでも見つける検査ツールを作って、通過させます。

なぜ重要なのか

ダッシュボードが静かに間違う場所は、クエリではなくパネルオプションです。クエリは合っているのに、数字1つのパネルが平均を表示していると、20分間の急増は、6時間の平均の中で消えます。欠けた点をつないで描くと、収集が途切れたという事実そのものが消え、系列を積み重ねると、いちばん上の線を個々の値として読んでしまいます。3つとも「間違った値」ではなく、「尋ねていない問いの正確な答え」なので、見る人は、自分が間違って読んでいることに気づけません。そのため、パネルごとにどんな問いに答えるのかを説明として固定し、その約束を検査ツールで守らせます。

ステップ

  1. lab-start-grafanaでGrafanaを起動し、欠陥が入ったダッシュボード/opt/lab/gfd/gfd-misread/broken.jsonを、修正せず、そのままGrafanaにアップロードしてください(uidはファイルに書かれたgfd-misread、パネルは6つ)。curlで/api/dashboards/dbにPOSTすればよいです。
  2. パネル1(요청률、韓国語のタイトルは「リクエストレート」という意味です)は、今、平均を表示しています。過ぎた区間を1つ選び(1時間以上、終わりは今より前)、その区間でsum(rate(http_requests_total{job="shop-api"}[5m]))の最後の値・平均・最大値を自分で測って、/root/gfd-misread/02-calc.txtに、start=、end=、last=、mean=、max=の5行で書いてください(startとendはエポック秒)。そして、パネル1の計算値をlastNotNullに変えて保存してください。
  3. /root/gfd-misread/03-null.txtに、connected=、none=、zero=の3行を書いてください。各行は、そのnull値の扱いの選択が、見る人に何を主張するのかを、40文字以上で説明する必要があり、3行は互いに異なっている必要があります。そして、パネル2(대기열、韓国語のタイトルは「キュー」という意味です)のspanNullsをfalseに変えて保存してください。
  4. パネル3(핸들러별 요청률、韓国語のタイトルは「ハンドラー別のリクエストレート」という意味です)は、系列を積み重ねて描いています。過ぎた時刻を1つ選び、その瞬間の全体の合計と、/api/ordersの1つのハンドラーの値を、それぞれ測って、/root/gfd-misread/04-stack.txtに、at=、total=、orders=の3行で書いてください(atはエポック秒)。そして、パネル3のstacking.modeをnoneに変えて保存してください。
  5. パネル4(핸들러 지연、韓国語のタイトルは「ハンドラーのレイテンシ」という意味です)のクエリは、ハンドラーごとに系列を1つずつ返します。その数を数えて、/root/gfd-misread/05-series.txtのbefore=に書き、このパネルが「いま最も遅いハンドラーのp95はいくつか」という1つの問いに答えるようにクエリを直して保存したあと、直したクエリの系列数をafter=に書いてください。
  6. 6つのパネルすべてについて、タイトルを、何を見るパネルなのかがわかるように直し(그래프のような名前は禁止です。韓国語で「グラフ」を意味する語です)、説明には、そのパネルが答える問いの文を、疑問符で終わるように書いてください(12文字以上、パネルごとに異なる内容で)。直したダッシュボードを保存してください。
  7. /root/gfd-misread/lint.pyを作成してください。ダッシュボードJSONファイルのパスを引数に受け取って、次の5つのルールの違反を1行に1つずつ(R1からR5までで始まる形で)出力し、違反が1つでもあれば、終了コード1で終わる必要があります。R1はstatパネルの計算値に平均が入っていること、R2はspanNullsが真であること、R3はstacking.modeがnormalであること、R4は説明が疑問符で終わっていないこと、R5はタイトルが空であるか、그래프・패널・차트(韓国語で順に「グラフ」「パネル」「チャート」を意味する語です)のいずれかであることです。原本の/opt/lab/gfd/gfd-misread/broken.jsonに対して実行して、5つのルールがすべて検出されるかを確認してください。
  8. Grafanaにアップロードされている今のダッシュボードをそのままダウンロードして、/root/gfd-misread/fixed.jsonに保存し(.dashboardの本体だけ)、検査ツールを実行して、違反が0で、終了コードが0であることを確認してください。そして/root/gfd-misread/08-review.mdに、R1=からR5=までの5行で、何をなぜ直したかを、それぞれ30文字以上で書いてください。

参考

直す前の状態を画面に載せる

lab-start-grafanaでGrafanaを起動し、欠陥が入ったダッシュボード/opt/lab/gfd/gfd-misread/broken.jsonを、修正せず、そのままGrafanaにアップロードしてください(uidはファイルに書かれたgfd-misread、パネルは6つ)。curlで/api/dashboards/dbにPOSTすればよいです。

保存APIは、ダッシュボードの本体をdashboardキーの中に入れ、overwriteを一緒に送ります。ファイルからその形を作るには、jq -n --slurpfileが便利です。Grafanaが起動するのに数秒かかるので、/api/healthが応答するかどうかを、先に見てください。

数字1つのパネルは、何を計算した値なのか

パネル1(요청률、韓国語のタイトルは「リクエストレート」という意味です)は、今、平均を表示しています。過ぎた区間を1つ選び(1時間以上、終わりは今より前)、その区間でsum(rate(http_requests_total{job="shop-api"}[5m]))の最後の値・平均・最大値を自分で測って、/root/gfd-misread/02-calc.txtに、start=、end=、last=、mean=、max=の5行で書いてください(startとendはエポック秒)。そして、パネル1の計算値をlastNotNullに変えて保存してください。

区間クエリは/api/v1/query_rangeで、start・end・stepを一緒に送ります。データソースプロキシで投げれば、Grafanaが使うのと同じ経路で飛びます。計算値は、ダッシュボードJSONのoptions.reduceOptions.calcsにあります。固定した区間で測る理由は、あとでもう一度測っても同じ値が出るようにするためです。

欠けた点をつなぐことも、主張である

/root/gfd-misread/03-null.txtに、connected=、none=、zero=の3行を書いてください。各行は、そのnull値の扱いの選択が、見る人に何を主張するのかを、40文字以上で説明する必要があり、3行は互いに異なっている必要があります。そして、パネル2(대기열、韓国語のタイトルは「キュー」という意味です)のspanNullsをfalseに変えて保存してください。

収集が途切れた区間をつないで描くと、その時間にも値があったように見えます。null値の扱いは、fieldConfig.defaults.custom.spanNullsにあります。3つの選択が、それぞれどんな状況で正しいかも、一緒に考えてみてください。正しい答えが1つだけの問題ではありません。

積み上げたいちばん上の線は、どの系列でもない

パネル3(핸들러별 요청률、韓国語のタイトルは「ハンドラー別のリクエストレート」という意味です)は、系列を積み重ねて描いています。過ぎた時刻を1つ選び、その瞬間の全体の合計と、/api/ordersの1つのハンドラーの値を、それぞれ測って、/root/gfd-misread/04-stack.txtに、at=、total=、orders=の3行で書いてください(atはエポック秒)。そして、パネル3のstacking.modeをnoneに変えて保存してください。

ある瞬間の値は、/api/v1/queryにtime=を一緒に送れば得られます。時刻を固定しておくと、あとでもう一度測っても同じ値が出ます。スタックの設定は、fieldConfig.defaults.custom.stacking.modeにあります。2つの数字を比べてみると、いちばん上の線を個々の系列として読んだときに、どれだけ間違うかがわかります。

値1つを問うパネルに、系列が4つ来たら

パネル4(핸들러 지연、韓国語のタイトルは「ハンドラーのレイテンシ」という意味です)のクエリは、ハンドラーごとに系列を1つずつ返します。その数を数えて、/root/gfd-misread/05-series.txtのbefore=に書き、このパネルが「いま最も遅いハンドラーのp95はいくつか」という1つの問いに答えるようにクエリを直して保存したあと、直したクエリの系列数をafter=に書いてください。

promq "<쿼리>"で投げてみると(プレースホルダーはクエリです)、結果の系列が1行に1つずつ出ます。複数の系列のうち、最も大きい値1つだけを残す集計演算子があります。クエリは、ダッシュボードJSONのtargets[0].exprです。

タイトルと説明が、そのパネルの問いである

6つのパネルすべてについて、タイトルを、何を見るパネルなのかがわかるように直し(그래프のような名前は禁止です。韓国語で「グラフ」を意味する語です)、説明には、そのパネルが答える問いの文を、疑問符で終わるように書いてください(12文字以上、パネルごとに異なる内容で)。直したダッシュボードを保存してください。

説明は、ダッシュボードJSONのパネルごとにあるdescriptionです。画面では、パネルのタイトルの横にある情報アイコンとして表示されます。問いの文として書いておけば、半年後にこのパネルを削除してよいかどうかを判断できます。その問いをまだ尋ねているかどうかだけを見ればよいからです。

同じ欠陥を、次のダッシュボードでも見つける

/root/gfd-misread/lint.pyを作成してください。ダッシュボードJSONファイルのパスを引数に受け取って、次の5つのルールの違反を1行に1つずつ(R1からR5までで始まる形で)出力し、違反が1つでもあれば、終了コード1で終わる必要があります。R1はstatパネルの計算値に平均が入っていること、R2はspanNullsが真であること、R3はstacking.modeがnormalであること、R4は説明が疑問符で終わっていないこと、R5はタイトルが空であるか、그래프・패널・차트(韓国語で順に「グラフ」「パネル」「チャート」を意味する語です)のいずれかであることです。原本の/opt/lab/gfd/gfd-misread/broken.jsonに対して実行して、5つのルールがすべて検出されるかを確認してください。

ルールを文章で書いておくと、次のダッシュボードは、また同じ状態で生まれます。動くコードで書いてください。行(row)の中に畳まれたパネルもパネルであることを、忘れないでください。ファイルが{"dashboard": ...}で包まれている場合も、ダッシュボードの本体そのものである場合もあります。

直したダッシュボードが、自分自身の検査ツールを通る

Grafanaにアップロードされている今のダッシュボードをそのままダウンロードして、/root/gfd-misread/fixed.jsonに保存し(.dashboardの本体だけ)、検査ツールを実行して、違反が0で、終了コードが0であることを確認してください。そして/root/gfd-misread/08-review.mdに、R1=からR5=までの5行で、何をなぜ直したかを、それぞれ30文字以上で書いてください。

ファイルと画面が食い違わないようにするには、直したあとにもう一度ダウンロードする必要があります。検査ツールが0で終わらなければ、どのパネルが残っているかを出力が教えてくれます。記録は、次の人が同じ判断をもう一度しなくて済むように残すものです。