BASEプロダクトチームブログ

ネットショップ作成サービス「BASE ( https://thebase.in )」、ショッピングアプリ「BASE ( https://thebase.in/sp )」のプロダクトチームによるブログです。

New Relic OneでDevOpsのキーメトリクス デプロイ頻度をグラフ化する

BASE BANKでエンジニアをしている @budougumi0617 です。
この記事はBASE Advent Calendar 2021 10日目の記事…ではなく、New Relic Advent Calendar 2021 10日目の記事です。

qiita.com

TL;DR

f:id:budougumi0617:20211208205409p:plain
ダッシュボード

自分たちチームのパフォーマンスはどれくらいなのか?

2009年に「10 deploys per day」というタイトルと共にDevOpsというキーワードが産まれて1から10年以上が経ちました。

www.slideshare.net

市場へサービスのリリースを繰り返し、より短時間で多くのフィードバックループを回すことがソフトウェア開発チームの生産性向上の鍵なようです。
この事実を具体的な指標にしたのがDevOps Research and Assessment(DORA)チームの研究から導き出されたソフトウェア開発チームのパフォーマンスを示す 4 つの指標です(Google Cloudブログより引用)。

  • デプロイの頻度 - 組織による正常な本番環境へのリリースの頻度
  • 変更のリードタイム - commit から本番環境稼働までの所要時間
  • 変更障害率 - デプロイが原因で本番環境で障害が発生する割合(%)
  • サービス復元時間 - 組織が本番環境での障害から回復するのにかかる時間

LeanとDevOpsの科学[Accelerate]クイックチェックツールでは具体的なパフォーマンスレベルも示されています。

f:id:budougumi0617:20211208204040p:plain
performance
表はさきほど同様 Google Cloudブログより引用

しかし、「ではあなたのチームはどのレベルなの?」と聞かれると「多分先週は毎日デプロイしてたはず…」なんて曖昧な回答しかできない状態でした。すでに他社ではこの質問に答えるためのアプローチ方法がいろいろ取られています。

普段「推測するな、計測せよ」「可観測性!!Observability!!O11y!!」なんて言っているのにこれではいけない…ということでチームの各指標をちゃんと計測しようと思いました。本記事ではまずは手始めにデプロイの頻度を計測した方法の紹介です。

デプロイ頻度を集計したい

デプロイ頻度を計測するには様々なツールがあると思いますが、我々はNew Relicを使ってデプロイ頻度を集計することにしました。
New Relicを使ってデプロイ頻度を集計する理由は次のとおりです。

  • New Relicで集計している他のメトリクス情報と組み合わせて別の情報を引き出せる可能性がある
  • 新たなツールを導入するよりも日々使うツールは少ないほうがよい
  • 同様に確認が必要なダッシュボードは少ないほうがよい
  • NRQLの便利さとグラフの作りやすさ

サービスをデプロイしたという事実を集計する

New RelicにはDeployment Markerという他のパフォーマンス情報とアプリケーションのデプロイを関連付ける機能があります。

docs.newrelic.com qiita.com

Deployment Marker を利用して Deployment イベントを記録すると、APMのグラフにデプロイタイミングを示す線がプロットされます。
New Relic One上でデプロイタイミングを記録しておくことでデプロイがメトリクスにどのような影響を及ぼしたのか解析できます。

f:id:budougumi0617:20211209170351p:plain
Deploymentが一緒に描画されたメトリクス

最初はこの機能を使って記録したDeploymentイベントをNRQLで集計すればよいと考えていました。
しかし、当時(そして2021年12月現在も、)DeploymentはNRQLによって集計できるイベントはありませんでした。
デプロイ頻度を可視化するには集計してグラフ化する必要があります。そこで我々はデプロイのたびに独自のカスタムイベントを発行することにしました。

Event APIを利用した独自イベントの発行

New RelicのNRQLで集計できるtype(NRQLのFROMに指定できるデータ)はLogTransactionなど多岐に渡ります。
そしてNRQLはユーザーが独自に定義したtypeのデータを集計することも可能です。独自定義のイベント(type)を作れるのがEvent APIです。

docs.newrelic.com

Event APIを実行するために必要なもの

Event APIを利用するために必要な情報は次の2点です。

  • License Key
  • Account ID

New Relic Oneを利用している場合、Event APIはLicense Keyを確認するだけで実行できます(以前はInsert Keyが必要だったはずなのですが、2021年12月現在は非推奨)。

docs.newrelic.com

Licence Key自体は次のURLをクリックすると遷移できる「API Keys」の中から確認することができます。
同ページを見れば自分たち組織のアカウントIDも確認できるはずです。

one.newrelic.com

Event APIの実行方法

Event APIの基本的な利用方法は先ほど記述したLicense Keyを利用して任意のJSONをcurlコマンドでPOSTするだけです。

docs.newrelic.com

細かい仕様はありますが、任意のキー/バリューを含めることで記録する情報を自由に付与することができます。
今回は次のようなJSONフォーマットで独自イベントを発行することにします。

[
  {
    "eventType":"Deploy",
    "deploy_user":"${DEPLOY_USER}",
    "service":"${SEPLOY_SERVICE_NAME}"
  }
]

たとえひとつのイベントだけでも配列で定義しないとうまくいきません。
時刻情報はAPI実行時のtimestampが自動的に含まれるので自前の定義は不要です。
「誰がデプロイしたのか?」も情報として含めていますが、これを集計すると謎の力学が発生してしまうのであくまで参考値として記録しておくだけにしておきます。

CircleCI上でEvent APIを実行する

上記のJSON定義をNew Relicのエンドポイントに送信すればイベントの記録が始まります。
我々のチームはCircleCIを使ってサービスをデプロイしているので、CircleCIのデプロイ用ワークフローの最後のステップにEvent APIを実行するようにします。
各サービスの.circleci/config.ymlの中に次のjobを定義しました。

record-deployment:
  executor:
    name: aws-cli/default # curlコマンドが使えれば何でもよい
  steps:
    - setenv_prd # 環境変数のセットアップ
    - run:
        name: Send Deploy event to New Relic
        command: |
          curl -i \
          -X POST 'https://insights-collector.newrelic.com/v1/accounts/${NEW_RELIC_ACOUNT_ID}/events' \
          -H "X-Insert-Key:${NEW_RELIC_LICENSE_KEY}" \
          -H "Content-Type: application/json" \
          -d \
          "[
            {
              \"eventType\":\"Deploy\",
              \"deploy_user\":\"${CIRCLE_USERNAME}\",
              \"service\":\"${CIRCLE_PROJECT_REPONAME}\"
            }\
          ]"

NEW_RELIC_ACOUNT_IDNEW_RELIC_LICENSE_KEY という環境変数を設定する必要があります。
CIRCLE_USERNAMECIRCLE_PROJECT_REPONAMEはCircleCI実行時に自動的に設定される値です。
circleci.com

あとはこのjobをデプロイフローの最後に設定しておきます。
デプロイフローの実行完了(デプロイ成功)のタイミングでDeployというイベントが記録されます。

test-build-deploy:
  jobs:
    - test:
        filters:
          branches:
            only: main
    - build-push:
        requires:
          - test
    # ....
    - deploy-prd:
        requires:
          - approve-deploy-prd
    - record-deployment:
        requires:
          - deploy-prd

Event APIを利用した独自イベントの集計

データが取得できるようになったならば後は集計してダッシュボードに掲載します。
New Relic Oneを開いたらQuery Builderに移動してDeployイベントを集計していきます。
良いグラフができたら右下の「Add to Dashboard」ボタンを使ってダッシュボードにグラフを追加していきます。
参考までに我々が作成したグラフとNRQLのクエリを紹介します。

f:id:budougumi0617:20211208205409p:plain
ダッシュボード

月間デイリーデプロイ数

SELECT count(*) FROM Deploy TIMESERIES 1 day FACET service SINCE 30 days ago

f:id:budougumi0617:20211208204156p:plain
月間デイリーデプロイ数

まずは過去30日の日毎のデプロイ数です。サービス別にカウントしています。
NRQLは独自イベントに付与している独自属性を使ってFACETを書くこともできます。

今週のデプロイ総数(先週比較)

SELECT count(*) FROM Deploy SINCE this week COMPARE WITH 1 week ago

f:id:budougumi0617:20211208204210p:plain
ウィークリーデプロイ数

次に先週比較の数値です。COMPARE WITHを使うと比較対象との比率まで簡単に示してくれます。
先週と比べて今週のデプロイ頻度は低いのか?気づかないうちにチームのパフォーマンスがブレてていないか?を確認したくて作りました。

週間デプロイ数

最後は直近4週間のデプロイ総数です。

SELECT count(*) FROM Deploy FACET weekOf(timestamp) UNTIL monday SINCE 5 week ago

f:id:budougumi0617:20211208204250p:plain
週別デプロイ数

こちらもコンスタントにデプロイできているか?を確認するために作りました。

終わりに

本記事では「LeanとDevOpsの科学」などで示されているソフトウェア開発チームのパフォーマンスを示す4 つの指標のうち、デプロイ頻度をNew Relicを使って確認する方法を紹介しました。いくつか実際に利用している集計クエリも紹介しました。「こんな見方もできるのは?」「私たちのチームはこういう点をみている」とコメントある方は教えていただけると幸いです。

ソフトウェア開発チームのパフォーマンスの4つの指標ではデプロイ頻度の他に3つのキーが定義されています(再度Google Cloudブログより引用)。

  • デプロイの頻度 - 組織による正常な本番環境へのリリースの頻度
  • 変更のリードタイム - commit から本番環境稼働までの所要時間
  • 変更障害率 - デプロイが原因で本番環境で障害が発生する割合(%)
  • サービス復元時間 - 組織が本番環境での障害から回復するのにかかる時間

デプロイ頻度以外については現状まだ計測できていません。
その他のキーについても可視化した際は本開発者ブログで共有させていただきます。

また、New Relic Oneでは最近サービスレベル目標(SLO)を設定、サービスレベル指標(SLI)、Error budgetを管理できるService Level Management機能もPublic betaになりました。
来年は4キーメトリクスの他に、SLIについても可視化していければなと思います。

docs.newrelic.com

そしてBASE Advent Calendar 2021 10日目の記事も書いたのでよかったら読んでみてください。

devblog.thebase.in

参考