こんにちは。CircleCI カスタマーサクセスチームの Chisato です。
最近個人的に幸せを感じた出来事は、育てているレモンの花が咲いたことです。今年2回目の開花で、とても良い香りがします。
今回は、インサイト(以下 Insights)についてご紹介します。
最近お客様から、「不安定なテストの自動検知、いいですよね」などのコメントをいただく機会が増え、とても嬉しく思います。
Insights をご活用いただきありがとうございます。
Insights とは
Insights は、CircleCIのご利用をデータとして可視化したページです。
お客様側で設定いただく必要なく、UIから簡単にデータを確認いただけます。
4つの指標(キー メトリクス)
CircleCI を最大限活用いただけるよう、CircleCI では Insights を利用して4つの指標を計測することを推奨しています。
実行時間/ Duration
ワークフローの実行時間です。CIの最終的な目標は「迅速なフィードバック」であるため、4つの中で最も重要な指標です。実行時間を短くすることにだけ専念するのではなく、失敗したビルドから意義のあるフィードバックを得ることが大切です。「実行スピードと価値のある情報を両立するワークフロー」を意識して、コミットサイズの最適化を進めましょう。
スループット/ Throughput
ワークフローの1日あたりの平均実行回数です。実行回数にこだわるよりも、メインブランチにいつでもプルリクエストをマージできる状態を保つことを意識されることをおすすめします。
平均復旧時間/ Mean Time to Recovery
ワークフローが失敗してから次に成功するまでの平均時間です。チームが、失敗に対してどれだけ迅速に対応できるかを測るのに役立ちます。テストのカバレッジが上がるにつれて短縮される傾向にあります。
成功率/ Success Rate
特定の期間にワークフローが成功した回数を、合計実行回数で割った値です。トピックブランチで「安全で価値ある失敗」をしながら、メインブランチには十分にテストされたコードだけをマージできているか確認するのに役立ちます。
これからデータを計測をスタートする場合、まずは実行時間、または平均復旧時間を計測することが推奨されます。
Insights のUI
実際の Insights を一緒に見てみましょう。ダッシュボードで Insights というタブをクリックしてアクセスします。
ページの画像中にピンク色の文字で説明を記載しています。
上図の選択期間は7日間です。
矢印とその横のパーセンテージは、選択中の期間とその前の期間を比較した値です。
Runs(実行回数)を見ると、「直近の7日間は、その前の7日間に比べて 16% 実行回数が多かった」のがわかります。
実行時間の横の P95 は、95パーセンタイルを表します。
選択期間の前の期間のなかで、最長の実行時間をベンチマークとしています。
( P50 は中央値を表します)
4つの指標の活用事例
実行時間/ Duration
- ある機能の利用前と後で実行時間を比較し、その機能が実行時間の高速化に貢献しているか確認する
- リソースクラスのサイズ(スペック)を変更して、実行時間とクレジットの消費数の兼ね合いを見る
- スループットなど他の指標と組み合わせて、適切なコミットサイズを検討する
- 短時間で終了するテストがすべて成功した場合のみ、時間のかかるテストを実行するフローにする ("Fail fast")
スループット/ Throughput
- メインブランチにプルリクエストをいつでもマージできる状態にするための指標とする
- ワークフローの実行回数から、適切なコミットサイズを検討する
平均復旧時間/ Mean Time to Recovery
- 失敗が発生した時のチームの対応スピードやフローについて改善点がないか検討する
- 失敗したビルドのフィードバックへの対応から、チームの生産性について考える
成功率/ Success Rate
- 成功率が低く失敗の多いテストの改善、または削除をする。これにより、テスト最適化を進め、クレジットの無駄な消費を防ぐ
- 各プロジェクトのメインブランチの成功率を確認し、改善点を確認する
Test Insights
テスト結果の分析には、Test Insights(テストインサイト)が便利です。
JUnit や RSpec などのテストフレームワークが生成するテストレポートのメタデータを config.yml 内 に記述する store_test_result ステップで CircleCI に保存することで利用できます。
"TEST"のタブをクリックすることでアクセスできます。
下記が主な表示項目です。
- 実行時間の遅いテストのランキング
- 失敗率の多いテストのランキング
- 不安定なテストの自動検知
不安定なテストの自動検知をもとにテスト最適化を進めていただくお客様がかなり増えています。
"JOBS"タブをクリックすると、ジョブごとのデータが確認できます。
指標やクレジット消費量のほか、CPUとRAMの使用率が確認できるため、リソースクラスのスペックの最適化に便利です。
Insights API
Insights はAPIでもデータを取得可能です。
詳しくはInsights APIのページを参照ください。
トークン作成のステップ
- CircleCI の User Settings ページ(ダッシュボード左下のアイコン)から Personal API Token ページに移動します。
URL:https://app.circleci.com/settings/user/tokens - Create New Tokenをクリックして、Personal API トークン(Personal API Tokens)を作成、保存します。
Insights API 利用のステップ
- CircleCI API Tokenを設定する
- 下記コードのうち次の3項目を自身のものに変更する
* "circle-farm": 組織名(VCS)
* "pepper-deploy": プロジェクト名
* "YOUR_TOKEN": ステップ1で作成したトークン - デスクトップのコマンドプロンプトにコードをペーストしてAPIを呼び出す
今回使用する指標(メトリクス)のデータはこちらのページの ”Shell + Curl” 欄で確認できます。
curl --request GET \
--url 'https://circleci.com/api/v2/insights/gh/circle-farm/pepper-deploy/workflows?reporting-window=last-30-days' \
--header 'circle-token: YOUR_TOKEN'
Slackにデータを送信する
今回はAPIを使って、Insights のデータをSlackに送信する設定をご紹介します。
下記はサポートエンジニアのAaronさんが作成したプロジェクトです。
プロジェクトの URLはこちら
次のデータが取得できるようになっています。
- ワークフローのURL
- ワークフロー名
- 消費クレジット数
- データの計測開始・終了時刻(UTC)
- ワークフローの成功数
- ワークフローの失敗数
Slack への通知は、Slack orbを用いています。
コンテキストの設定方法はこちらを参照ください。
設定のステップ
- Slack orbを設定する
- 下記ソースコードについて、次の項目を変更する
* CIRCLE_TOKEN: 自身のPersonal API トークン
* project-name: プロジェクト名
* org-name: VCS Organization名
* vcs-name: GitHubは "gh", Bitbucketは "bb"
* workflow-names: ワークフロー名(複数設定したいときはカンマで区切る)
* reporting-window: 希望するデータ取得期間 - 定期的にSlackに通知する場合は、パイプラインのスケジュール実行 (Scheduled pipelines) を設定する
version: 2.1
orbs:
slack: circleci/slack@4.10.1
jobs:
insightsdata:
parameters:
project-name:
type: string
org-name:
type: string
vcs-name:
type: string
workflow-names:
type: string
reporting-window:
type: enum
enum: ["24-hours","7-days","30-days","60-days","90-days"]
docker:
- image: cimg/base:stable
resource_class: small
steps:
- run:
name: Get workflow insight data
command: |
# Strip whitespaces from list of workflows
WORKFLOWS=$(echo "<< parameters.workflow-names >>" | sed 's/, /,/g' | sed 's/ ,/,/g' | xargs)
# Generate project slug
PROJECT_SLUG="<< parameters.vcs-name >>/<< parameters.org-name >>/<< parameters.project-name >>"
# Get insight data from API
INSIGHT_DATA=$(curl --request GET \
--url "https://circleci.com/api/v2/insights/$PROJECT_SLUG/workflows?reporting-window=last-<< parameters.reporting-window >>&all-branches=true" \
--header "circle-token: $CIRCLE_TOKEN")
# Parse insight data and map to template
INSIGHT_MAP=$(echo $INSIGHT_DATA | jq --arg workflows "$WORKFLOWS" '[.items[] | select(.name == ($workflows | split(",")[])) | {"type":"section","fields":[{"type":"mrkdwn","text":("*Workflow Name*: " + .name)},{"type":"mrkdwn","text":("*Credits Used*: " + (.metrics.total_credits_used|@sh))},{"type":"mrkdwn","text":("*First Run*: " + (.window_start|@sh))},{"type":"mrkdwn","text":("*Last Run*: " + (.window_end|@sh))},{"type":"mrkdwn","text":("*Successful Runs*: " + (.metrics.successful_runs|@sh))},{"type":"mrkdwn","text":("*Failed Runs*: " + (.metrics.failed_runs|@sh))}]},{"type":"divider"}]')
# Create base template to append to
echo '{"blocks":[{"type":"header","text":{"type":"plain_text","text":"Credit Usage Report for << parameters.org-name >>/<< parameters.project-name >>","emoji":true}},{"type":"context","elements":[{"type":"mrkdwn","text":"*Period:* << parameters.reporting-window >> <https://app.circleci.com/insights/<< parameters.vcs-name >>/<< parameters.org-name >>/<< parameters.project-name >>/?reporting-window=last-<< parameters.reporting-window >>|View on CircleCI>"}]}]}' > template.json
# Append insight data to base template
CUSTOM_SLACK_TEMPLATE="$(jq -r --argjson INSIGHT_MAP "$INSIGHT_MAP" '.blocks += $INSIGHT_MAP' template.json)"
# Export complete template to .json file
echo $CUSTOM_SLACK_TEMPLATE > template2.json
# Make template available in later steps via the environment variable CUSTOM_SLACK_TEMPLATE
echo 'export CUSTOM_SLACK_TEMPLATE=$(jq . template2.json)' >> $BASH_ENV
- slack/notify:
template: CUSTOM_SLACK_TEMPLATE
event: always
workflows:
insightdata:
when:
and:
- equal: [ scheduled_pipeline, << pipeline.trigger_source >> ]
- equal: [ "insight_schedule", << pipeline.schedule.name >> ]
jobs:
- insightsdata:
project-name: "machine-executor-images"
org-name: "circle-farm"
vcs-name: "gh"
workflow-names: "build_all_images,daily"
reporting-window: "30-days"
context:
- Slack
パイプラインのスケジュール実行 (Scheduled Pipelines)は Project Settingsのページから設定できます。

まとめ
Insights は今後ますます多くのお客様に利用いただくページになると思います。
お使いいただいているなかで、「こんな表示がほしい」などのリクエストがありましたら、ぜひ機能リクエストを提出してください。他のユーザーのリクエストに投票することもできます。
今回、サポートエンジニアのAaronさんとNaoyaさんにご指導いただきながらブログを執筆しました。
いつもほんとうにありがとうございます。
技術的なご質問はこちらから無料のサポートチケットを提出してお問い合わせください。日本語でお問い合わせいただけます。
→ CircleCI サポートセンター
参考文献
Get summary metrics for a project's workflows
APIの例として挙げたプロジェクト: https://github.com/ogii/circleci-insights-slack





