📊

GitHub Actions の実行を Grafana で可視化 & 分析している話

2024/08/19に公開

こんにちは。サイボウズ株式会社 生産性向上チームtakamin55 です。

今回は、生産性向上チームが社内で運用を開始した新しい基盤である「GitHub Actions の実行に関する情報を可視化・分析できる基盤」について紹介したいと思います。

基盤のイメージ図

背景

CI や CD を実行するのに便利な GitHub Actions ですが、長く開発をしているといつの間にか CI にかかる時間が伸びていたり、エラーの発生率が高まって不安定なワークフローになっていたりしますよね。

昨今では Four Keys 指標なども登場し、開発のリードタイムを短くしてデプロイ回数を増やしていく考え方がありますから、CI がボトルネックになるのは避けたいところです。

実際にサイボウズでは過去に何度か CI の改善が行われていますし、今でもすべての問題が解決したわけではないため、これからも CI の状況を注視していく必要があります。

もう 1 つほかの背景として、生産性向上チームは Four Keys 指標を可視化する基盤を開発チームに提供しているものの、いざ開発チームが変更のリードタイムの指標を改善したいと考えたときにどこから手を付けたら良いのか分からず、アクションが起こしにくいという意見がありました。

これら 2 つの背景に対して、GitHub Actions の実行情報を可視化できれば CI に関するボトルネックを継続的に把握できますし、ボトルネックが分かれば改善アクションも起こしやすく、変更のリードタイム短縮に繋がります。CI の実行を健全に保ち続ることで開発生産性の向上に貢献できると考え、今回の GitHub Actions の実行情報を収集・分析・可視化する基盤を社内で作成しました。

アーキテクチャ・仕組み

Google Cloud を利用した構成になっています。

実はこの構成は、2024 年 6 月に開催された開発生産性カンファレンス 2024 で発表されたサイボウズの Four Keys 計測に関する基盤と同じであり、実際にその Four Keys 基盤を拡張する形で実装されています。

以下のような流れで GitHub Actions の実行情報が可視化されます。

1. リポジトリで GitHub Actions の実行に関する Webhook を設定する

GitHub リポジトリは特定のアクションが起きたときにそのイベント情報を Webhook で飛ばすことが可能です。

GitHub Actions に関するイベントは workflow_runworkflow_jobの 2 つがあり、このチェックボックスを入れるとワークフローやジョブが実行された際に Webhook が実行されるようになります。(他にもキューに入ったときや、完了したときなど、トリガータイミングはいくつかあります。)

Webhook によるリクエストのペイロードについては公式ドキュメントが参考になります。

2. BigQuery にて永続化する

Webhook を Cloud Run で実行中のアプリケーションで受け取り、検証をした後に BigQuery に挿入します。

永続化層は BigQuery 以外でも問題ないと思いますが、現在すでに社内運用中で、今回の GitHub Actions の分析機能を拡張することになった Four Keys 基盤が BigQuery を使っていた点や、GitHub Actions から飛んでくる Webhook のリクエストのペイロードはネストされた json 構造になっており RDB では扱いにくいといった点で、BigQuery を採用しています。

BigQuery では、テーブルは以下の二段構成になっています。

  1. イベントの json をそのまま保存するテーブル
  2. 実行情報を可視化するにあたり必要な情報だけをピックアップしたビュー

2 のビューは以下のようなスキーマになっています。例えば workflow_run イベントのペイロードにあるワークフローの結果に関する情報である conclusion プロパティは、エラー率を計算するために必要なのでビューにピックアップしています。

フィールド名 説明
id 実行ごとに振られる ID
workflow_id ワークフロー ID
workflow_name ワークフロー名
conclusion concluion(※実行結果のようなもの)
started_at 実行の開始時刻
completed_at 実行の終了時刻
url 実行詳細への URL
...

3. Grafana でクエリを実行し可視化する

可視化は Grafana を Cloud Run 上で実行することで実現しています。

Grafana はデータソースとして BigQuery を選択することができ、まるで BigQuery コンソールで SQL を書くのと同じように Grafana パネルで SQL を書き、データを取得することができます。

以下のようなパネルを用意しています(ピックアップ)

a.ワークフロー実行時間の推移

すべてのワークフローのすべての実行時点でプロットし、折れ線グラフを形成しています。異常な実行を見つけるのが目的です。

プロットをクリックすると実際の GitHub Actions の実行結果へ飛ぶボタンがあり、結果を確認しにいくことができます。

SQL は以下のようになっています。

SELECT
  completed_at,
  TIMESTAMP_DIFF(completed_at, started_at, second),
  workflow_name,
  url,
FROM 
  workflow_table
WHERE 
  $__timeFilter(completed_at) 
  AND workflow_name IN (${workflow})
  AND conclusion IN (${workflow_conclusion})
ORDER BY completed_at ASC

TIMESTAMP_DIFF() は BigQuery の関数で、2つのタイムスタンプ型の値を第 3 引数の単位で切り捨てます。今回は second を指定しているためミリ秒の情報は捨てられます。

$__timeFilter()は Grafana の関数で、ダッシュボード上で指定した期間を SQL に置き換えてくれます。例えばダッシュボード上で Last 2 days を選択すると、今から2日前の時刻 < completed_at AND completed_at < 今の時刻 のような SQL に自動で置き換わります。

また${workflow}${workflow_conclusion} という記述についてですが、これは Grafana のダッシュボードに定義した変数の値が入ります。利用ユーザーはダッシュボード上にあるプルダウン選択式の変数でワークフロー名や conclusion を選択することで、選択されたものに絞り込んでグラフを表示させられるようににしました。例えば成功しているワークフローの情報だけ見たい場合は、以下のように success だけを選択します。

なお、すべての実行についてプロットするのではなく、実行日ごとに集計して 90 パーセンタイル値をプロットしたグラフもあります。こちらでは実行時間の大まかな傾向を掴むことが可能です。

b.ワークフロー実行回数のランキング

ワークフローの実行回数を計算し、実行回数の多い順に棒グラフを表示しています。実行回数が多いワークフローは改善のインパクトが大きいです。

SQL はこちらです。

SELECT
  workflow_name,
  COUNT(id) AS execution_count
FROM 
  workflow_table
WHERE
  $__timeFilter(completed_at) 
  AND workflow_name IN (${workflow})
  AND conclusion IN (${workflow_conclusion})
GROUP BY workflow_name
ORDER BY execution_count DESC

c.ワークフローの conclusion による積み上げグラフ

ワークフローの実行結果(conclusion)を「成功」「失敗」「その他」で分類して積み上げグラフを作り、失敗とその他の降順で並び替えています。公式ドキュメントの conclusion の分類に従ってより詳細に分けることも可能です。

ここから失敗が多いワークフローを見つけ、改善することができます。

SQL はこちらです。

SELECT
  workflow_name,
  SUM(CASE WHEN conclusion = 'success' THEN 1 ELSE 0 END) as success_count,
  SUM(CASE WHEN conclusion = 'failure' THEN 1 ELSE 0 END) as failure_count,
  SUM(CASE WHEN conclusion NOT IN ('success','failure') THEN 1 ELSE 0 END) as other_count,
FROM 
  workflow_table
WHERE
  $__timeFilter(completed_at) 
  AND workflow_name in (${workflow})
GROUP BY workflow_name
ORDER BY failure_count DESC, other_count DESC

なお、これはすべてのワークフローの積み上げグラフですが、1 つのワークフローを選ぶことで一定期間における実行結果の推移を見ることも可能です。例えば失敗が増加しているワークフローを見つけたり、反対に失敗が減って改善されたことを把握したりすることが可能です。

d.ジョブやステップに関するグラフ

さらに細かく、ジョブやステップに関するグラフも用意しています。
ワークフローのグラフを見て改善余地のあるワークフローを見つけた後に、こちらのグラフを見て原因をさらに絞り込むことが可能です。

今後について

コスト抑制

現在見えている明らかな課題として、将来の BigQuery のクエリコストがあります。

ワークフローは 3 つの conclusion を持っているためそれぞれのイベントが発生し、各イベントは数十KB のデータ量を持ちます。ジョブも同様に 4 つの conclusion を持ち、数十KB のデータ量を持ちます。

そのため、ワークフローが多数のジョブを抱えていたり、ワークフローの実行頻度が高かったり、そもそもワークフローの数が多かったりすると、クエリ対象のデータが膨らんでいくことは簡単に予想されます。

BigQuery は主にクエリでスキャンされたデータに対して課金が発生するため、何も対策をしないとデータが膨らんでいくにつれて料金がかかっていきます。

幸いまだ社内向けリリース直後であるためデータも少なく、クエリが実行される機会も少ないので大きな問題にはなっていませんが、以下のような対策を検討中です。

  • BigQuery のパーティショニングの見直し
    • 適切な単位でパーティショニングを行うことでスキャン対象を減らす
  • BigQuery のクラスタリングの見直し
    • 適切なカラムでクラスタリングを行うことでスキャン対象を減らす
  • マテリアライズド・ビューの検討
    • データのリアルタイム性は不要なので、クエリ結果をビューに保存し、スキャン対象を減らす
  • クエリ結果のキャッシュの検討
    • データのリアルタイム性は不要なので、クエリ結果をキャッシュさせて料金を減らす
  • その他

まとめ

GitHub Actions の実行情報を収集・分析・可視化する基盤を紹介しました。
今や健全な CI はリードタイムの短縮や変更障害の防止に必須ですから、コストとも折り合いをつけながらうまくこの基盤を継続的に利用し、社内の開発生産性の向上に役立てていきたいです。

ところでですが、CircleCI やAzure Pipeline では CI の実行情報が分析できる機能がついていたりするので、GitHub Actions も公式の機能が出てほしいですね。

最後までお読みいただきありがとうございました。

サイボウズ 生産性向上チーム 💪

Discussion