Apdex って何？スコアの意味は？閾値やアラートに何を設定するべき？全部答えます。

New Relic 2017 Advent Calendar 二日目。

今日から何日かはいまいちよくわからない Apdex ついて投稿していく。今回の投稿が一番言いたいこと。(後は補足情報とか別視点の話）

----

New Relic では、Apdex (アプデックス: Application Performance Index) をウェブサービスのユーザー満足度の指標として採用している。

個人的には Apdex は一言では説明しづらく、うまくまとまった説明がないと思うので、この記事だけ読んで、New Relic (特に APM)で、Apdex を活用できるようになることを目指す。特に、閾値として何を設定すべきか、アラートの設定はどうすべきかに重点を置いている。(結局、この2つをどうするのかという話にしかならないため）
　
Apdex は正確に全部書いていくと長くなるので、この記事内で書いている値の根拠や理論は別記事のリンクを張るのでそっちを見てください。あと、Apdex についての細かい説明も省きます。New Relic APM 使ってて、Apdex をなんとなく知っている人向けの記事です。

## 結論

ユーザーが知っておくべき最低限の情報。

以下は、推奨すべき目安となる設定値。サービスごとに最適な値は異なるが、デフォルト値として使える数字。なぜ、この数字なのかは、この後、説明していく。

- サービスが目指すべき Apdex スコア: 0.95
- 0.95 となる Apdext T (閾値): 過去24時間のリクエストの 90 パーセンタイルのレスポンスタイム(秒)
- 90パーセンタイルのレスポンスタイム求めるための NRQL: `select percentile(duration, 90) from Transaction where appName=NNNNN since 24 hours ago`
- アラートの設定: Warning の閾値: 0.85
- アラートの設定: Critical の閾値: 0.70

注: New Relic APM UI 上で、90パーセンタイルのレスポンスタイムを知るすべはない。New Relic Insights の NRQL を使うしかない。NRQL については、[こちらの記事](https://qiita.com/kumatronik/items/b25313a8631e46140499)を参考。


## Apdex とは

Apdex は、[Apdex アライアンス](http://apdex.org/index.html)が定義したウェブアプリのパフォーマンスに関するユーザー満足度を測る指標。

## Apdex の目的と役に立つ場面

Apdex は大きく２つの用途がある。それによって、アラートの設定は異なる。(閾値は上で説明した値でよい）。どちらの目的で利用するのかサービス（というか企業）ごとに決めておく必要がある。

### 品質管理(SLA)基準として役割

Apdex を作成した目的は、SLA (サービス品質保証)のようなアプリのサービス品質を適切に効率よく管理するためである。企業で、複数のサービスを運用している場合に、サービスの品質を一定にしたい場合や効率よく管理したい場合に Adpex が算出するスコアを使うと、サービス全体で同じ基準で現状認識や目標を定めることができる。

品質を求める基準として、レスポンスタイムで判断するという考えもあるが、それではサービスの特性や組織のそのサービスの重要度などにより、基準とするレスポンスタイムは異なる。全部のサービスで 0.3秒を目指せば良いというものでもない。よって、一律の値では管理しづらいし、目指すべき品質基準をサービスごとに変えると、パット見ではどのサービスが要件を満たしているのか判断しづらい。 

Apdex は、サービスのレスポンスタイムを基準として、スコアを算出するため、スコアを見たときに同じ尺度で判断できる。サービス A の Apdex スコアが 0.8 で、B のスコアが 0.9 なら B の方が必ずユーザー満足度が必ず高いと言える。また、全サービスのユーザー満足度を 0.9 にするなど統一した目標設定もやりやすいし、その判定も簡単。(0.9 に必要なレスポンスタイムはサービス毎に異なるが、それはそれぞれのサービスが気にすればいい)

よって、Apdex は常に一定の基準で複数のサービスの品質を効率よく管理したい場合に便利な指標と言える。

### 外れ値に左右されないアプリのパフォーマンスの状態を監視する役割

上記の説明だと、じゃあ、１つのサービスだけでしか使わない場合や明確に SLA とか定義していない場合は、Apdex は意味がないんじゃないかと思う方がいるかもしれない。だけど、別の点でも役に立ちます。(この２つの役割があるのが、Apdex を説明しづらくしている点の気がするけど）。

上記でも述べたけど (詳しくは後述）、Apdex はレスポンスタイムを基準に Adpex スコアを算出し、ユーザー満足度を測る。平均のレスポンスタイムを基準にすると、外れ値によって平均が歪められることがある。例えば、平時の平均は、0.3秒だが、あるとき0.8秒になった場合、全体的に遅くなったのか、ごく少数の(無視できる）トランザクションだけ異常に遅いのかは、平均の値だけでは判断ができない。一方、Adpex は、外れ値は見ないので、そこでスコアが歪むことがない。これに関する議論は、[パフォーマンス監視のユーザー満足度指標 Apdex についてちゃんとまとめてみた: 第3回 Apdex のベスト・プラクティス](https://newrelic.degica.com/blog/2017-03-09-about-apdex-03)をご覧を。

よって、Apdex は、1つのサービスであっても、サービス全体(のトランザクション）から見て、全体的にユーザー満足度がどうなっているかを知るための指標として、有効である。

### まとめ

そのため、組織の品質管理の基準として Apdex を利用する場合と１つのサービスだけで Apdex を使う場合では使い方が異なる。

今回紹介するのは、1つのサービスだけで Apdex を使う場合が主で、品質管理基準としてどう使うかは、別の記事で紹介する。ただし、品質管理基準として使いたい人も一通りこの記事を読んでおくことを進める。基本、Apdex に関する内容は変わらないため。現状、1つのサービスだけで、Apdex をどう使っていけばいいのか分からないケースが大半であると思うため今回の記事は1つのサービスに焦点を当てる。

## Apdex の公式

では、Apdex スコアを算出する公式について説明する。

[Apdex アライアンスが定義した式](http://apdex.org/overview.html)に従ってレスポンスタイムから Apdex スコアを算出する。Apdex スコアは、レスポンスタイムをある閾値に従って、以下の3つに分類し、それをある特定の期間に集めたリクエストをすべて、その3つに分類し、その数を以下の式を使って計算する。

閾値を T とした場合 (この T は後で説明する)

| 分類 | 意味 | 範囲 | 例 (閾値Tを 0.3 秒とした場合) |
| ---- | ----| ---- | --- |
| Satisfied (満足) | ユーザーがレスポンスタイムを気にならない状態 | T 以下 | 0.3 秒以下のリクエスト |
| Tolerating (許容) | ユーザーは少し遅いと感じるが、サイトを使い続けている状態 | T より遅く、4T(Tの4倍)以下 | 0.3 秒より遅くて、1.2秒以下のリクエスト |
| Frustrated (不満) | ユーザーは待つのが我慢できなく、サイトを離そうになっている状態 | 4T より遅い | 1.2 秒より遅いのリクエスト |

Apdex スコアを求める式は以下のとおり。

```math
Apdex スコア = \frac{満足のリクエスト数 + \frac{許容のリクエスト数}{2}}{全リクエスト}
```

**具体例:** 
1分あたりのにリクエストが 100 あったとする。閾値は、0.3秒とする。
70リクエストが、0.3 秒以内。20リクエストは、1.2 秒以内。残り10リクエストは、エラーとなったか1.2秒以上だとする。その場合の Apdex スコアは、

```math
Apdex スコア = \frac{70 + \frac{20}{2}}{100} = \frac{70 + 10}{100} = \frac{80}{100} = 0.8
```

ということで、Apdex スコアは 0.8。

ここまでで、Apdex スコアの算出の仕方は分かったと思う。もっと詳しく知りたい方は[ドキュメント: Apdex：ユーザー満足度の測定](https://newrelic.degica.com/docs/apm/new-relic-apm/apdex/apdex-measuring-user-satisfaction)を見てください。

では、次に New Relic でこの Apdex をどう使っていくかを見ていく。

## New Relic における Apdex とは

New Relic では、Apdex は、APM と Browser の2つに用意されている。APM の場合は、キートランザクション毎に Apdex スコアを知ることができる。APM の場合は、サーバー処理内でのレスポンスタイムが対象。Browser の場合は、ブラウザの処理が始まってから、終わるまでの時間が対象となる。

### Apdex が表示される箇所

New Relic APM では、以下のように右上に Apdex が表示される。Browser も使っている場合は、Browserのスコアも表示される。

見方として、0.95 [0.25] とあるが、0.25 が設定されている閾値Tで、それを元に、選択時間帯のトラフィックはを対象に計算した Apdex スコアが 0.95である。

![apdex_01.png](https://qiita-image-store.s3.amazonaws.com/0/46003/4ff73e86-c35d-2796-1a96-86c447e4fbe2.png)

チャートの Apdex スコアの線 (青: アプリ,黄色: ブラウザ)の上にマウスオーバーすると、そのタイミングでの Adpex スコアとその計算対象のサンプルサイズや Satisfied 等の数を知ることができる。

![apdex_02_1.png](https://qiita-image-store.s3.amazonaws.com/0/46003/3c369831-b255-c253-b3af-3ffb77b4765e.png)

また、SLA のレポートにも Apdex スコアは表示される。

### Apdex に関する設定

New Relic において、Apdex は以下の設定が行える。

- APM: **アプリ全体の Apdex の閾値 T**
- APM: **キートランザクション毎に Apdex の閾値 T**
- Browser: **アプリ全体の Apdex の閾値 T**

デフォルトの Apdex T は、APM: 0.5秒。Browser: 7秒。

この閾値 T によって、各製品の Overview ページに表示される Apdex スコアが異なる。(上で設定する閾値を基準に計算される）

また、Apdex スコアは、アラートにも使える。Apdex スコアでアラートを設定しておくことで、普段と異なるパターンになったときに、素早く検知できる。

- APM: **アプリ全体の Apdex スコアを対象に、Warning と Critical のアラートの設定**
- APM: **キートランザクション毎に その Apdex スコアを対象に、Warning と Critical のアラートの設定**
- Browser: **アプリ全体の Apdex スコアを対象に、Warning と Critical のアラートの設定**

まとめると、New Relic ユーザーは、閾値の設定とアラートの設定が、Apdex に関する設定。

Apdex T のデフォルト値は最適な値ではないので、各サービスにあった閾値を設定するしてください。また、アラートについても同様。

## Apdex の閾値は何を設定すべきか？

ようやく、ここからがこの記事でいいたいこと。

上記では、デフォルトが最適ではないと書いたが、ではどの値を設定すべきなのだろうか？ 

### サービスの Apdex スコアが 0.95 となるように、90パーセンタイルのレスポンスタイムを設定する

ここからは、APM のみの話。

New Relic は、サービスの平均 [Apdex スコアが **0.95** となるようにサービスを保つこと、そのように閾値を設定すること](https://newrelic.degica.com/blog/2017-07-06-how-to-choose-apdex-t)を推奨している。

平均が 0.95 となるには、閾値は何秒にすればいいのでしょうか？ それは、サービスの過去24時間の**レスポンスタイムの 90パーセンタイル**の数値。曜日でレスポンスタイムにばらつきがあるサービスは、過去1週間とかでみればいいと思う。

90パーセンタイルとは、どこらへんかというと、以下の緑と黄色の境目(以下の場合は 887ms)。

<img width="291" alt="スクリーンショット 2017-11-26 17.51.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/46003/7fd398ad-4360-a703-8909-63662310b372.png">

なぜ、90パーセンタイルで、095となるかの根拠を知りたい方は、[こちらの記事](https://newrelic.degica.com/blog/2017-07-06-how-to-choose-apdex-t)を参照。

### 90パーセンタイルのレスポンスタイムを知る方法

サービスの90パーセンタイルの秒数を知るには、[New Relic Insights](https://qiita.com/kumatronik/items/b25313a8631e46140499) を使う。それ以外、New Relic UI で知る方法はない。(New Relic APM の有料ユーザーであれば無料で利用できる New Relic のダッシュボードサービス)

Insights は、各 New Relic 製品が集めたデータを全部保持している。そのデータに対して、NRQL というクエリを使って問い合わせる。Insights にアクセスして、以下の NRQL を入力し、実行すると、過去24時間の90パーセンタイルのレスポンスタイムを知ることができる。

`select percentile(duration, 90) from Transaction where appName=NNNNN since 24 hours ago`

(appIDはアプリの名。24時間でなく、過去1週間のデータが知りたい場合は、`since` の箇所を `since 1 week ago` に置き換えてること。ただし、過去1週間のデータが見たい場合は、APM PRO の利用が必要。Essentials では3日分のデータしか Insights では見れないため)

Insights で上記の NRQL を実行した結果。この場合は、`0.02` が Adpex スコア。

![apdex_03.png](https://qiita-image-store.s3.amazonaws.com/0/46003/e97a3d4e-ac63-ddf4-918d-69a3a6e1e3ea.png)

この値を APM の設定画面で Apdex T に設定する。

設定方法: **APM にログイン > アプリを選択 > 画面左下の SETTINGS の Application リンクをクリック > 画面中央の APdex T のフィールドに値を設定し、"Save application settings" をクリック**。

詳しくは、[ドキュメント「Apdex の設定変更」](https://newrelic.degica.com/docs/apm/new-relic-apm/apdex/change-your-apdex-settings)を参照。(キートランザクションの Apdex の設定についてもこのドキュメントある）

もし、90パーセンタイルのレスポンスタイムを設定しても、0.95 のスコアとならない場合は、各自微調整してね。90パーセンタイルという数値は、あくまで統計的に導きだした平均なので、サービスによっては0.95にならない場合もある。

Apdex の閾値を設定できたとして、0.95 になるようになった。

ただ、これはまだ半分。せっかく、適切な閾値の設定ができたんだから、ユーザー満足度が下がったときに、知りたいよね。結構、アラートを設定していない人が多いんだけど、使わないともったいない。

では、アラートとみなす閾値に何を設定すべきだろうか？

## Apdex でアラートを設定するときに設定する閾値はどの値を選ぶべきか？

上記でも説明したように、New Relic ではアラートは2段階 (Warning と Critical)ある。Warning はその閾値を越えても、通知は飛ばす、New Relic UI 内だけでその状態を表示。こちらはオプションなので設定しなくてもいい。Critical は、その閾値に違反すると通知が飛ぶ。

New Relic では、デフォルトとして、**Warning: 0.85**。**Critical: 0.70** を推奨している。

とりあえずはこの値を設定しておけばいいと思う。参考までに、このスコアの意味を述べておく。（これについては別記事で解説予定)

Apdex スコア 0.85: 7割から8.5割が満足 / 最大3割が許容内 / 最大 1.5 割が不満の状態
Apdex スコア 0.70: 4割満足で6割許容内か、7割満足で3割不満か、その間の状態

これは、異常状態なので、一概にこのスコアがどういう分布になるのかはいいづらいので上のような微妙な言い方となる。

### Apdex をアラート条件として設定する手順

New Relic では、New Relic Alerts (画面右上）から、各製品のアラートを設定する。

アラートの設定手順:

1. 画面右上の "Alerts" をクリック
2. 中段のメニューから、Alert policies をクリック、ポリシーを選択 or 作成。
3. "Add a condition" をクリック。
4. select a product から "APM"、Select a type of condition から "Application metric" を選択し、"Next, select entities" をクリック。
5. アラートを設定するアプリにチェックする
6. 最初のドロップボックスから、"Apdex" を選択(デフォルト)。
7. Critical の閾値の設定: 赤×マークのアイコン の最初のフィールドに、0.70 を設定。
8. Warning の閾値の設定: その下の "Add a warning threshold" をクリックし、最初のフィールドに 0.85 を設定。
9. "Create condition" をクリック。

※ アラートの設定についてよくわからない方は、[「New Relic Alert: 柔軟なアラートの設定でインシデントを効率よく管理しよう」](https://qiita.com/kumatronik/items/5dd264df027941f40d79)をご覧を。

**キートランザクションのアラートを設定する場合**

上記の手順4の Select a type of condition から、"Key transaction metric" を選択する。すると、次の Select entities で登録済みのキートランザクション一覧が表示されるので、対象とするキートランザクションにチェックする。後は上と同じ。


## おまけ

New Relic Insights には、[Apdex スコアを算出する apdex 関数](https://newrelic.degica.com/docs/insights/nrql-new-relic-query-language/nrql-resources/nrql-syntax-components-functions)があり、任意のトランザクションや期間で、その Apdex スコアを求めることができます。

以下は、過去1時間の `Controller/notes/index` トランザクションに対して、閾値を 0.4秒とした場合の Apdex スコアを求める NRQL です。

```sql
SELECT apdex(duration, t: 0.4) FROM Transactio WHERE WHERE name='Controller/notes/index' SINCE 1 hour ago
```

## 参考資料

- [ドキュメント: Apdex：ユーザー満足度の測定](https://newrelic.degica.com/docs/apm/new-relic-apm/apdex/apdex-measuring-user-satisfaction)
- [ドキュメント: Apdex の設定変更](https://newrelic.degica.com/docs/apm/new-relic-apm/apdex/change-your-apdex-settings)
- [翻訳: Apdex T の決め方 : 決定版](https://newrelic.degica.com/blog/2017-07-06-how-to-choose-apdex-t)
- [パフォーマンス監視のユーザー満足度指標 Apdex についてちゃんとまとめてみた: 第1回 Apdex の定義](https://newrelic.degica.com/blog/2017-02-27-about-apdex-01)
- [パフォーマンス監視のユーザー満足度指標 Apdex についてちゃんとまとめてみた: 第2回 Apdex についての反対意見](https://newrelic.degica.com/blog/2017-03-03-about-apdex-02)
- [パフォーマンス監視のユーザー満足度指標 Apdex についてちゃんとまとめてみた: 第3回 Apdex のベスト・プラクティス](https://newrelic.degica.com/blog/2017-03-09-about-apdex-03)