1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NewRelicを使ってFour Keysを可視化してみる(②変更リードタイム編)

Posted at

こんにちは!
ポーラ・オルビスホールディングスのITプロダクト開発チームでスクラムマスターをしている川田です。

前回に引き続き、Four Keysの各指標についてNewRelicを利用して可視化:eyes:することを目指します。前回の記事はこちら:point_down:です。

変更リードタイムとは

今回は、Four Keysで定義された4つの指標のうち「変更リードタイム」について可視化を行います。前回と同様、最初に変更リードタイムのパフォーマンスレベルの定義を確認します。

Elite High Medium Low
1時間未満 1日~1週間 1か月~半年 半年以上

DORAの定義ではレベルの定義が非連続になっています。仮に計算結果が2つのレベルの間に位置する場合、今回は低いレベルになるような判定ロジックにします。
(例:リードタイムが1時間以上~1日未満の場合はHighとする)

変更リードタイムの定義は、Google Cloudのブログには以下のように記載されています。

For the primary application or service you work on, what is your lead time for changes (i.e., how long does it take to go from code committed to code successfully running in production)?

あなたが携わっている主要なアプリケーションやサービスについて、変更のリードタイム(コードをコミットしてから本番稼動するまでにかかる時間)はどのくらいですか?

つまり、必要なデータとしては

  • コミットが行われた時刻
  • コミットされた内容がブランチにマージされ、デプロイされた時刻

の2つで、各コミット単位でこれらの差分を計算し、全体の平均値を使ってパフォーマンスレベルを判定すれば良さそうです。

私たちのチームでは対象のブランチにプルリクがマージされたことをトリガーとしてデプロイを行っていることもあり、今回はブランチにマージされた時刻=デプロイ時刻として扱います。そうすることで、前回のデプロイ頻度で記録したデプロイイベントとデータを結合する必要がなくなるため全体の処理がシンプルになります。厳密にはデプロイ時間が差分として発生しますが、数分程度なので許容できる範囲内と判断しています。

前回と同様に本記事ではDORAの定義をそのまま利用しますが、実際のチームに適用する際にはチームの状況にあった定義をあらためて検討しましょう。

GitHub Actionsでコミット/マージ時刻を記録する

まずは、コミット/マージの時刻をNewRelicに送信する部分を実装します。GitHubで特定のブランチにマージされたことをトリガーに動くワークフローを作成し、前回と同様にNewRelicのカスタムイベントを利用してデータを送信します。また、あらかじめデータ送信先のNewRelicアカウントのアカウントIDとデータ送信のためのライセンスキーを払い出し、GitHubのシークレットに登録が必要な点もお忘れなく。

では実装内容について、パートごとに見ていきます。
まずはワークフローの最初からstepsの定義直前の設定部分です。

workflow.yaml
name: Send PullRequest event to New Relic

on:
  pull_request:
    types:
      - closed

jobs:
  send_event_to_newrelic:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged
    steps:
...

on.pull_request.typesclosed を指定することで、プルリクエストが閉じられたときに動くワークフローになります。これだけではマージせずにプルリクを閉じた場合にも動作してしまうため、jobs 内に if: github.event.pull_request.merged の設定を記載してマージが行われたときのみ有効となるようにします。
続いて、各stepに移ります。まずはプルリクの情報を取得します。

workflow.yaml
- name: Get PR info
  run: |
    echo "pr_no=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
    echo "pr_base_ref=${{ github.event.pull_request.base.ref }}" >> $GITHUB_ENV
    pr_merged_at=$(date +%s -d "${{ github.event.pull_request.merged_at }}")
    echo "pr_merged_at=$pr_merged_at" >> $GITHUB_ENV

プルリクに関する情報は github.pull_request.event から取得できます。取得できる情報の詳細は公式ドキュメントを参照してください。
今回はプルリクがマージされた時間を利用するため、github.pull_request.event.merged_at を利用します。merged_atはISO8601形式の文字列になっているので、後ほど計算しやすいようにdateコマンドでUNIX時間に変換し、環境変数 $GITHUB_ENV に入れておきます。また、一緒にプルリクの番号とマージ先のブランチも取得しておきます。
続いて、プルリクに含まれるすべてのコミットの時刻を取得します。

workflow.yaml
- name: Get all commit timestamps
  run: |
    dates=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
      "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits" \
      | jq -c '[.[] | .commit.committer.date ]')
    echo "dates=$dates" >> $GITHUB_ENV

プルリクに含まれるコミットの情報は、List commits on a pull request API を利用して取得します。1コミットの情報を表すJSONオブジェクトのリストが返却されるため、そこからコミットの時刻(commit.committer.date)を取得し、リスト化して環境変数に入れておきます。
最後に、ここまでに集めたデータをNewRelicに送ります。

workflow.yaml
- name: Send commit timestamps to new relic
  run: |
    echo '${{ env.dates }}' | jq -c '.[]' | while read date; do
     var=$(echo "$date" | tr -d '\\"')
     timestamp=$(date +%s -d $var)
     curl -i \
      -X POST 'https://insights-collector.newrelic.com/v1/accounts/${{ secrets.NEW_RELIC_ACCOUNT_ID }}/events' \
      -H "X-Insert-Key:${{ secrets.NEW_RELIC_LICENSE_KEY }}" \
      -H "Content-Type: application/json" \
      -d \
      "[
        {
          \"eventType\": \"Commit\",
          \"pr_no\": ${{ env.pr_no }},
          \"pr_base_ref\": \"${{ env.pr_base_ref }}\",
          \"pr_merged_at\": ${{ env.pr_merged_at }},
          \"commit_at\": $timestamp
        }
      ]"
    done

eventTypeに指定するカスタムイベントの名称は Commit としています。各コミットの情報ごとに、前ステップで取得した時刻をUNIX時間に変換してから他の情報と一緒にNewRelicに送ります。
今回求めたい時刻の差分についてはこのステップで計算しても良いのですが、なるべくデータは生の状態で保持しておき、利用するNewRelic側で自由に利用・加工できるような方針としています。

NewRelicでパフォーマンスレベルを判定し可視化する

必要なデータがNewRelicに集まったので、いよいよパフォーマンスレベルを判定した結果を可視化する部分を実装します。
まずは、NewRelicのクエリビルダーでデータを確認してみます。直近1か月に本番環境向けのリリースブランチへマージされたコミットの情報について、以下のNRQLで取得します。WHERE句の条件は環境に合わせて修正してください。

SELECT *
FROM Commit
WHERE pr_base_ref = ‘release-prd’
SINCE 1 month ago

結果は以下の通り、ちゃんと記録されています!

image.png

続いてプルリクがマージされた時刻とコミットされた時刻の差分を求め、その平均値を計算します。四則演算で差分を求めたのち、NRQLの average関数 を用いて平均値を計算します。あわせて、convert関数 により単位を秒から時間に変換してみます。

SELECT convert(average(pr_merged_at - commit_at), 'second', 'hour')
FROM Commit
WHERE pr_base_ref = 'release-prd'
SINCE 1 month ago

こちらのクエリを実行すると、ばっちり計算結果が表示されました!

image.png

あとはレベルに応じた基準と比較する部分を実装して完成です。最終的には以下のようなクエリとなりました。

SELECT
  if (count(*) = 0 OR convert(average(pr_merged_at - commit_at), 'second', 'hour') <= 1,
    'Elite',
    if(convert(average(pr_merged_at - commit_at), 'second', 'day') <= 7,
      'High',
      if(convert(average(pr_merged_at - commit_at), 'second', 'month') <= 6, 'Medium', 'Low')
    )
  )
AS '' // 結果に表示される関数名を消すため
FROM Commit
WHERE pr_base_ref = 'release-prd'
SINCE 1 month ago```

こちらを実行すると、無事レベルが表示されました!:tada:

image.png

さいごに

Four Keysの可視化の2回目として、今回は変更リードタイムをNewRelic上で可視化してみました。参考になれば幸いです。
次回は変更障害率の可視化にトライします!:muscle:

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?