NewRelicを使ってFour Keysを可視化してみる（①デプロイ頻度編）

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

みなさん、開発生産性は意識していますか？:rocket:
意識するにはまず可視化:eyes:から、ということで、生産性の指標としてFour Keysを採用し、NewRelicを利用して可視化することを目指します。Four Keysの4つの指標について1つずつ、全4回に分けてお送りします。

# Four Keysとは
Four Keysとは、DevOps Research and Assessment（DORA）チームが確立した、ソフトウェア開発チームのパフォーマンスを示す4つの指標（デプロイ頻度／変更リードタイム／変更障害率／サービス復元時間）です。
Four Keysの各指標は、可視化された値を元にElite/High/Medium/Lowの4段階のパフォーマンスレベルを判定します。このパフォーマンスレベルをEliteにすることを目指し、その状態を継続していくことで開発生産性の向上を図ります。
詳細は以下のGoogle Cloudのブログ記事を参照してください。

https://cloud.google.com/blog/ja/products/gcp/using-the-four-keys-to-measure-your-devops-performance

# デプロイ頻度とは
今回は、Four Keysで定義された4つの指標のうち「デプロイ頻度」について可視化を行います。最初に、デプロイ頻度のパフォーマンスレベルの定義を確認します。

| Elite | High | Medium | Low |
|:-|:-|:-|:-|
|オンデマンド（1日に複数回デプロイ）|1週間～1か月|1か月～半年|半年に1回より少ない|

デプロイ頻度は名前の通り、本番環境にリリースを行った頻度を表わす指標です。そのため、必要なデータとしてデプロイのイベントが記録できていればよさそうです。

::: note warn
本記事ではDORAの定義をそのまま利用しますが、実際のチームに適用する際にはチームの状況にあった定義をあらためて検討することを推奨します。例えばウォーターフォールで開発を進めているチームの場合、一般的にDORAの定義のEliteレベルを達成するのは難しいと思います。
可視化の目的はチームをFour Keysの定義にあわせることではなく、Four Keysを上手に活用して開発生産性を向上させることです。チームの進め方としてウォーターフォールがマッチしており、その状態で開発生産性の向上を狙っていきたいのであれば、それを考慮したパフォーマンスレベルを再定義しましょう。
:::

# GitHub Actionsでデプロイイベントを記録する
まずは、デプロイイベントをNewRelicに送信する部分を実装します。私たちのチームではGitHubを利用しており、デプロイはGitHub Actionsで実施しているため、デプロイのワークフローにデプロイイベントを記録する処理を追加します。
NewRelicでデプロイイベントを記録するには、以下の2つの方法があります。

- [変更追跡機能](https://docs.newrelic.com/jp/docs/change-tracking/change-tracking-introduction/)を利用する
- [カスタムイベント](https://docs.newrelic.com/jp/docs/data-apis/ingest-apis/event-api/introduction-event-api/)を送る

今回はカスタムイベントを使った方法で進めます。理由としては同じタイミングで送りたいデータがあったことと、後ほどNewRelic上でクエリを実行してイベントデータを操作することを考慮したとき、カスタムイベントの方が容易に実現できるためです。
実装手順としては、デプロイのワークフローに以下のステップを追加するだけです。あらかじめデータ送信先のNewRelicアカウントの[アカウントID](https://docs.newrelic.com/jp/docs/accounts/accounts-billing/account-structure/account-id/)とデータ送信のための[ライセンスキー](https://docs.newrelic.com/jp/docs/apis/intro-apis/new-relic-api-keys/)を払い出し、GitHubの[シークレット](https://docs.github.com/ja/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions)に登録しておいてください。

``` workflow.yaml
- name: Send deployment event to new relic
  run: |
    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\": \"Deployment\",
         \"environment\": \"${{ env.ENVIRONMENT }}\",
         \"version\": \"${{ env.TAG_NAME }}\"
       }
     ]"
```

`eventType` にはカスタムイベントの名称を指定します。名称は自由に設定でき、後ほどNewRelic上でデータを参照する際に使用します。また、上記の例では同時にデプロイ先の環境情報とデプロイしたバージョンの情報も送っています。これらの情報はワークフロー内の前のステップで取得し、GitHub Actionsの環境変数（`$GITHUB_ENV`）に格納したものを参照しています。
なお、カスタムイベントを送る際のタイムスタンプについてはNewRelic側で自動的に付与されます。よって、こちらから明示的に送信する必要はありません。

# NewRelicでパフォーマンスレベルを判定し可視化する
必要なデータがNewRelicに集まったので、いよいよパフォーマンスレベルを判定した結果を可視化する部分を実装します。

まずは、NewRelicのクエリビルダーでデータを確認してみます。直近1か月の本番環境へのデプロイイベントについて、以下の[NRQL](https://docs.newrelic.com/jp/docs/nrql/get-started/introduction-nrql-new-relics-query-language/)で取得します。

```
SELECT *
FROM Deployment
WHERE environment = ‘prd’
SINCE 1 month ago
```

カスタムイベントを送る際 `eventType` に指定した内容をFROM句に指定し、期間指定はSINCE句で行います。WHERE句の条件はご自身のデータに合わせて適宜変更してください。
前述のクエリを実行すると、データが取れました。ちゃんとタイムスタンプも付与されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550354/3cd6e731-a8cf-4957-8065-05e63e3f4fba.png)

ではこのデータを使って、パフォーマンスレベルの判定ロジックをNRQLで作成します。
デプロイ頻度のパフォーマンスレベルは特定の時間枠内に発生したデプロイイベントの発生頻度をカウントすれば良さそうです。NRQLには今回のような用途で使える[rate関数](https://docs.newrelic.com/jp/docs/nrql/using-nrql/rate-function/)が用意されているため、こちらを利用します。先ほどのクエリを以下のように書き換えて実行してみます。

```
SELECT rate(count(*), 1 week)
FROM Deployment
WHERE environment = ‘prd’
SINCE 1 month ago
```

rate関数の第2引数で、計算する時間枠を指定します。このクエリであれば、過去1か月における1週あたりのデプロイイベントの平均発生数が計算されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550354/1b73ec38-a36a-46d4-b715-8c8e5479a27c.png)

ここまで行けば、あとはデプロイイベントの発生数をレベルに応じた基準と比較すれば完成です。条件判定を行うためのif関数を利用して、最終的には以下のようなクエリとなりました。

```
SELECT
  if(rate(count(*), 1 day) >= 1,
    'Elite',
    if(rate(count(*), 1 month) >= 1,
      'High',
      if(rate(count(*), 6 months) >= 1, 'Medium', 'Low')
    )
  )
AS '' // 結果に表示される関数名を消すため
FROM Deployment
WHERE environment = 'prd'
SINCE 1 month ago
```

実行してみると、無事レベルが表示されました！:tada:
あとはこのクエリをダッシュボードに追加しておけば、いつでも簡単に参照できます:+1:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550354/00e65363-ea8e-4528-a163-eb6035041d8d.png)

# さいごに
Four Keysの可視化の第一歩として、まずはデプロイ頻度をNewRelic上で可視化してみました。参考になれば幸いです。
次回は変更リードタイムの可視化にトライします！:muscle: